From 239ae6eea1585695868c5b200b375bd4c27d8292 Mon Sep 17 00:00:00 2001 From: Jim Date: Thu, 4 May 2023 07:10:23 -0400 Subject: [PATCH] release 0.9.0a0 --- README.md | 9 +- py5/__init__.py | 10163 ++++++++-------- py5/base.py | 2 +- py5/bridge.py | 24 +- py5/create_font_tool.py | 19 +- py5/custom_exceptions.py | 21 +- py5/decorators.py | 2 +- py5/font.py | 75 +- py5/graphics.py | 6060 ++++----- py5/image.py | 471 +- py5/image_conversion.py | 18 +- py5/jars/core.jar | Bin 1015216 -> 1016386 bytes py5/jars/dxf/dxf.jar | Bin 2532 -> 2537 bytes py5/jars/pdf/pdf.jar | Bin 5561 -> 5566 bytes py5/jars/py5.jar | Bin 34263 -> 35656 bytes py5/jars/svg/svg.jar | Bin 3393 -> 3399 bytes py5/keyevent.py | 45 +- py5/mixins/__init__.py | 2 +- py5/mixins/data.py | 84 +- py5/mixins/math.py | 558 +- py5/mixins/pixels.py | 578 +- py5/mixins/print_tools.py | 25 +- py5/mixins/threads.py | 158 +- py5/mouseevent.py | 42 +- py5/natives/windows-amd64/fenster.exe | Bin 8704 -> 41472 bytes ...ava_conversion.py => object_conversion.py} | 61 +- py5/pmath.py | 4 +- py5/reference.py | 67 +- py5/render_helper.py | 122 +- py5/shader.py | 18 +- py5/shape.py | 2988 +++-- py5/sketch.py | 7024 +++++------ py5/spelling.py | 83 + py5/surface.py | 74 +- py5/utilities.py | 79 + py5/vector.py | 256 +- py5_tools/__init__.py | 4 +- py5_tools/config.py | 31 +- py5_tools/environ.py | 2 +- py5_tools/hooks/__init__.py | 2 +- py5_tools/hooks/frame_hooks.py | 141 +- py5_tools/hooks/hooks.py | 17 +- py5_tools/hooks/zmq_hooks.py | 44 +- py5_tools/hooks/zmq_hooks_fail.py | 42 +- py5_tools/imported.py | 71 +- py5_tools/jvm.py | 41 +- py5_tools/kernel/__init__.py | 20 - py5_tools/kernel/__main__.py | 22 - py5_tools/kernel/install.py | 89 - py5_tools/kernel/kernel.py | 99 - py5_tools/kernel/resources/logo-32x32.png | Bin 2643 -> 0 bytes py5_tools/libraries.py | 73 +- py5_tools/magics/__init__.py | 2 +- py5_tools/magics/drawing.py | 41 +- py5_tools/magics/py5bot.py | 40 +- py5_tools/magics/util.py | 2 +- py5_tools/parsing.py | 74 +- py5_tools/printstreams.py | 2 +- py5_tools/py5bot/__init__.py | 20 - py5_tools/py5bot/__main__.py | 22 - py5_tools/py5bot/install.py | 89 - py5_tools/py5bot/kernel.py | 101 - py5_tools/py5bot/py5bot.py | 219 - py5_tools/py5bot/resources/logo-32x32.png | Bin 2541 -> 0 bytes py5_tools/py5bot/resources/logo-64x64.png | Bin 6819 -> 0 bytes py5_tools/reference.py | 10 +- .../{kernel => }/resources/logo-64x64.png | Bin py5_tools/split_setup.py | 4 +- py5_tools/testing.py | 2 +- py5_tools/tools/__init__.py | 2 +- py5_tools/tools/py5cmd.py | 87 +- .../tools/py5translate_imported2module.py | 2 +- .../tools/py5translate_module2imported.py | 2 +- .../py5translate_processingpy2imported.py | 2 +- py5_tools/tools/py5utils.py | 2 +- py5_tools/tools/run_sketch.py | 2 +- py5_tools/translators/__init__.py | 2 +- py5_tools/translators/imported2module.py | 2 +- py5_tools/translators/module2imported.py | 2 +- .../translators/processingpy2imported.py | 2 +- py5_tools/translators/util.py | 2 +- py5_tools/utilities.py | 32 +- pyproject.toml | 71 + setup.py | 107 +- 84 files changed, 15509 insertions(+), 15268 deletions(-) rename py5/{java_conversion.py => object_conversion.py} (68%) create mode 100644 py5/spelling.py create mode 100644 py5/utilities.py delete mode 100644 py5_tools/kernel/__init__.py delete mode 100644 py5_tools/kernel/__main__.py delete mode 100644 py5_tools/kernel/install.py delete mode 100644 py5_tools/kernel/kernel.py delete mode 100644 py5_tools/kernel/resources/logo-32x32.png delete mode 100644 py5_tools/py5bot/__init__.py delete mode 100644 py5_tools/py5bot/__main__.py delete mode 100644 py5_tools/py5bot/install.py delete mode 100644 py5_tools/py5bot/kernel.py delete mode 100644 py5_tools/py5bot/py5bot.py delete mode 100644 py5_tools/py5bot/resources/logo-32x32.png delete mode 100644 py5_tools/py5bot/resources/logo-64x64.png rename py5_tools/{kernel => }/resources/logo-64x64.png (100%) create mode 100644 pyproject.toml diff --git a/README.md b/README.md index a79bc7f..775040f 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ [![mybinder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/py5coding/py5examples/HEAD?urlpath=lab) -py5 is a new version of [**Processing**][processing] for Python 3.8+. It makes the Java [**Processing**][processing] jars available to the CPython interpreter using [**JPype**][jpype]. It can do just about all of the 2D and 3D drawing [**Processing**][processing] can do, except with Python instead of Java code. +py5 is a version of [**Processing**][processing] for Python 3.8+. It makes the Java [**Processing**][processing] jars available to the CPython interpreter using [**JPype**][jpype]. It can do just about all of the 2D and 3D drawing [**Processing**][processing] can do, except with Python instead of Java code. -The goal of py5 is to create a new version of Processing that is integrated into the Python ecosystem. Built into the library are thoughtful choices about how to best get py5 to work with other popular Python libraries and tools such as [Jupyter][jupyter], [numpy][numpy], and [Pillow][pillow]. +The goal of py5 is to offer a new version of Processing that is integrated into the Python ecosystem. Built into the library are thoughtful choices about how to best get py5 to work with other popular Python libraries and tools such as [Jupyter][jupyter], [numpy][numpy], and [Pillow][pillow]. ## Simple Example @@ -46,14 +46,15 @@ pip install py5 ## Getting Started -There are currently four basic ways to use py5. They are: +There are currently five basic ways to use py5. They are: * **module mode**: create a sketch with `setup()` and `draw()` functions that call methods provided by the `py5` library. The above example is created in module mode. * **class mode**: create a Python class inherited from `py5.Sketch`. This mode supports multiple Sketches running at the same time. * **imported mode**: simplified code that omits the `py5.` prefix. This mode is supported by the py5 Jupyter notebook kernel and the `run_sketch` command line utility. * **static mode**: functionless code to create static images. This mode is supported by the py5bot Jupyter notebook kernel, the `%%py5bot` IPython magic, and the `run_sketch` command line utility. +* **processing mode**: make calls to Python from a Processing (Java) Sketch. This mode enables py5 to function as bridge, connecting the Python and Java ecosystems through a new `callPython()` method. -The documentation website, [https://py5coding.org/](https://py5coding.org/), is a work in progress. The reference documentation is solid but the how-to's and tutorials are incomplete. +The documentation website, [https://py5coding.org/](https://py5coding.org/), is a work in progress, but contains solid reference documentation and many tutorials for beginner coders. [py5generator][py5_generator_repo] is a meta-programming project that creates the py5 library. To view the actual installed py5 library code, look at the [py5 repository][py5_repo]. All py5 library development is done through py5generator. diff --git a/py5/__init__.py b/py5/__init__.py index ba9c52c..95ea9e0 100644 --- a/py5/__init__.py +++ b/py5/__init__.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -80,20 +80,21 @@ from .vector import Py5Vector, Py5Vector2D, Py5Vector3D, Py5Vector4D # noqa from py5_tools import split_setup as _split_setup from . import reference -from . import java_conversion # noqa +from . import object_conversion # noqa +from . import spelling as _spelling try: from py5_tools.magics import load_ipython_extension # noqa -except ModuleNotFoundError: +except ImportError: # IPython must not be installed pass -__version__ = '0.8.3a1' +__version__ = '0.9.0a0' _PY5_USE_IMPORTED_MODE = py5_tools.get_imported_mode() py5_tools._lock_imported_mode() -java_conversion.init_jpype_converters() +object_conversion.init_jpype_converters() _py5sketch = Sketch() @@ -286,7 +287,7 @@ def alpha(rgb: int, /) -> float: - """Extracts the alpha value from a color, scaled to match current ``color_mode()``. + """Extracts the alpha value from a color, scaled to match current `color_mode()`. Underlying Processing method: PApplet.alpha @@ -299,14 +300,14 @@ def alpha(rgb: int, /) -> float: Notes ----- - Extracts the alpha value from a color, scaled to match current ``color_mode()``. + Extracts the alpha value from a color, scaled to match current `color_mode()`. - The ``alpha()`` function is easy to use and understand, but it is slower than a - technique called bit shifting. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``alpha()`` but with greater speed by using the - right shift operator (``>>``) with a bit mask. For example, ``alpha(c)`` and ``c - >> 24 & 0xFF`` both extract the alpha value from a color variable ``c`` but the - later is faster. + The `alpha()` function is easy to use and understand, but it is slower than a + technique called bit shifting. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `alpha()` but with greater speed by using the right + shift operator (`>>`) with a bit mask. For example, `alpha(c)` and `c >> 24 & + 0xFF` both extract the alpha value from a color variable `c` but the later is + faster. """ return _py5sketch.alpha(rgb) @@ -350,9 +351,9 @@ def ambient(gray: float, /) -> None: Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with ``emissive()``, - ``specular()``, and ``shininess()`` to set the material properties of shapes. + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect + and half of the green light to reflect. Use in combination with `emissive()`, + `specular()`, and `shininess()` to set the material properties of shapes. """ pass @@ -396,9 +397,9 @@ def ambient(v1: float, v2: float, v3: float, /) -> None: Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with ``emissive()``, - ``specular()``, and ``shininess()`` to set the material properties of shapes. + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect + and half of the green light to reflect. Use in combination with `emissive()`, + `specular()`, and `shininess()` to set the material properties of shapes. """ pass @@ -442,9 +443,9 @@ def ambient(rgb: int, /) -> None: Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with ``emissive()``, - ``specular()``, and ``shininess()`` to set the material properties of shapes. + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect + and half of the green light to reflect. Use in combination with `emissive()`, + `specular()`, and `shininess()` to set the material properties of shapes. """ pass @@ -487,9 +488,9 @@ def ambient(*args): Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with ``emissive()``, - ``specular()``, and ``shininess()`` to set the material properties of shapes. + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect + and half of the green light to reflect. Use in combination with `emissive()`, + `specular()`, and `shininess()` to set the material properties of shapes. """ return _py5sketch.ambient(*args) @@ -535,11 +536,11 @@ def ambient_light(v1: float, v2: float, v3: float, /) -> None: Adds an ambient light. Ambient light doesn't come from a specific direction, the rays of light have bounced around so much that objects are evenly lit from all sides. Ambient lights are almost always used in combination with other types of - lights. Lights need to be included in the ``draw()`` to remain persistent in a - looping program. Placing them in the ``setup()`` of a looping program will cause - them to only have an effect the first time through the loop. The ``v1``, ``v2``, - and ``v3`` parameters are interpreted as either ``RGB`` or ``HSB`` values, - depending on the current color mode. + lights. Lights need to be included in the `draw()` to remain persistent in a + looping program. Placing them in the `setup()` of a looping program will cause + them to only have an effect the first time through the loop. The `v1`, `v2`, and + `v3` parameters are interpreted as either `RGB` or `HSB` values, depending on + the current color mode. """ pass @@ -586,11 +587,11 @@ def ambient_light(v1: float, v2: float, v3: float, Adds an ambient light. Ambient light doesn't come from a specific direction, the rays of light have bounced around so much that objects are evenly lit from all sides. Ambient lights are almost always used in combination with other types of - lights. Lights need to be included in the ``draw()`` to remain persistent in a - looping program. Placing them in the ``setup()`` of a looping program will cause - them to only have an effect the first time through the loop. The ``v1``, ``v2``, - and ``v3`` parameters are interpreted as either ``RGB`` or ``HSB`` values, - depending on the current color mode. + lights. Lights need to be included in the `draw()` to remain persistent in a + looping program. Placing them in the `setup()` of a looping program will cause + them to only have an effect the first time through the loop. The `v1`, `v2`, and + `v3` parameters are interpreted as either `RGB` or `HSB` values, depending on + the current color mode. """ pass @@ -635,11 +636,11 @@ def ambient_light(*args): Adds an ambient light. Ambient light doesn't come from a specific direction, the rays of light have bounced around so much that objects are evenly lit from all sides. Ambient lights are almost always used in combination with other types of - lights. Lights need to be included in the ``draw()`` to remain persistent in a - looping program. Placing them in the ``setup()`` of a looping program will cause - them to only have an effect the first time through the loop. The ``v1``, ``v2``, - and ``v3`` parameters are interpreted as either ``RGB`` or ``HSB`` values, - depending on the current color mode. + lights. Lights need to be included in the `draw()` to remain persistent in a + looping program. Placing them in the `setup()` of a looping program will cause + them to only have an effect the first time through the loop. The `v1`, `v2`, and + `v3` parameters are interpreted as either `RGB` or `HSB` values, depending on + the current color mode. """ return _py5sketch.ambient_light(*args) @@ -720,7 +721,7 @@ def apply_matrix(n00: float, n01: float, n02: float, Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. """ pass @@ -817,7 +818,7 @@ def apply_matrix( Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. """ pass @@ -897,7 +898,7 @@ def apply_matrix(source: npt.NDArray[np.floating], /) -> None: Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. """ pass @@ -976,7 +977,7 @@ def apply_matrix(*args): Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. """ return _py5sketch.apply_matrix(*args) @@ -1024,20 +1025,20 @@ def arc(a: float, b: float, c: float, d: float, ----- Draws an arc to the screen. Arcs are drawn along the outer edge of an ellipse - defined by the ``a``, ``b``, ``c``, and ``d`` parameters. The origin of the - arc's ellipse may be changed with the ``ellipse_mode()`` function. Use the - ``start`` and ``stop`` parameters to specify the angles (in radians) at which to - draw the arc. The start/stop values must be in clockwise order. + defined by the `a`, `b`, `c`, and `d` parameters. The origin of the arc's + ellipse may be changed with the `ellipse_mode()` function. Use the `start` and + `stop` parameters to specify the angles (in radians) at which to draw the arc. + The start/stop values must be in clockwise order. There are three ways to draw an arc; the rendering technique used is defined by the optional seventh parameter. The three options, depicted in the examples, are - ``PIE``, ``OPEN``, and ``CHORD``. The default mode is the ``OPEN`` stroke with a - ``PIE`` fill. + `PIE`, `OPEN`, and `CHORD`. The default mode is the `OPEN` stroke with a `PIE` + fill. - In some cases, the ``arc()`` function isn't accurate enough for smooth drawing. + In some cases, the `arc()` function isn't accurate enough for smooth drawing. For example, the shape may jitter on screen when rotating slowly. If you're having an issue with how arcs are rendered, you'll need to draw the arc yourself - with ``begin_shape()`` & ``end_shape()`` or a ``Py5Shape``. + with `begin_shape()` & `end_shape()` or a `Py5Shape`. """ pass @@ -1085,20 +1086,20 @@ def arc(a: float, b: float, c: float, d: float, ----- Draws an arc to the screen. Arcs are drawn along the outer edge of an ellipse - defined by the ``a``, ``b``, ``c``, and ``d`` parameters. The origin of the - arc's ellipse may be changed with the ``ellipse_mode()`` function. Use the - ``start`` and ``stop`` parameters to specify the angles (in radians) at which to - draw the arc. The start/stop values must be in clockwise order. + defined by the `a`, `b`, `c`, and `d` parameters. The origin of the arc's + ellipse may be changed with the `ellipse_mode()` function. Use the `start` and + `stop` parameters to specify the angles (in radians) at which to draw the arc. + The start/stop values must be in clockwise order. There are three ways to draw an arc; the rendering technique used is defined by the optional seventh parameter. The three options, depicted in the examples, are - ``PIE``, ``OPEN``, and ``CHORD``. The default mode is the ``OPEN`` stroke with a - ``PIE`` fill. + `PIE`, `OPEN`, and `CHORD`. The default mode is the `OPEN` stroke with a `PIE` + fill. - In some cases, the ``arc()`` function isn't accurate enough for smooth drawing. + In some cases, the `arc()` function isn't accurate enough for smooth drawing. For example, the shape may jitter on screen when rotating slowly. If you're having an issue with how arcs are rendered, you'll need to draw the arc yourself - with ``begin_shape()`` & ``end_shape()`` or a ``Py5Shape``. + with `begin_shape()` & `end_shape()` or a `Py5Shape`. """ pass @@ -1144,27 +1145,27 @@ def arc(*args): ----- Draws an arc to the screen. Arcs are drawn along the outer edge of an ellipse - defined by the ``a``, ``b``, ``c``, and ``d`` parameters. The origin of the - arc's ellipse may be changed with the ``ellipse_mode()`` function. Use the - ``start`` and ``stop`` parameters to specify the angles (in radians) at which to - draw the arc. The start/stop values must be in clockwise order. + defined by the `a`, `b`, `c`, and `d` parameters. The origin of the arc's + ellipse may be changed with the `ellipse_mode()` function. Use the `start` and + `stop` parameters to specify the angles (in radians) at which to draw the arc. + The start/stop values must be in clockwise order. There are three ways to draw an arc; the rendering technique used is defined by the optional seventh parameter. The three options, depicted in the examples, are - ``PIE``, ``OPEN``, and ``CHORD``. The default mode is the ``OPEN`` stroke with a - ``PIE`` fill. + `PIE`, `OPEN`, and `CHORD`. The default mode is the `OPEN` stroke with a `PIE` + fill. - In some cases, the ``arc()`` function isn't accurate enough for smooth drawing. + In some cases, the `arc()` function isn't accurate enough for smooth drawing. For example, the shape may jitter on screen when rotating slowly. If you're having an issue with how arcs are rendered, you'll need to draw the arc yourself - with ``begin_shape()`` & ``end_shape()`` or a ``Py5Shape``. + with `begin_shape()` & `end_shape()` or a `Py5Shape`. """ return _py5sketch.arc(*args) @overload def background(gray: float, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -1209,27 +1210,27 @@ def background(gray: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(gray: float, alpha: float, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -1274,27 +1275,27 @@ def background(gray: float, alpha: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(v1: float, v2: float, v3: float, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -1339,27 +1340,27 @@ def background(v1: float, v2: float, v3: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(v1: float, v2: float, v3: float, alpha: float, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -1404,27 +1405,27 @@ def background(v1: float, v2: float, v3: float, alpha: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(rgb: int, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -1469,27 +1470,27 @@ def background(rgb: int, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(rgb: int, alpha: float, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -1534,27 +1535,27 @@ def background(rgb: int, alpha: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(image: Py5Image, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -1599,26 +1600,26 @@ def background(image: Py5Image, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass def background(*args): - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -1663,79 +1664,77 @@ def background(*args): Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ return _py5sketch.background(*args) def begin_camera() -> None: - """The ``begin_camera()`` and ``end_camera()`` functions enable advanced - customization of the camera space. + """The `begin_camera()` and `end_camera()` functions enable advanced customization + of the camera space. Underlying Processing method: PApplet.beginCamera Notes ----- - The ``begin_camera()`` and ``end_camera()`` functions enable advanced - customization of the camera space. The functions are useful if you want to more - control over camera movement, however for most users, the ``camera()`` function - will be sufficient. The camera functions will replace any transformations (such - as ``rotate()`` or ``translate()``) that occur before them in ``draw()``, but - they will not automatically replace the camera transform itself. For this - reason, camera functions should be placed at the beginning of ``draw()`` (so - that transformations happen afterwards), and the ``camera()`` function can be - used after ``begin_camera()`` if you want to reset the camera before applying + The `begin_camera()` and `end_camera()` functions enable advanced customization + of the camera space. The functions are useful if you want to more control over + camera movement, however for most users, the `camera()` function will be + sufficient. The camera functions will replace any transformations (such as + `rotate()` or `translate()`) that occur before them in `draw()`, but they will + not automatically replace the camera transform itself. For this reason, camera + functions should be placed at the beginning of `draw()` (so that transformations + happen afterwards), and the `camera()` function can be used after + `begin_camera()` if you want to reset the camera before applying transformations. This function sets the matrix mode to the camera matrix so calls such as - ``translate()``, ``rotate()``, ``apply_matrix()`` and ``reset_matrix()`` affect - the camera. ``begin_camera()`` should always be used with a following - ``end_camera()`` and pairs of ``begin_camera()`` and ``end_camera()`` cannot be - nested. + `translate()`, `rotate()`, `apply_matrix()` and `reset_matrix()` affect the + camera. `begin_camera()` should always be used with a following `end_camera()` + and pairs of `begin_camera()` and `end_camera()` cannot be nested. - This method can be used as a context manager to ensure that ``end_camera()`` + This method can be used as a context manager to ensure that `end_camera()` always gets called, as shown in the last example. """ return _py5sketch.begin_camera() def begin_contour() -> None: - """Use the ``begin_contour()`` and ``end_contour()`` methods to create negative - shapes within shapes such as the center of the letter 'O'. + """Use the `begin_contour()` and `end_contour()` methods to create negative shapes + within shapes such as the center of the letter 'O'. Underlying Processing method: PApplet.beginContour Notes ----- - Use the ``begin_contour()`` and ``end_contour()`` methods to create negative - shapes within shapes such as the center of the letter 'O'. The - ``begin_contour()`` method begins recording vertices for the shape and - ``end_contour()`` stops recording. The vertices that define a negative shape - must "wind" in the opposite direction from the exterior shape. First draw - vertices for the exterior shape in clockwise order, then for internal shapes, - draw vertices counterclockwise. + Use the `begin_contour()` and `end_contour()` methods to create negative shapes + within shapes such as the center of the letter 'O'. The `begin_contour()` method + begins recording vertices for the shape and `end_contour()` stops recording. The + vertices that define a negative shape must "wind" in the opposite direction from + the exterior shape. First draw vertices for the exterior shape in clockwise + order, then for internal shapes, draw vertices counterclockwise. - These methods can only be used within a ``begin_shape()`` & ``end_shape()`` pair - and transformations such as ``translate()``, ``rotate()``, and ``scale()`` do - not work within a ``begin_contour()`` & ``end_contour()`` pair. It is also not - possible to use other shapes, such as ``ellipse()`` or ``rect()`` within. + These methods can only be used within a `begin_shape()` & `end_shape()` pair and + transformations such as `translate()`, `rotate()`, and `scale()` do not work + within a `begin_contour()` & `end_contour()` pair. It is also not possible to + use other shapes, such as `ellipse()` or `rect()` within. - This method can be used as a context manager to ensure that ``end_contour()`` + This method can be used as a context manager to ensure that `end_contour()` always gets called, as shown in the second example. """ return _py5sketch.begin_contour() @@ -1743,8 +1742,7 @@ def begin_contour() -> None: @overload def begin_raw(renderer: str, filename: str, /) -> Py5Graphics: - """To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. + """To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. Underlying Processing method: PApplet.beginRaw @@ -1771,37 +1769,36 @@ def begin_raw(renderer: str, filename: str, /) -> Py5Graphics: Notes ----- - To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. These commands will grab the shape data just before it is rendered to - the screen. At this stage, your entire scene is nothing but a long list of - individual lines and triangles. This means that a shape created with - ``sphere()`` function will be made up of hundreds of triangles, rather than a - single object. Or that a multi-segment line shape (such as a curve) will be - rendered as individual segments. + To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. + These commands will grab the shape data just before it is rendered to the + screen. At this stage, your entire scene is nothing but a long list of + individual lines and triangles. This means that a shape created with `sphere()` + function will be made up of hundreds of triangles, rather than a single object. + Or that a multi-segment line shape (such as a curve) will be rendered as + individual segments. - When using ``begin_raw()`` and ``end_raw()``, it's possible to write to either a - 2D or 3D renderer. For instance, ``begin_raw()`` with the ``PDF`` library will - write the geometry as flattened triangles and lines, even if recording from the - ``P3D`` renderer. + When using `begin_raw()` and `end_raw()`, it's possible to write to either a 2D + or 3D renderer. For instance, `begin_raw()` with the `PDF` library will write + the geometry as flattened triangles and lines, even if recording from the `P3D` + renderer. - If you want a background to show up in your files, use ``rect(0, 0, width, - height)`` after setting the ``fill()`` to the background color. Otherwise the + If you want a background to show up in your files, use `rect(0, 0, width, + height)` after setting the `fill()` to the background color. Otherwise the background will not be rendered to the file because the background is not a shape. - This method can be used as a context manager to ensure that ``end_raw()`` always + This method can be used as a context manager to ensure that `end_raw()` always gets called, as shown in the last example. - Using ``hint(ENABLE_DEPTH_SORT)`` can improve the appearance of 3D geometry - drawn to 2D file formats. + Using `hint(ENABLE_DEPTH_SORT)` can improve the appearance of 3D geometry drawn + to 2D file formats. """ pass @overload def begin_raw(raw_graphics: Py5Graphics, /) -> None: - """To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. + """To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. Underlying Processing method: PApplet.beginRaw @@ -1828,36 +1825,35 @@ def begin_raw(raw_graphics: Py5Graphics, /) -> None: Notes ----- - To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. These commands will grab the shape data just before it is rendered to - the screen. At this stage, your entire scene is nothing but a long list of - individual lines and triangles. This means that a shape created with - ``sphere()`` function will be made up of hundreds of triangles, rather than a - single object. Or that a multi-segment line shape (such as a curve) will be - rendered as individual segments. + To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. + These commands will grab the shape data just before it is rendered to the + screen. At this stage, your entire scene is nothing but a long list of + individual lines and triangles. This means that a shape created with `sphere()` + function will be made up of hundreds of triangles, rather than a single object. + Or that a multi-segment line shape (such as a curve) will be rendered as + individual segments. - When using ``begin_raw()`` and ``end_raw()``, it's possible to write to either a - 2D or 3D renderer. For instance, ``begin_raw()`` with the ``PDF`` library will - write the geometry as flattened triangles and lines, even if recording from the - ``P3D`` renderer. + When using `begin_raw()` and `end_raw()`, it's possible to write to either a 2D + or 3D renderer. For instance, `begin_raw()` with the `PDF` library will write + the geometry as flattened triangles and lines, even if recording from the `P3D` + renderer. - If you want a background to show up in your files, use ``rect(0, 0, width, - height)`` after setting the ``fill()`` to the background color. Otherwise the + If you want a background to show up in your files, use `rect(0, 0, width, + height)` after setting the `fill()` to the background color. Otherwise the background will not be rendered to the file because the background is not a shape. - This method can be used as a context manager to ensure that ``end_raw()`` always + This method can be used as a context manager to ensure that `end_raw()` always gets called, as shown in the last example. - Using ``hint(ENABLE_DEPTH_SORT)`` can improve the appearance of 3D geometry - drawn to 2D file formats. + Using `hint(ENABLE_DEPTH_SORT)` can improve the appearance of 3D geometry drawn + to 2D file formats. """ pass def begin_raw(*args): - """To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. + """To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. Underlying Processing method: PApplet.beginRaw @@ -1884,29 +1880,29 @@ def begin_raw(*args): Notes ----- - To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. These commands will grab the shape data just before it is rendered to - the screen. At this stage, your entire scene is nothing but a long list of - individual lines and triangles. This means that a shape created with - ``sphere()`` function will be made up of hundreds of triangles, rather than a - single object. Or that a multi-segment line shape (such as a curve) will be - rendered as individual segments. + To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. + These commands will grab the shape data just before it is rendered to the + screen. At this stage, your entire scene is nothing but a long list of + individual lines and triangles. This means that a shape created with `sphere()` + function will be made up of hundreds of triangles, rather than a single object. + Or that a multi-segment line shape (such as a curve) will be rendered as + individual segments. - When using ``begin_raw()`` and ``end_raw()``, it's possible to write to either a - 2D or 3D renderer. For instance, ``begin_raw()`` with the ``PDF`` library will - write the geometry as flattened triangles and lines, even if recording from the - ``P3D`` renderer. + When using `begin_raw()` and `end_raw()`, it's possible to write to either a 2D + or 3D renderer. For instance, `begin_raw()` with the `PDF` library will write + the geometry as flattened triangles and lines, even if recording from the `P3D` + renderer. - If you want a background to show up in your files, use ``rect(0, 0, width, - height)`` after setting the ``fill()`` to the background color. Otherwise the + If you want a background to show up in your files, use `rect(0, 0, width, + height)` after setting the `fill()` to the background color. Otherwise the background will not be rendered to the file because the background is not a shape. - This method can be used as a context manager to ensure that ``end_raw()`` always + This method can be used as a context manager to ensure that `end_raw()` always gets called, as shown in the last example. - Using ``hint(ENABLE_DEPTH_SORT)`` can improve the appearance of 3D geometry - drawn to 2D file formats. + Using `hint(ENABLE_DEPTH_SORT)` can improve the appearance of 3D geometry drawn + to 2D file formats. """ return _py5sketch.begin_raw(*args) @@ -1942,19 +1938,19 @@ def begin_record(renderer: str, filename: str, /) -> Py5Graphics: ----- Opens a new file and all subsequent drawing functions are echoed to this file as - well as the display window. The ``begin_record()`` function requires two + well as the display window. The `begin_record()` function requires two parameters, the first is the renderer and the second is the file name. This - function is always used with ``end_record()`` to stop the recording process and + function is always used with `end_record()` to stop the recording process and close the file. - Note that ``begin_record()`` will only pick up any settings that happen after it - has been called. For instance, if you call ``text_font()`` before - ``begin_record()``, then that font will not be set for the file that you're + Note that `begin_record()` will only pick up any settings that happen after it + has been called. For instance, if you call `text_font()` before + `begin_record()`, then that font will not be set for the file that you're recording to. - ``begin_record()`` works only with the ``PDF`` and ``SVG`` renderers. + `begin_record()` works only with the `PDF` and `SVG` renderers. - This method can be used as a context manager to ensure that ``end_record()`` + This method can be used as a context manager to ensure that `end_record()` always gets called, as shown in the last example. """ pass @@ -1991,19 +1987,19 @@ def begin_record(recorder: Py5Graphics, /) -> None: ----- Opens a new file and all subsequent drawing functions are echoed to this file as - well as the display window. The ``begin_record()`` function requires two + well as the display window. The `begin_record()` function requires two parameters, the first is the renderer and the second is the file name. This - function is always used with ``end_record()`` to stop the recording process and + function is always used with `end_record()` to stop the recording process and close the file. - Note that ``begin_record()`` will only pick up any settings that happen after it - has been called. For instance, if you call ``text_font()`` before - ``begin_record()``, then that font will not be set for the file that you're + Note that `begin_record()` will only pick up any settings that happen after it + has been called. For instance, if you call `text_font()` before + `begin_record()`, then that font will not be set for the file that you're recording to. - ``begin_record()`` works only with the ``PDF`` and ``SVG`` renderers. + `begin_record()` works only with the `PDF` and `SVG` renderers. - This method can be used as a context manager to ensure that ``end_record()`` + This method can be used as a context manager to ensure that `end_record()` always gets called, as shown in the last example. """ pass @@ -2039,19 +2035,19 @@ def begin_record(*args): ----- Opens a new file and all subsequent drawing functions are echoed to this file as - well as the display window. The ``begin_record()`` function requires two + well as the display window. The `begin_record()` function requires two parameters, the first is the renderer and the second is the file name. This - function is always used with ``end_record()`` to stop the recording process and + function is always used with `end_record()` to stop the recording process and close the file. - Note that ``begin_record()`` will only pick up any settings that happen after it - has been called. For instance, if you call ``text_font()`` before - ``begin_record()``, then that font will not be set for the file that you're + Note that `begin_record()` will only pick up any settings that happen after it + has been called. For instance, if you call `text_font()` before + `begin_record()`, then that font will not be set for the file that you're recording to. - ``begin_record()`` works only with the ``PDF`` and ``SVG`` renderers. + `begin_record()` works only with the `PDF` and `SVG` renderers. - This method can be used as a context manager to ensure that ``end_record()`` + This method can be used as a context manager to ensure that `end_record()` always gets called, as shown in the last example. """ return _py5sketch.begin_record(*args) @@ -2059,7 +2055,7 @@ def begin_record(*args): @overload def begin_shape() -> None: - """Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more + """Using the `begin_shape()` and `end_shape()` functions allow creating more complex forms. Underlying Processing method: PApplet.beginShape @@ -2081,40 +2077,39 @@ def begin_shape() -> None: Notes ----- - Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more - complex forms. ``begin_shape()`` begins recording vertices for a shape and - ``end_shape()`` stops recording. The value of the ``kind`` parameter tells it - which types of shapes to create from the provided vertices. With no mode - specified, the shape can be any irregular polygon. The parameters available for - ``begin_shape()`` are ``POINTS``, ``LINES``, ``TRIANGLES``, ``TRIANGLE_FAN``, - ``TRIANGLE_STRIP``, ``QUADS``, and ``QUAD_STRIP``. After calling the - ``begin_shape()`` function, a series of ``vertex()`` commands must follow. To - stop drawing the shape, call ``end_shape()``. The ``vertex()`` function with two - parameters specifies a position in 2D and the ``vertex()`` function with three - parameters specifies a position in 3D. Each shape will be outlined with the - current stroke color and filled with the fill color. + Using the `begin_shape()` and `end_shape()` functions allow creating more + complex forms. `begin_shape()` begins recording vertices for a shape and + `end_shape()` stops recording. The value of the `kind` parameter tells it which + types of shapes to create from the provided vertices. With no mode specified, + the shape can be any irregular polygon. The parameters available for + `begin_shape()` are `POINTS`, `LINES`, `TRIANGLES`, `TRIANGLE_FAN`, + `TRIANGLE_STRIP`, `QUADS`, and `QUAD_STRIP`. After calling the `begin_shape()` + function, a series of `vertex()` commands must follow. To stop drawing the + shape, call `end_shape()`. The `vertex()` function with two parameters specifies + a position in 2D and the `vertex()` function with three parameters specifies a + position in 3D. Each shape will be outlined with the current stroke color and + filled with the fill color. - Transformations such as ``translate()``, ``rotate()``, and ``scale()`` do not - work within ``begin_shape()``. It is also not possible to use other shapes, such - as ``ellipse()`` or ``rect()`` within ``begin_shape()``. + Transformations such as `translate()`, `rotate()`, and `scale()` do not work + within `begin_shape()`. It is also not possible to use other shapes, such as + `ellipse()` or `rect()` within `begin_shape()`. - The ``P2D`` and ``P3D`` renderers allow ``stroke()`` and ``fill()`` to be - altered on a per-vertex basis, but the default renderer does not. Settings such - as ``stroke_weight()``, ``stroke_cap()``, and ``stroke_join()`` cannot be - changed while inside a ``begin_shape()`` & ``end_shape()`` block with any - renderer. + The `P2D` and `P3D` renderers allow `stroke()` and `fill()` to be altered on a + per-vertex basis, but the default renderer does not. Settings such as + `stroke_weight()`, `stroke_cap()`, and `stroke_join()` cannot be changed while + inside a `begin_shape()` & `end_shape()` block with any renderer. - This method can be used as a context manager to ensure that ``end_shape()`` - always gets called, as shown in the last example. Use ``begin_closed_shape()`` - to create a context manager that will pass the ``CLOSE`` parameter to - ``end_shape()``, closing the shape. + This method can be used as a context manager to ensure that `end_shape()` always + gets called, as shown in the last example. Use `begin_closed_shape()` to create + a context manager that will pass the `CLOSE` parameter to `end_shape()`, closing + the shape. """ pass @overload def begin_shape(kind: int, /) -> None: - """Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more + """Using the `begin_shape()` and `end_shape()` functions allow creating more complex forms. Underlying Processing method: PApplet.beginShape @@ -2136,39 +2131,38 @@ def begin_shape(kind: int, /) -> None: Notes ----- - Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more - complex forms. ``begin_shape()`` begins recording vertices for a shape and - ``end_shape()`` stops recording. The value of the ``kind`` parameter tells it - which types of shapes to create from the provided vertices. With no mode - specified, the shape can be any irregular polygon. The parameters available for - ``begin_shape()`` are ``POINTS``, ``LINES``, ``TRIANGLES``, ``TRIANGLE_FAN``, - ``TRIANGLE_STRIP``, ``QUADS``, and ``QUAD_STRIP``. After calling the - ``begin_shape()`` function, a series of ``vertex()`` commands must follow. To - stop drawing the shape, call ``end_shape()``. The ``vertex()`` function with two - parameters specifies a position in 2D and the ``vertex()`` function with three - parameters specifies a position in 3D. Each shape will be outlined with the - current stroke color and filled with the fill color. + Using the `begin_shape()` and `end_shape()` functions allow creating more + complex forms. `begin_shape()` begins recording vertices for a shape and + `end_shape()` stops recording. The value of the `kind` parameter tells it which + types of shapes to create from the provided vertices. With no mode specified, + the shape can be any irregular polygon. The parameters available for + `begin_shape()` are `POINTS`, `LINES`, `TRIANGLES`, `TRIANGLE_FAN`, + `TRIANGLE_STRIP`, `QUADS`, and `QUAD_STRIP`. After calling the `begin_shape()` + function, a series of `vertex()` commands must follow. To stop drawing the + shape, call `end_shape()`. The `vertex()` function with two parameters specifies + a position in 2D and the `vertex()` function with three parameters specifies a + position in 3D. Each shape will be outlined with the current stroke color and + filled with the fill color. - Transformations such as ``translate()``, ``rotate()``, and ``scale()`` do not - work within ``begin_shape()``. It is also not possible to use other shapes, such - as ``ellipse()`` or ``rect()`` within ``begin_shape()``. + Transformations such as `translate()`, `rotate()`, and `scale()` do not work + within `begin_shape()`. It is also not possible to use other shapes, such as + `ellipse()` or `rect()` within `begin_shape()`. - The ``P2D`` and ``P3D`` renderers allow ``stroke()`` and ``fill()`` to be - altered on a per-vertex basis, but the default renderer does not. Settings such - as ``stroke_weight()``, ``stroke_cap()``, and ``stroke_join()`` cannot be - changed while inside a ``begin_shape()`` & ``end_shape()`` block with any - renderer. + The `P2D` and `P3D` renderers allow `stroke()` and `fill()` to be altered on a + per-vertex basis, but the default renderer does not. Settings such as + `stroke_weight()`, `stroke_cap()`, and `stroke_join()` cannot be changed while + inside a `begin_shape()` & `end_shape()` block with any renderer. - This method can be used as a context manager to ensure that ``end_shape()`` - always gets called, as shown in the last example. Use ``begin_closed_shape()`` - to create a context manager that will pass the ``CLOSE`` parameter to - ``end_shape()``, closing the shape. + This method can be used as a context manager to ensure that `end_shape()` always + gets called, as shown in the last example. Use `begin_closed_shape()` to create + a context manager that will pass the `CLOSE` parameter to `end_shape()`, closing + the shape. """ pass def begin_shape(*args): - """Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more + """Using the `begin_shape()` and `end_shape()` functions allow creating more complex forms. Underlying Processing method: PApplet.beginShape @@ -2190,33 +2184,32 @@ def begin_shape(*args): Notes ----- - Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more - complex forms. ``begin_shape()`` begins recording vertices for a shape and - ``end_shape()`` stops recording. The value of the ``kind`` parameter tells it - which types of shapes to create from the provided vertices. With no mode - specified, the shape can be any irregular polygon. The parameters available for - ``begin_shape()`` are ``POINTS``, ``LINES``, ``TRIANGLES``, ``TRIANGLE_FAN``, - ``TRIANGLE_STRIP``, ``QUADS``, and ``QUAD_STRIP``. After calling the - ``begin_shape()`` function, a series of ``vertex()`` commands must follow. To - stop drawing the shape, call ``end_shape()``. The ``vertex()`` function with two - parameters specifies a position in 2D and the ``vertex()`` function with three - parameters specifies a position in 3D. Each shape will be outlined with the - current stroke color and filled with the fill color. + Using the `begin_shape()` and `end_shape()` functions allow creating more + complex forms. `begin_shape()` begins recording vertices for a shape and + `end_shape()` stops recording. The value of the `kind` parameter tells it which + types of shapes to create from the provided vertices. With no mode specified, + the shape can be any irregular polygon. The parameters available for + `begin_shape()` are `POINTS`, `LINES`, `TRIANGLES`, `TRIANGLE_FAN`, + `TRIANGLE_STRIP`, `QUADS`, and `QUAD_STRIP`. After calling the `begin_shape()` + function, a series of `vertex()` commands must follow. To stop drawing the + shape, call `end_shape()`. The `vertex()` function with two parameters specifies + a position in 2D and the `vertex()` function with three parameters specifies a + position in 3D. Each shape will be outlined with the current stroke color and + filled with the fill color. - Transformations such as ``translate()``, ``rotate()``, and ``scale()`` do not - work within ``begin_shape()``. It is also not possible to use other shapes, such - as ``ellipse()`` or ``rect()`` within ``begin_shape()``. + Transformations such as `translate()`, `rotate()`, and `scale()` do not work + within `begin_shape()`. It is also not possible to use other shapes, such as + `ellipse()` or `rect()` within `begin_shape()`. - The ``P2D`` and ``P3D`` renderers allow ``stroke()`` and ``fill()`` to be - altered on a per-vertex basis, but the default renderer does not. Settings such - as ``stroke_weight()``, ``stroke_cap()``, and ``stroke_join()`` cannot be - changed while inside a ``begin_shape()`` & ``end_shape()`` block with any - renderer. + The `P2D` and `P3D` renderers allow `stroke()` and `fill()` to be altered on a + per-vertex basis, but the default renderer does not. Settings such as + `stroke_weight()`, `stroke_cap()`, and `stroke_join()` cannot be changed while + inside a `begin_shape()` & `end_shape()` block with any renderer. - This method can be used as a context manager to ensure that ``end_shape()`` - always gets called, as shown in the last example. Use ``begin_closed_shape()`` - to create a context manager that will pass the ``CLOSE`` parameter to - ``end_shape()``, closing the shape. + This method can be used as a context manager to ensure that `end_shape()` always + gets called, as shown in the last example. Use `begin_closed_shape()` to create + a context manager that will pass the `CLOSE` parameter to `end_shape()`, closing + the shape. """ return _py5sketch.begin_shape(*args) @@ -2246,12 +2239,12 @@ def begin_closed_shape() -> None: This method is used to start a custom closed shape. This method should only be used as a context manager, as shown in the examples. When used as a context - manager, this will ensure that ``end_shape()`` always gets called, just like - when using ``begin_shape()`` as a context manager. The difference is that when - exiting, the parameter ``CLOSE`` will be passed to ``end_shape()``, connecting - the last vertex to the first. This will close the shape. If this method were to - be used not as a context manager, it won't be able to close the shape by making - the call to ``end_shape()``. + manager, this will ensure that `end_shape()` always gets called, just like when + using `begin_shape()` as a context manager. The difference is that when exiting, + the parameter `CLOSE` will be passed to `end_shape()`, connecting the last + vertex to the first. This will close the shape. If this method were to be used + not as a context manager, it won't be able to close the shape by making the call + to `end_shape()`. """ pass @@ -2281,12 +2274,12 @@ def begin_closed_shape(kind: int, /) -> None: This method is used to start a custom closed shape. This method should only be used as a context manager, as shown in the examples. When used as a context - manager, this will ensure that ``end_shape()`` always gets called, just like - when using ``begin_shape()`` as a context manager. The difference is that when - exiting, the parameter ``CLOSE`` will be passed to ``end_shape()``, connecting - the last vertex to the first. This will close the shape. If this method were to - be used not as a context manager, it won't be able to close the shape by making - the call to ``end_shape()``. + manager, this will ensure that `end_shape()` always gets called, just like when + using `begin_shape()` as a context manager. The difference is that when exiting, + the parameter `CLOSE` will be passed to `end_shape()`, connecting the last + vertex to the first. This will close the shape. If this method were to be used + not as a context manager, it won't be able to close the shape by making the call + to `end_shape()`. """ pass @@ -2315,12 +2308,12 @@ def begin_closed_shape(*args): This method is used to start a custom closed shape. This method should only be used as a context manager, as shown in the examples. When used as a context - manager, this will ensure that ``end_shape()`` always gets called, just like - when using ``begin_shape()`` as a context manager. The difference is that when - exiting, the parameter ``CLOSE`` will be passed to ``end_shape()``, connecting - the last vertex to the first. This will close the shape. If this method were to - be used not as a context manager, it won't be able to close the shape by making - the call to ``end_shape()``. + manager, this will ensure that `end_shape()` always gets called, just like when + using `begin_shape()` as a context manager. The difference is that when exiting, + the parameter `CLOSE` will be passed to `end_shape()`, connecting the last + vertex to the first. This will close the shape. If this method were to be used + not as a context manager, it won't be able to close the shape by making the call + to `end_shape()`. """ return _py5sketch.begin_closed_shape(*args) @@ -2387,7 +2380,7 @@ def bezier(x1: float, y1: float, x2: float, y2: float, x3: float, point and the last two parameters specify the other anchor point. The middle parameters specify the control points which define the shape of the curve. Bezier curves were developed by French engineer Pierre Bezier. Using the 3D - version requires rendering with ``P3D``. + version requires rendering with `P3D`. """ pass @@ -2454,7 +2447,7 @@ def bezier(x1: float, y1: float, z1: float, x2: float, y2: float, z2: float, point and the last two parameters specify the other anchor point. The middle parameters specify the control points which define the shape of the curve. Bezier curves were developed by French engineer Pierre Bezier. Using the 3D - version requires rendering with ``P3D``. + version requires rendering with `P3D`. """ pass @@ -2519,7 +2512,7 @@ def bezier(*args): point and the last two parameters specify the other anchor point. The middle parameters specify the control points which define the shape of the curve. Bezier curves were developed by French engineer Pierre Bezier. Using the 3D - version requires rendering with ``P3D``. + version requires rendering with `P3D`. """ return _py5sketch.bezier(*args) @@ -2539,7 +2532,7 @@ def bezier_detail(detail: int, /) -> None: ----- Sets the resolution at which Beziers display. The default value is 20. This - function is only useful when using the ``P3D`` renderer; the default ``P2D`` + function is only useful when using the `P3D` renderer; the default `P2D` renderer does not use this information. """ return _py5sketch.bezier_detail(detail) @@ -2660,14 +2653,14 @@ def bezier_vertex(x2: float, y2: float, x3: float, y3: float, Notes ----- - Specifies vertex coordinates for Bezier curves. Each call to ``bezier_vertex()`` + Specifies vertex coordinates for Bezier curves. Each call to `bezier_vertex()` defines the position of two control points and one anchor point of a Bezier - curve, adding a new segment to a line or shape. The first time - ``bezier_vertex()`` is used within a ``begin_shape()`` call, it must be prefaced - with a call to ``vertex()`` to set the first anchor point. This function must be - used between ``begin_shape()`` and ``end_shape()`` and only when there is no - ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + curve, adding a new segment to a line or shape. The first time `bezier_vertex()` + is used within a `begin_shape()` call, it must be prefaced with a call to + `vertex()` to set the first anchor point. This function must be used between + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. Using the 3D version requires rendering with + `P3D`. """ pass @@ -2720,14 +2713,14 @@ def bezier_vertex(x2: float, y2: float, z2: float, x3: float, Notes ----- - Specifies vertex coordinates for Bezier curves. Each call to ``bezier_vertex()`` + Specifies vertex coordinates for Bezier curves. Each call to `bezier_vertex()` defines the position of two control points and one anchor point of a Bezier - curve, adding a new segment to a line or shape. The first time - ``bezier_vertex()`` is used within a ``begin_shape()`` call, it must be prefaced - with a call to ``vertex()`` to set the first anchor point. This function must be - used between ``begin_shape()`` and ``end_shape()`` and only when there is no - ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + curve, adding a new segment to a line or shape. The first time `bezier_vertex()` + is used within a `begin_shape()` call, it must be prefaced with a call to + `vertex()` to set the first anchor point. This function must be used between + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. Using the 3D version requires rendering with + `P3D`. """ pass @@ -2778,14 +2771,14 @@ def bezier_vertex(*args): Notes ----- - Specifies vertex coordinates for Bezier curves. Each call to ``bezier_vertex()`` + Specifies vertex coordinates for Bezier curves. Each call to `bezier_vertex()` defines the position of two control points and one anchor point of a Bezier - curve, adding a new segment to a line or shape. The first time - ``bezier_vertex()`` is used within a ``begin_shape()`` call, it must be prefaced - with a call to ``vertex()`` to set the first anchor point. This function must be - used between ``begin_shape()`` and ``end_shape()`` and only when there is no - ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + curve, adding a new segment to a line or shape. The first time `bezier_vertex()` + is used within a `begin_shape()` call, it must be prefaced with a call to + `vertex()` to set the first anchor point. This function must be used between + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. Using the 3D version requires rendering with + `P3D`. """ return _py5sketch.bezier_vertex(*args) @@ -2805,14 +2798,14 @@ def bezier_vertices(coordinates: npt.NDArray[np.floating], /) -> None: ----- Create a collection of bezier vertices. The purpose of this method is to provide - an alternative to repeatedly calling ``bezier_vertex()`` in a loop. For a large - number of bezier vertices, the performance of ``bezier_vertices()`` will be much + an alternative to repeatedly calling `bezier_vertex()` in a loop. For a large + number of bezier vertices, the performance of `bezier_vertices()` will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each - bezier vertex. The first few columns are for the first control point, the next - few columns are for the second control point, and the final few columns are for - the anchor point. There should be six or nine columns for 2D or 3D points, + The `coordinates` parameter should be a numpy array with one row for each bezier + vertex. The first few columns are for the first control point, the next few + columns are for the second control point, and the final few columns are for the + anchor point. There should be six or nine columns for 2D or 3D points, respectively. """ return _py5sketch.bezier_vertices(coordinates) @@ -2874,11 +2867,11 @@ def blend(sx: int, sy: int, sw: int, sh: int, dx: int, full alpha channel support. There is a choice of the following modes to blend the source pixels (A) with the ones of pixels in the destination image (B): - * BLEND: linear interpolation of colors: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colors: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -2895,10 +2888,10 @@ def blend(sx: int, sy: int, sw: int, sh: int, dx: int, All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the display window is used as the source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the display window is used as the source image. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @@ -2959,11 +2952,11 @@ def blend(src: Py5Image, sx: int, sy: int, sw: int, sh: int, full alpha channel support. There is a choice of the following modes to blend the source pixels (A) with the ones of pixels in the destination image (B): - * BLEND: linear interpolation of colors: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colors: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -2980,10 +2973,10 @@ def blend(src: Py5Image, sx: int, sy: int, sw: int, sh: int, All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the display window is used as the source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the display window is used as the source image. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @@ -3042,11 +3035,11 @@ def blend(*args): full alpha channel support. There is a choice of the following modes to blend the source pixels (A) with the ones of pixels in the destination image (B): - * BLEND: linear interpolation of colors: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colors: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -3063,10 +3056,10 @@ def blend(*args): All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the display window is used as the source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the display window is used as the source image. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ return _py5sketch.blend(*args) @@ -3092,12 +3085,12 @@ def blend_mode(mode: int, /) -> None: independently. The red channel is compared with red, green with green, and blue with blue. - * BLEND: linear interpolation of colors: ``C = A*factor + B``. This is the + * BLEND: linear interpolation of colors: `C = A*factor + B`. This is the default. - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: multiply the colors, result will always be darker. @@ -3105,17 +3098,17 @@ def blend_mode(mode: int, /) -> None: * REPLACE: the pixels entirely replace the others and don't utilize alpha (transparency) values - We recommend using ``blend_mode()`` and not the previous ``blend()`` function. - However, unlike ``blend()``, the ``blend_mode()`` function does not support the - following: ``HARD_LIGHT``, ``SOFT_LIGHT``, ``OVERLAY``, ``DODGE``, ``BURN``. On - older hardware, the ``LIGHTEST``, ``DARKEST``, and ``DIFFERENCE`` modes might - not be available as well. + We recommend using `blend_mode()` and not the previous `blend()` function. + However, unlike `blend()`, the `blend_mode()` function does not support the + following: `HARD_LIGHT`, `SOFT_LIGHT`, `OVERLAY`, `DODGE`, `BURN`. On older + hardware, the `LIGHTEST`, `DARKEST`, and `DIFFERENCE` modes might not be + available as well. """ return _py5sketch.blend_mode(mode) def blue(rgb: int, /) -> float: - """Extracts the blue value from a color, scaled to match current ``color_mode()``. + """Extracts the blue value from a color, scaled to match current `color_mode()`. Underlying Processing method: PApplet.blue @@ -3128,14 +3121,13 @@ def blue(rgb: int, /) -> float: Notes ----- - Extracts the blue value from a color, scaled to match current ``color_mode()``. + Extracts the blue value from a color, scaled to match current `color_mode()`. - The ``blue()`` function is easy to use and understand, but it is slower than a - technique called bit masking. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``blue()`` but with greater speed by using a bit - mask to remove the other color components. For example, ``blue(c)`` and ``c & - 0xFF`` both extract the blue value from a color variable ``c`` but the later is - faster. + The `blue()` function is easy to use and understand, but it is slower than a + technique called bit masking. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `blue()` but with greater speed by using a bit mask + to remove the other color components. For example, `blue(c)` and `c & 0xFF` both + extract the blue value from a color variable `c` but the later is faster. """ return _py5sketch.blue(rgb) @@ -3325,9 +3317,9 @@ def camera() -> None: direction it is pointing (the center of the scene) allows the images to be seen from different angles. The version without any parameters sets the camera to the default position, pointing to the center of the display window with the Y axis - as up. The default values are ``camera(width//2.0, height//2.0, (height//2.0) / - tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)``. This function is - similar to ``glu_look_at()`` in OpenGL, but it first clears the current camera + as up. The default values are `camera(width//2.0, height//2.0, (height//2.0) / + tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)`. This function is + similar to `glu_look_at()` in OpenGL, but it first clears the current camera settings. """ pass @@ -3387,9 +3379,9 @@ def camera(eye_x: float, eye_y: float, eye_z: float, center_x: float, center_y: direction it is pointing (the center of the scene) allows the images to be seen from different angles. The version without any parameters sets the camera to the default position, pointing to the center of the display window with the Y axis - as up. The default values are ``camera(width//2.0, height//2.0, (height//2.0) / - tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)``. This function is - similar to ``glu_look_at()`` in OpenGL, but it first clears the current camera + as up. The default values are `camera(width//2.0, height//2.0, (height//2.0) / + tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)`. This function is + similar to `glu_look_at()` in OpenGL, but it first clears the current camera settings. """ pass @@ -3447,9 +3439,9 @@ def camera(*args): direction it is pointing (the center of the scene) allows the images to be seen from different angles. The version without any parameters sets the camera to the default position, pointing to the center of the display window with the Y axis - as up. The default values are ``camera(width//2.0, height//2.0, (height//2.0) / - tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)``. This function is - similar to ``glu_look_at()`` in OpenGL, but it first clears the current camera + as up. The default values are `camera(width//2.0, height//2.0, (height//2.0) / + tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)`. This function is + similar to `glu_look_at()` in OpenGL, but it first clears the current camera settings. """ return _py5sketch.camera(*args) @@ -3477,7 +3469,7 @@ def circle(x: float, y: float, extent: float, /) -> None: Draws a circle to the screen. By default, the first two parameters set the location of the center, and the third sets the shape's width and height. The - origin may be changed with the ``ellipse_mode()`` function. + origin may be changed with the `ellipse_mode()` function. """ return _py5sketch.circle(x, y, extent) @@ -3491,11 +3483,10 @@ def clear() -> None: ----- Clear the drawing surface by setting every pixel to black. Calling this method - is the same as passing ``0`` to the ``background()`` method, as in - ``background(0)``. + is the same as passing `0` to the `background()` method, as in `background(0)`. - This method behaves differently than ``Py5Graphics.clear()`` because - ``Py5Graphics`` objects allow transparent pixels. + This method behaves differently than `Py5Graphics.clear()` because `Py5Graphics` + objects allow transparent pixels. """ return _py5sketch.clear() @@ -3524,15 +3515,15 @@ def clip(a: float, b: float, c: float, d: float, /) -> None: ----- Limits the rendering to the boundaries of a rectangle defined by the parameters. - The boundaries are drawn based on the state of the ``image_mode()`` fuction, - either ``CORNER``, ``CORNERS``, or ``CENTER``. + The boundaries are drawn based on the state of the `image_mode()` fuction, + either `CORNER`, `CORNERS`, or `CENTER`. """ return _py5sketch.clip(a, b, c, d) @overload def color(fgray: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -3590,43 +3581,43 @@ def color(fgray: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(fgray: float, falpha: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -3684,43 +3675,43 @@ def color(fgray: float, falpha: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(v1: float, v2: float, v3: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -3778,43 +3769,43 @@ def color(v1: float, v2: float, v3: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(v1: float, v2: float, v3: float, alpha: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -3872,43 +3863,43 @@ def color(v1: float, v2: float, v3: float, alpha: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(gray: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -3966,43 +3957,43 @@ def color(gray: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(gray: int, alpha: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -4060,43 +4051,43 @@ def color(gray: int, alpha: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(v1: int, v2: int, v3: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -4154,43 +4145,43 @@ def color(v1: int, v2: int, v3: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(v1: int, v2: int, v3: int, alpha: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -4248,42 +4239,42 @@ def color(v1: int, v2: int, v3: int, alpha: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass def color(*args): - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -4341,36 +4332,36 @@ def color(*args): Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ return _py5sketch.color(*args) @@ -4416,21 +4407,20 @@ def color_mode(mode: int, /) -> None: ----- Changes the way py5 interprets color data. By default, the parameters for - ``fill()``, ``stroke()``, ``background()``, and ``color()`` are defined by - values between 0 and 255 using the ``RGB`` color model. The ``color_mode()`` - function is used to change the numerical range used for specifying colors and to - switch color systems. For example, calling ``color_mode(RGB, 1.0)`` will specify - that values are specified between 0 and 1. The limits for defining colors are - altered by setting the parameters ``max``, ``max1``, ``max2``, ``max3``, and - ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `fill()`, `stroke()`, `background()`, and `color()` are defined by values + between 0 and 255 using the `RGB` color model. The `color_mode()` function is + used to change the numerical range used for specifying colors and to switch + color systems. For example, calling `color_mode(RGB, 1.0)` will specify that + values are specified between 0 and 1. The limits for defining colors are altered + by setting the parameters `max`, `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. """ pass @@ -4476,21 +4466,20 @@ def color_mode(mode: int, max: float, /) -> None: ----- Changes the way py5 interprets color data. By default, the parameters for - ``fill()``, ``stroke()``, ``background()``, and ``color()`` are defined by - values between 0 and 255 using the ``RGB`` color model. The ``color_mode()`` - function is used to change the numerical range used for specifying colors and to - switch color systems. For example, calling ``color_mode(RGB, 1.0)`` will specify - that values are specified between 0 and 1. The limits for defining colors are - altered by setting the parameters ``max``, ``max1``, ``max2``, ``max3``, and - ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `fill()`, `stroke()`, `background()`, and `color()` are defined by values + between 0 and 255 using the `RGB` color model. The `color_mode()` function is + used to change the numerical range used for specifying colors and to switch + color systems. For example, calling `color_mode(RGB, 1.0)` will specify that + values are specified between 0 and 1. The limits for defining colors are altered + by setting the parameters `max`, `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. """ pass @@ -4536,21 +4525,20 @@ def color_mode(mode: int, max1: float, max2: float, max3: float, /) -> None: ----- Changes the way py5 interprets color data. By default, the parameters for - ``fill()``, ``stroke()``, ``background()``, and ``color()`` are defined by - values between 0 and 255 using the ``RGB`` color model. The ``color_mode()`` - function is used to change the numerical range used for specifying colors and to - switch color systems. For example, calling ``color_mode(RGB, 1.0)`` will specify - that values are specified between 0 and 1. The limits for defining colors are - altered by setting the parameters ``max``, ``max1``, ``max2``, ``max3``, and - ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `fill()`, `stroke()`, `background()`, and `color()` are defined by values + between 0 and 255 using the `RGB` color model. The `color_mode()` function is + used to change the numerical range used for specifying colors and to switch + color systems. For example, calling `color_mode(RGB, 1.0)` will specify that + values are specified between 0 and 1. The limits for defining colors are altered + by setting the parameters `max`, `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. """ pass @@ -4597,21 +4585,20 @@ def color_mode(mode: int, max1: float, max2: float, ----- Changes the way py5 interprets color data. By default, the parameters for - ``fill()``, ``stroke()``, ``background()``, and ``color()`` are defined by - values between 0 and 255 using the ``RGB`` color model. The ``color_mode()`` - function is used to change the numerical range used for specifying colors and to - switch color systems. For example, calling ``color_mode(RGB, 1.0)`` will specify - that values are specified between 0 and 1. The limits for defining colors are - altered by setting the parameters ``max``, ``max1``, ``max2``, ``max3``, and - ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `fill()`, `stroke()`, `background()`, and `color()` are defined by values + between 0 and 255 using the `RGB` color model. The `color_mode()` function is + used to change the numerical range used for specifying colors and to switch + color systems. For example, calling `color_mode(RGB, 1.0)` will specify that + values are specified between 0 and 1. The limits for defining colors are altered + by setting the parameters `max`, `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. """ pass @@ -4656,21 +4643,20 @@ def color_mode(*args): ----- Changes the way py5 interprets color data. By default, the parameters for - ``fill()``, ``stroke()``, ``background()``, and ``color()`` are defined by - values between 0 and 255 using the ``RGB`` color model. The ``color_mode()`` - function is used to change the numerical range used for specifying colors and to - switch color systems. For example, calling ``color_mode(RGB, 1.0)`` will specify - that values are specified between 0 and 1. The limits for defining colors are - altered by setting the parameters ``max``, ``max1``, ``max2``, ``max3``, and - ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `fill()`, `stroke()`, `background()`, and `color()` are defined by values + between 0 and 255 using the `RGB` color model. The `color_mode()` function is + used to change the numerical range used for specifying colors and to switch + color systems. For example, calling `color_mode(RGB, 1.0)` will specify that + values are specified between 0 and 1. The limits for defining colors are altered + by setting the parameters `max`, `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. """ return _py5sketch.color_mode(*args) @@ -4678,7 +4664,7 @@ def color_mode(*args): @overload def copy() -> Py5Image: """Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. Underlying Processing method: PApplet.copy @@ -4726,13 +4712,13 @@ def copy() -> Py5Image: ----- Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @@ -4741,7 +4727,7 @@ def copy() -> Py5Image: def copy(sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, /) -> None: """Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. Underlying Processing method: PApplet.copy @@ -4789,13 +4775,13 @@ def copy(sx: int, sy: int, sw: int, sh: int, dx: int, ----- Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @@ -4804,7 +4790,7 @@ def copy(sx: int, sy: int, sw: int, sh: int, dx: int, def copy(src: Py5Image, sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, /) -> None: """Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. Underlying Processing method: PApplet.copy @@ -4852,20 +4838,20 @@ def copy(src: Py5Image, sx: int, sy: int, sw: int, sh: int, ----- Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass def copy(*args): """Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. Underlying Processing method: PApplet.copy @@ -4913,13 +4899,13 @@ def copy(*args): ----- Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ return _py5sketch.copy(*args) @@ -4962,24 +4948,24 @@ def create_font(name: str, size: float, /) -> Py5Font: Dynamically converts a font to the format used by py5 from a .ttf or .otf file inside the Sketch's "data" folder or a font that's installed elsewhere on the computer. If you want to use a font installed on your computer, use the - ``Py5Font.list()`` method to first determine the names for the fonts recognized - by the computer and are compatible with this function. Not all fonts can be used + `Py5Font.list()` method to first determine the names for the fonts recognized by + the computer and are compatible with this function. Not all fonts can be used and some might work with one operating system and not others. When sharing a Sketch with other people or posting it on the web, you may need to include a .ttf or .otf version of your font in the data directory of the Sketch because other people might not have the font installed on their computer. Only fonts that can legally be distributed should be included with a Sketch. - The ``size`` parameter states the font size you want to generate. The ``smooth`` - parameter specifies if the font should be antialiased or not. The ``charset`` + The `size` parameter states the font size you want to generate. The `smooth` + parameter specifies if the font should be antialiased or not. The `charset` parameter is an array of chars that specifies the characters to generate. This function allows py5 to work with the font natively in the default renderer, so the letters are defined by vector geometry and are rendered quickly. In the - ``P2D`` and ``P3D`` renderers, the function sets the project to render the font - as a series of small textures. For instance, when using the default renderer, - the actual native version of the font will be employed by the Sketch, improving - drawing quality and performance. With the ``P2D`` and ``P3D`` renderers, the + `P2D` and `P3D` renderers, the function sets the project to render the font as a + series of small textures. For instance, when using the default renderer, the + actual native version of the font will be employed by the Sketch, improving + drawing quality and performance. With the `P2D` and `P3D` renderers, the bitmapped version will be used to improve speed and appearance, but the results are poor when exporting if the Sketch does not include the .otf or .ttf file, and the requested font is not available on the machine running the Sketch. @@ -5025,24 +5011,24 @@ def create_font(name: str, size: float, smooth: bool, /) -> Py5Font: Dynamically converts a font to the format used by py5 from a .ttf or .otf file inside the Sketch's "data" folder or a font that's installed elsewhere on the computer. If you want to use a font installed on your computer, use the - ``Py5Font.list()`` method to first determine the names for the fonts recognized - by the computer and are compatible with this function. Not all fonts can be used + `Py5Font.list()` method to first determine the names for the fonts recognized by + the computer and are compatible with this function. Not all fonts can be used and some might work with one operating system and not others. When sharing a Sketch with other people or posting it on the web, you may need to include a .ttf or .otf version of your font in the data directory of the Sketch because other people might not have the font installed on their computer. Only fonts that can legally be distributed should be included with a Sketch. - The ``size`` parameter states the font size you want to generate. The ``smooth`` - parameter specifies if the font should be antialiased or not. The ``charset`` + The `size` parameter states the font size you want to generate. The `smooth` + parameter specifies if the font should be antialiased or not. The `charset` parameter is an array of chars that specifies the characters to generate. This function allows py5 to work with the font natively in the default renderer, so the letters are defined by vector geometry and are rendered quickly. In the - ``P2D`` and ``P3D`` renderers, the function sets the project to render the font - as a series of small textures. For instance, when using the default renderer, - the actual native version of the font will be employed by the Sketch, improving - drawing quality and performance. With the ``P2D`` and ``P3D`` renderers, the + `P2D` and `P3D` renderers, the function sets the project to render the font as a + series of small textures. For instance, when using the default renderer, the + actual native version of the font will be employed by the Sketch, improving + drawing quality and performance. With the `P2D` and `P3D` renderers, the bitmapped version will be used to improve speed and appearance, but the results are poor when exporting if the Sketch does not include the .otf or .ttf file, and the requested font is not available on the machine running the Sketch. @@ -5089,24 +5075,24 @@ def create_font(name: str, size: float, smooth: bool, Dynamically converts a font to the format used by py5 from a .ttf or .otf file inside the Sketch's "data" folder or a font that's installed elsewhere on the computer. If you want to use a font installed on your computer, use the - ``Py5Font.list()`` method to first determine the names for the fonts recognized - by the computer and are compatible with this function. Not all fonts can be used + `Py5Font.list()` method to first determine the names for the fonts recognized by + the computer and are compatible with this function. Not all fonts can be used and some might work with one operating system and not others. When sharing a Sketch with other people or posting it on the web, you may need to include a .ttf or .otf version of your font in the data directory of the Sketch because other people might not have the font installed on their computer. Only fonts that can legally be distributed should be included with a Sketch. - The ``size`` parameter states the font size you want to generate. The ``smooth`` - parameter specifies if the font should be antialiased or not. The ``charset`` + The `size` parameter states the font size you want to generate. The `smooth` + parameter specifies if the font should be antialiased or not. The `charset` parameter is an array of chars that specifies the characters to generate. This function allows py5 to work with the font natively in the default renderer, so the letters are defined by vector geometry and are rendered quickly. In the - ``P2D`` and ``P3D`` renderers, the function sets the project to render the font - as a series of small textures. For instance, when using the default renderer, - the actual native version of the font will be employed by the Sketch, improving - drawing quality and performance. With the ``P2D`` and ``P3D`` renderers, the + `P2D` and `P3D` renderers, the function sets the project to render the font as a + series of small textures. For instance, when using the default renderer, the + actual native version of the font will be employed by the Sketch, improving + drawing quality and performance. With the `P2D` and `P3D` renderers, the bitmapped version will be used to improve speed and appearance, but the results are poor when exporting if the Sketch does not include the .otf or .ttf file, and the requested font is not available on the machine running the Sketch. @@ -5151,24 +5137,24 @@ def create_font(*args): Dynamically converts a font to the format used by py5 from a .ttf or .otf file inside the Sketch's "data" folder or a font that's installed elsewhere on the computer. If you want to use a font installed on your computer, use the - ``Py5Font.list()`` method to first determine the names for the fonts recognized - by the computer and are compatible with this function. Not all fonts can be used + `Py5Font.list()` method to first determine the names for the fonts recognized by + the computer and are compatible with this function. Not all fonts can be used and some might work with one operating system and not others. When sharing a Sketch with other people or posting it on the web, you may need to include a .ttf or .otf version of your font in the data directory of the Sketch because other people might not have the font installed on their computer. Only fonts that can legally be distributed should be included with a Sketch. - The ``size`` parameter states the font size you want to generate. The ``smooth`` - parameter specifies if the font should be antialiased or not. The ``charset`` + The `size` parameter states the font size you want to generate. The `smooth` + parameter specifies if the font should be antialiased or not. The `charset` parameter is an array of chars that specifies the characters to generate. This function allows py5 to work with the font natively in the default renderer, so the letters are defined by vector geometry and are rendered quickly. In the - ``P2D`` and ``P3D`` renderers, the function sets the project to render the font - as a series of small textures. For instance, when using the default renderer, - the actual native version of the font will be employed by the Sketch, improving - drawing quality and performance. With the ``P2D`` and ``P3D`` renderers, the + `P2D` and `P3D` renderers, the function sets the project to render the font as a + series of small textures. For instance, when using the default renderer, the + actual native version of the font will be employed by the Sketch, improving + drawing quality and performance. With the `P2D` and `P3D` renderers, the bitmapped version will be used to improve speed and appearance, but the results are poor when exporting if the Sketch does not include the .otf or .ttf file, and the requested font is not available on the machine running the Sketch. @@ -5178,7 +5164,7 @@ def create_font(*args): @overload def create_graphics(w: int, h: int, /) -> Py5Graphics: - """Creates and returns a new ``Py5Graphics`` object. + """Creates and returns a new `Py5Graphics` object. Underlying Processing method: PApplet.createGraphics @@ -5209,47 +5195,45 @@ def create_graphics(w: int, h: int, /) -> Py5Graphics: Notes ----- - Creates and returns a new ``Py5Graphics`` object. Use this class if you need to + Creates and returns a new `Py5Graphics` object. Use this class if you need to draw into an off-screen graphics buffer. The first two parameters define the width and height in pixels. The third, optional parameter specifies the - renderer. It can be defined as ``P2D``, ``P3D``, ``PDF``, or ``SVG``. If the - third parameter isn't used, the default renderer is set. The ``PDF`` and ``SVG`` - renderers require the filename parameter. - - It's important to consider the renderer used with ``create_graphics()`` in - relation to the main renderer specified in ``size()``. For example, it's only - possible to use ``P2D`` or ``P3D`` with ``create_graphics()`` when one of them - is defined in ``size()``. ``P2D`` and ``P3D`` use OpenGL for drawing, and when - using an OpenGL renderer it's necessary for the main drawing surface to be - OpenGL-based. If ``P2D`` or ``P3D`` are used as the renderer in ``size()``, then - any of the options can be used with ``create_graphics()``. If the default - renderer is used in ``size()``, then only the default, ``PDF``, or ``SVG`` can - be used with ``create_graphics()``. + renderer. It can be defined as `P2D`, `P3D`, `PDF`, or `SVG`. If the third + parameter isn't used, the default renderer is set. The `PDF` and `SVG` renderers + require the filename parameter. + + It's important to consider the renderer used with `create_graphics()` in + relation to the main renderer specified in `size()`. For example, it's only + possible to use `P2D` or `P3D` with `create_graphics()` when one of them is + defined in `size()`. `P2D` and `P3D` use OpenGL for drawing, and when using an + OpenGL renderer it's necessary for the main drawing surface to be OpenGL-based. + If `P2D` or `P3D` are used as the renderer in `size()`, then any of the options + can be used with `create_graphics()`. If the default renderer is used in + `size()`, then only the default, `PDF`, or `SVG` can be used with + `create_graphics()`. It's important to run all drawing functions between the - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. As the exception to - this rule, ``smooth()`` should be run on the Py5Graphics object before - ``Py5Graphics.begin_draw()``. See the reference for ``smooth()`` for more - detail. + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. As the exception to + this rule, `smooth()` should be run on the Py5Graphics object before + `Py5Graphics.begin_draw()`. See the reference for `smooth()` for more detail. - The ``create_graphics()`` function should almost never be used inside ``draw()`` + The `create_graphics()` function should almost never be used inside `draw()` because of the memory and time needed to set up the graphics. One-time or - occasional use during ``draw()`` might be acceptable, but code that calls - ``create_graphics()`` at 60 frames per second might run out of memory or freeze + occasional use during `draw()` might be acceptable, but code that calls + `create_graphics()` at 60 frames per second might run out of memory or freeze your Sketch. Unlike the main drawing surface which is completely opaque, surfaces created - with ``create_graphics()`` can have transparency. This makes it possible to draw - into a graphics and maintain the alpha channel. By using ``save()`` to write a - ``PNG`` or ``TGA`` file, the transparency of the graphics object will be - honored. + with `create_graphics()` can have transparency. This makes it possible to draw + into a graphics and maintain the alpha channel. By using `save()` to write a + `PNG` or `TGA` file, the transparency of the graphics object will be honored. """ pass @overload def create_graphics(w: int, h: int, renderer: str, /) -> Py5Graphics: - """Creates and returns a new ``Py5Graphics`` object. + """Creates and returns a new `Py5Graphics` object. Underlying Processing method: PApplet.createGraphics @@ -5280,40 +5264,38 @@ def create_graphics(w: int, h: int, renderer: str, /) -> Py5Graphics: Notes ----- - Creates and returns a new ``Py5Graphics`` object. Use this class if you need to + Creates and returns a new `Py5Graphics` object. Use this class if you need to draw into an off-screen graphics buffer. The first two parameters define the width and height in pixels. The third, optional parameter specifies the - renderer. It can be defined as ``P2D``, ``P3D``, ``PDF``, or ``SVG``. If the - third parameter isn't used, the default renderer is set. The ``PDF`` and ``SVG`` - renderers require the filename parameter. - - It's important to consider the renderer used with ``create_graphics()`` in - relation to the main renderer specified in ``size()``. For example, it's only - possible to use ``P2D`` or ``P3D`` with ``create_graphics()`` when one of them - is defined in ``size()``. ``P2D`` and ``P3D`` use OpenGL for drawing, and when - using an OpenGL renderer it's necessary for the main drawing surface to be - OpenGL-based. If ``P2D`` or ``P3D`` are used as the renderer in ``size()``, then - any of the options can be used with ``create_graphics()``. If the default - renderer is used in ``size()``, then only the default, ``PDF``, or ``SVG`` can - be used with ``create_graphics()``. + renderer. It can be defined as `P2D`, `P3D`, `PDF`, or `SVG`. If the third + parameter isn't used, the default renderer is set. The `PDF` and `SVG` renderers + require the filename parameter. + + It's important to consider the renderer used with `create_graphics()` in + relation to the main renderer specified in `size()`. For example, it's only + possible to use `P2D` or `P3D` with `create_graphics()` when one of them is + defined in `size()`. `P2D` and `P3D` use OpenGL for drawing, and when using an + OpenGL renderer it's necessary for the main drawing surface to be OpenGL-based. + If `P2D` or `P3D` are used as the renderer in `size()`, then any of the options + can be used with `create_graphics()`. If the default renderer is used in + `size()`, then only the default, `PDF`, or `SVG` can be used with + `create_graphics()`. It's important to run all drawing functions between the - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. As the exception to - this rule, ``smooth()`` should be run on the Py5Graphics object before - ``Py5Graphics.begin_draw()``. See the reference for ``smooth()`` for more - detail. + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. As the exception to + this rule, `smooth()` should be run on the Py5Graphics object before + `Py5Graphics.begin_draw()`. See the reference for `smooth()` for more detail. - The ``create_graphics()`` function should almost never be used inside ``draw()`` + The `create_graphics()` function should almost never be used inside `draw()` because of the memory and time needed to set up the graphics. One-time or - occasional use during ``draw()`` might be acceptable, but code that calls - ``create_graphics()`` at 60 frames per second might run out of memory or freeze + occasional use during `draw()` might be acceptable, but code that calls + `create_graphics()` at 60 frames per second might run out of memory or freeze your Sketch. Unlike the main drawing surface which is completely opaque, surfaces created - with ``create_graphics()`` can have transparency. This makes it possible to draw - into a graphics and maintain the alpha channel. By using ``save()`` to write a - ``PNG`` or ``TGA`` file, the transparency of the graphics object will be - honored. + with `create_graphics()` can have transparency. This makes it possible to draw + into a graphics and maintain the alpha channel. By using `save()` to write a + `PNG` or `TGA` file, the transparency of the graphics object will be honored. """ pass @@ -5321,7 +5303,7 @@ def create_graphics(w: int, h: int, renderer: str, /) -> Py5Graphics: @overload def create_graphics(w: int, h: int, renderer: str, path: str, /) -> Py5Graphics: - """Creates and returns a new ``Py5Graphics`` object. + """Creates and returns a new `Py5Graphics` object. Underlying Processing method: PApplet.createGraphics @@ -5352,46 +5334,44 @@ def create_graphics(w: int, h: int, renderer: str, Notes ----- - Creates and returns a new ``Py5Graphics`` object. Use this class if you need to + Creates and returns a new `Py5Graphics` object. Use this class if you need to draw into an off-screen graphics buffer. The first two parameters define the width and height in pixels. The third, optional parameter specifies the - renderer. It can be defined as ``P2D``, ``P3D``, ``PDF``, or ``SVG``. If the - third parameter isn't used, the default renderer is set. The ``PDF`` and ``SVG`` - renderers require the filename parameter. - - It's important to consider the renderer used with ``create_graphics()`` in - relation to the main renderer specified in ``size()``. For example, it's only - possible to use ``P2D`` or ``P3D`` with ``create_graphics()`` when one of them - is defined in ``size()``. ``P2D`` and ``P3D`` use OpenGL for drawing, and when - using an OpenGL renderer it's necessary for the main drawing surface to be - OpenGL-based. If ``P2D`` or ``P3D`` are used as the renderer in ``size()``, then - any of the options can be used with ``create_graphics()``. If the default - renderer is used in ``size()``, then only the default, ``PDF``, or ``SVG`` can - be used with ``create_graphics()``. + renderer. It can be defined as `P2D`, `P3D`, `PDF`, or `SVG`. If the third + parameter isn't used, the default renderer is set. The `PDF` and `SVG` renderers + require the filename parameter. + + It's important to consider the renderer used with `create_graphics()` in + relation to the main renderer specified in `size()`. For example, it's only + possible to use `P2D` or `P3D` with `create_graphics()` when one of them is + defined in `size()`. `P2D` and `P3D` use OpenGL for drawing, and when using an + OpenGL renderer it's necessary for the main drawing surface to be OpenGL-based. + If `P2D` or `P3D` are used as the renderer in `size()`, then any of the options + can be used with `create_graphics()`. If the default renderer is used in + `size()`, then only the default, `PDF`, or `SVG` can be used with + `create_graphics()`. It's important to run all drawing functions between the - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. As the exception to - this rule, ``smooth()`` should be run on the Py5Graphics object before - ``Py5Graphics.begin_draw()``. See the reference for ``smooth()`` for more - detail. + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. As the exception to + this rule, `smooth()` should be run on the Py5Graphics object before + `Py5Graphics.begin_draw()`. See the reference for `smooth()` for more detail. - The ``create_graphics()`` function should almost never be used inside ``draw()`` + The `create_graphics()` function should almost never be used inside `draw()` because of the memory and time needed to set up the graphics. One-time or - occasional use during ``draw()`` might be acceptable, but code that calls - ``create_graphics()`` at 60 frames per second might run out of memory or freeze + occasional use during `draw()` might be acceptable, but code that calls + `create_graphics()` at 60 frames per second might run out of memory or freeze your Sketch. Unlike the main drawing surface which is completely opaque, surfaces created - with ``create_graphics()`` can have transparency. This makes it possible to draw - into a graphics and maintain the alpha channel. By using ``save()`` to write a - ``PNG`` or ``TGA`` file, the transparency of the graphics object will be - honored. + with `create_graphics()` can have transparency. This makes it possible to draw + into a graphics and maintain the alpha channel. By using `save()` to write a + `PNG` or `TGA` file, the transparency of the graphics object will be honored. """ pass def create_graphics(*args): - """Creates and returns a new ``Py5Graphics`` object. + """Creates and returns a new `Py5Graphics` object. Underlying Processing method: PApplet.createGraphics @@ -5422,40 +5402,38 @@ def create_graphics(*args): Notes ----- - Creates and returns a new ``Py5Graphics`` object. Use this class if you need to + Creates and returns a new `Py5Graphics` object. Use this class if you need to draw into an off-screen graphics buffer. The first two parameters define the width and height in pixels. The third, optional parameter specifies the - renderer. It can be defined as ``P2D``, ``P3D``, ``PDF``, or ``SVG``. If the - third parameter isn't used, the default renderer is set. The ``PDF`` and ``SVG`` - renderers require the filename parameter. - - It's important to consider the renderer used with ``create_graphics()`` in - relation to the main renderer specified in ``size()``. For example, it's only - possible to use ``P2D`` or ``P3D`` with ``create_graphics()`` when one of them - is defined in ``size()``. ``P2D`` and ``P3D`` use OpenGL for drawing, and when - using an OpenGL renderer it's necessary for the main drawing surface to be - OpenGL-based. If ``P2D`` or ``P3D`` are used as the renderer in ``size()``, then - any of the options can be used with ``create_graphics()``. If the default - renderer is used in ``size()``, then only the default, ``PDF``, or ``SVG`` can - be used with ``create_graphics()``. + renderer. It can be defined as `P2D`, `P3D`, `PDF`, or `SVG`. If the third + parameter isn't used, the default renderer is set. The `PDF` and `SVG` renderers + require the filename parameter. + + It's important to consider the renderer used with `create_graphics()` in + relation to the main renderer specified in `size()`. For example, it's only + possible to use `P2D` or `P3D` with `create_graphics()` when one of them is + defined in `size()`. `P2D` and `P3D` use OpenGL for drawing, and when using an + OpenGL renderer it's necessary for the main drawing surface to be OpenGL-based. + If `P2D` or `P3D` are used as the renderer in `size()`, then any of the options + can be used with `create_graphics()`. If the default renderer is used in + `size()`, then only the default, `PDF`, or `SVG` can be used with + `create_graphics()`. It's important to run all drawing functions between the - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. As the exception to - this rule, ``smooth()`` should be run on the Py5Graphics object before - ``Py5Graphics.begin_draw()``. See the reference for ``smooth()`` for more - detail. + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. As the exception to + this rule, `smooth()` should be run on the Py5Graphics object before + `Py5Graphics.begin_draw()`. See the reference for `smooth()` for more detail. - The ``create_graphics()`` function should almost never be used inside ``draw()`` + The `create_graphics()` function should almost never be used inside `draw()` because of the memory and time needed to set up the graphics. One-time or - occasional use during ``draw()`` might be acceptable, but code that calls - ``create_graphics()`` at 60 frames per second might run out of memory or freeze + occasional use during `draw()` might be acceptable, but code that calls + `create_graphics()` at 60 frames per second might run out of memory or freeze your Sketch. Unlike the main drawing surface which is completely opaque, surfaces created - with ``create_graphics()`` can have transparency. This makes it possible to draw - into a graphics and maintain the alpha channel. By using ``save()`` to write a - ``PNG`` or ``TGA`` file, the transparency of the graphics object will be - honored. + with `create_graphics()` can have transparency. This makes it possible to draw + into a graphics and maintain the alpha channel. By using `save()` to write a + `PNG` or `TGA` file, the transparency of the graphics object will be honored. """ return _py5sketch.create_graphics(*args) @@ -5481,22 +5459,22 @@ def create_image(w: int, h: int, format: int, /) -> Py5Image: ----- Creates a new Py5Image (the datatype for storing images). This provides a fresh - buffer of pixels to play with. Set the size of the buffer with the ``w`` and - ``h`` parameters. The ``format`` parameter defines how the pixels are stored. - See the ``Py5Image`` reference for more information. + buffer of pixels to play with. Set the size of the buffer with the `w` and `h` + parameters. The `format` parameter defines how the pixels are stored. See the + `Py5Image` reference for more information. Be sure to include all three parameters, specifying only the width and height (but no format) will produce a strange error. - Advanced users please note that ``create_image()`` should be used instead of the - syntax ``Py5Image()``. + Advanced users please note that `create_image()` should be used instead of the + syntax `Py5Image()`. """ return _py5sketch.create_image(w, h, format) @overload def create_shape() -> Py5Shape: - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PApplet.createShape @@ -5524,37 +5502,36 @@ def create_shape() -> Py5Shape: Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``shape()`` function. The basic way to use the + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `shape()` function. The basic way to use the function defines new primitive shapes. One of the following parameters are used - as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, ``TRIANGLE``, - ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for each of these - different shapes are the same as their corresponding functions: ``ellipse()``, - ``rect()``, ``arc()``, ``triangle()``, ``sphere()``, ``box()``, ``quad()``, and - ``line()``. The first example clarifies how this works. - - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``begin_shape()`` and ``end_shape()`` - methods. See the second example for specifics, and the reference for - ``begin_shape()`` for all of its options. - - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. See the fourth example to see how it - works. - - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, `BOX`, + `QUAD`, or `LINE`. The parameters for each of these different shapes are the + same as their corresponding functions: `ellipse()`, `rect()`, `arc()`, + `triangle()`, `sphere()`, `box()`, `quad()`, and `line()`. The first example + clarifies how this works. + + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `begin_shape()` and `end_shape()` methods. See + the second example for specifics, and the reference for `begin_shape()` for all + of its options. + + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. See the fourth example to see how it works. + + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. """ pass @overload def create_shape(type: int, /) -> Py5Shape: - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PApplet.createShape @@ -5582,37 +5559,36 @@ def create_shape(type: int, /) -> Py5Shape: Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``shape()`` function. The basic way to use the + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `shape()` function. The basic way to use the function defines new primitive shapes. One of the following parameters are used - as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, ``TRIANGLE``, - ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for each of these - different shapes are the same as their corresponding functions: ``ellipse()``, - ``rect()``, ``arc()``, ``triangle()``, ``sphere()``, ``box()``, ``quad()``, and - ``line()``. The first example clarifies how this works. - - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``begin_shape()`` and ``end_shape()`` - methods. See the second example for specifics, and the reference for - ``begin_shape()`` for all of its options. - - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. See the fourth example to see how it - works. - - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, `BOX`, + `QUAD`, or `LINE`. The parameters for each of these different shapes are the + same as their corresponding functions: `ellipse()`, `rect()`, `arc()`, + `triangle()`, `sphere()`, `box()`, `quad()`, and `line()`. The first example + clarifies how this works. + + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `begin_shape()` and `end_shape()` methods. See + the second example for specifics, and the reference for `begin_shape()` for all + of its options. + + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. See the fourth example to see how it works. + + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. """ pass @overload def create_shape(kind: int, /, *p: float) -> Py5Shape: - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PApplet.createShape @@ -5640,36 +5616,35 @@ def create_shape(kind: int, /, *p: float) -> Py5Shape: Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``shape()`` function. The basic way to use the + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `shape()` function. The basic way to use the function defines new primitive shapes. One of the following parameters are used - as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, ``TRIANGLE``, - ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for each of these - different shapes are the same as their corresponding functions: ``ellipse()``, - ``rect()``, ``arc()``, ``triangle()``, ``sphere()``, ``box()``, ``quad()``, and - ``line()``. The first example clarifies how this works. - - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``begin_shape()`` and ``end_shape()`` - methods. See the second example for specifics, and the reference for - ``begin_shape()`` for all of its options. - - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. See the fourth example to see how it - works. - - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, `BOX`, + `QUAD`, or `LINE`. The parameters for each of these different shapes are the + same as their corresponding functions: `ellipse()`, `rect()`, `arc()`, + `triangle()`, `sphere()`, `box()`, `quad()`, and `line()`. The first example + clarifies how this works. + + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `begin_shape()` and `end_shape()` methods. See + the second example for specifics, and the reference for `begin_shape()` for all + of its options. + + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. See the fourth example to see how it works. + + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. """ pass def create_shape(*args): - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PApplet.createShape @@ -5697,30 +5672,29 @@ def create_shape(*args): Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``shape()`` function. The basic way to use the + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `shape()` function. The basic way to use the function defines new primitive shapes. One of the following parameters are used - as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, ``TRIANGLE``, - ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for each of these - different shapes are the same as their corresponding functions: ``ellipse()``, - ``rect()``, ``arc()``, ``triangle()``, ``sphere()``, ``box()``, ``quad()``, and - ``line()``. The first example clarifies how this works. - - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``begin_shape()`` and ``end_shape()`` - methods. See the second example for specifics, and the reference for - ``begin_shape()`` for all of its options. - - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. See the fourth example to see how it - works. - - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, `BOX`, + `QUAD`, or `LINE`. The parameters for each of these different shapes are the + same as their corresponding functions: `ellipse()`, `rect()`, `arc()`, + `triangle()`, `sphere()`, `box()`, `quad()`, and `line()`. The first example + clarifies how this works. + + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `begin_shape()` and `end_shape()` methods. See + the second example for specifics, and the reference for `begin_shape()` for all + of its options. + + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. See the fourth example to see how it works. + + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. """ return _py5sketch.create_shape(*args) @@ -5762,15 +5736,15 @@ def cursor() -> None: Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended - size is 16x16 or 32x32 pixels. The values for parameters ``x`` and ``y`` must be + size is 16x16 or 32x32 pixels. The values for parameters `x` and `y` must be less than the dimensions of the image. Setting or hiding the cursor does not generally work with "Present" mode (when running full-screen). - With the ``P2D`` and ``P3D`` renderers, a generic set of cursors are used - because the OpenGL renderer doesn't have access to the default cursor images for - each platform (Processing Issue 3791). + With the `P2D` and `P3D` renderers, a generic set of cursors are used because + the OpenGL renderer doesn't have access to the default cursor images for each + platform (Processing Issue 3791). """ pass @@ -5812,15 +5786,15 @@ def cursor(kind: int, /) -> None: Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended - size is 16x16 or 32x32 pixels. The values for parameters ``x`` and ``y`` must be + size is 16x16 or 32x32 pixels. The values for parameters `x` and `y` must be less than the dimensions of the image. Setting or hiding the cursor does not generally work with "Present" mode (when running full-screen). - With the ``P2D`` and ``P3D`` renderers, a generic set of cursors are used - because the OpenGL renderer doesn't have access to the default cursor images for - each platform (Processing Issue 3791). + With the `P2D` and `P3D` renderers, a generic set of cursors are used because + the OpenGL renderer doesn't have access to the default cursor images for each + platform (Processing Issue 3791). """ pass @@ -5862,15 +5836,15 @@ def cursor(img: Py5Image, /) -> None: Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended - size is 16x16 or 32x32 pixels. The values for parameters ``x`` and ``y`` must be + size is 16x16 or 32x32 pixels. The values for parameters `x` and `y` must be less than the dimensions of the image. Setting or hiding the cursor does not generally work with "Present" mode (when running full-screen). - With the ``P2D`` and ``P3D`` renderers, a generic set of cursors are used - because the OpenGL renderer doesn't have access to the default cursor images for - each platform (Processing Issue 3791). + With the `P2D` and `P3D` renderers, a generic set of cursors are used because + the OpenGL renderer doesn't have access to the default cursor images for each + platform (Processing Issue 3791). """ pass @@ -5912,15 +5886,15 @@ def cursor(img: Py5Image, x: int, y: int, /) -> None: Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended - size is 16x16 or 32x32 pixels. The values for parameters ``x`` and ``y`` must be + size is 16x16 or 32x32 pixels. The values for parameters `x` and `y` must be less than the dimensions of the image. Setting or hiding the cursor does not generally work with "Present" mode (when running full-screen). - With the ``P2D`` and ``P3D`` renderers, a generic set of cursors are used - because the OpenGL renderer doesn't have access to the default cursor images for - each platform (Processing Issue 3791). + With the `P2D` and `P3D` renderers, a generic set of cursors are used because + the OpenGL renderer doesn't have access to the default cursor images for each + platform (Processing Issue 3791). """ pass @@ -5961,15 +5935,15 @@ def cursor(*args): Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended - size is 16x16 or 32x32 pixels. The values for parameters ``x`` and ``y`` must be + size is 16x16 or 32x32 pixels. The values for parameters `x` and `y` must be less than the dimensions of the image. Setting or hiding the cursor does not generally work with "Present" mode (when running full-screen). - With the ``P2D`` and ``P3D`` renderers, a generic set of cursors are used - because the OpenGL renderer doesn't have access to the default cursor images for - each platform (Processing Issue 3791). + With the `P2D` and `P3D` renderers, a generic set of cursors are used because + the OpenGL renderer doesn't have access to the default cursor images for each + platform (Processing Issue 3791). """ return _py5sketch.cursor(*args) @@ -6034,11 +6008,11 @@ def curve(x1: float, y1: float, x2: float, y2: float, x3: float, Draws a curved line on the screen. The first and second parameters specify the beginning control point and the last two parameters specify the ending control point. The middle parameters specify the start and stop of the curve. Longer - curves can be created by putting a series of ``curve()`` functions together or - using ``curve_vertex()``. An additional function called ``curve_tightness()`` - provides control for the visual quality of the curve. The ``curve()`` function - is an implementation of Catmull-Rom splines. Using the 3D version requires - rendering with ``P3D``. + curves can be created by putting a series of `curve()` functions together or + using `curve_vertex()`. An additional function called `curve_tightness()` + provides control for the visual quality of the curve. The `curve()` function is + an implementation of Catmull-Rom splines. Using the 3D version requires + rendering with `P3D`. """ pass @@ -6103,11 +6077,11 @@ def curve(x1: float, y1: float, z1: float, x2: float, y2: float, z2: float, Draws a curved line on the screen. The first and second parameters specify the beginning control point and the last two parameters specify the ending control point. The middle parameters specify the start and stop of the curve. Longer - curves can be created by putting a series of ``curve()`` functions together or - using ``curve_vertex()``. An additional function called ``curve_tightness()`` - provides control for the visual quality of the curve. The ``curve()`` function - is an implementation of Catmull-Rom splines. Using the 3D version requires - rendering with ``P3D``. + curves can be created by putting a series of `curve()` functions together or + using `curve_vertex()`. An additional function called `curve_tightness()` + provides control for the visual quality of the curve. The `curve()` function is + an implementation of Catmull-Rom splines. Using the 3D version requires + rendering with `P3D`. """ pass @@ -6170,11 +6144,11 @@ def curve(*args): Draws a curved line on the screen. The first and second parameters specify the beginning control point and the last two parameters specify the ending control point. The middle parameters specify the start and stop of the curve. Longer - curves can be created by putting a series of ``curve()`` functions together or - using ``curve_vertex()``. An additional function called ``curve_tightness()`` - provides control for the visual quality of the curve. The ``curve()`` function - is an implementation of Catmull-Rom splines. Using the 3D version requires - rendering with ``P3D``. + curves can be created by putting a series of `curve()` functions together or + using `curve_vertex()`. An additional function called `curve_tightness()` + provides control for the visual quality of the curve. The `curve()` function is + an implementation of Catmull-Rom splines. Using the 3D version requires + rendering with `P3D`. """ return _py5sketch.curve(*args) @@ -6194,14 +6168,14 @@ def curve_detail(detail: int, /) -> None: ----- Sets the resolution at which curves display. The default value is 20. This - function is only useful when using the ``P3D`` renderer as the default ``P2D`` + function is only useful when using the `P3D` renderer as the default `P2D` renderer does not use this information. """ return _py5sketch.curve_detail(detail) def curve_point(a: float, b: float, c: float, d: float, t: float, /) -> float: - """Evaluates the curve at point ``t`` for points ``a``, ``b``, ``c``, ``d``. + """Evaluates the curve at point `t` for points `a`, `b`, `c`, `d`. Underlying Processing method: PApplet.curvePoint @@ -6226,12 +6200,11 @@ def curve_point(a: float, b: float, c: float, d: float, t: float, /) -> float: Notes ----- - Evaluates the curve at point ``t`` for points ``a``, ``b``, ``c``, ``d``. The - parameter ``t`` may range from 0 (the start of the curve) and 1 (the end of the - curve). ``a`` and ``d`` are the control points, and ``b`` and ``c`` are points - on the curve. As seen in the example, this can be used once with the ``x`` - coordinates and a second time with the ``y`` coordinates to get the location of - a curve at ``t``. + Evaluates the curve at point `t` for points `a`, `b`, `c`, `d`. The parameter + `t` may range from 0 (the start of the curve) and 1 (the end of the curve). `a` + and `d` are the control points, and `b` and `c` are points on the curve. As seen + in the example, this can be used once with the `x` coordinates and a second time + with the `y` coordinates to get the location of a curve at `t`. """ return _py5sketch.curve_point(a, b, c, d, t) @@ -6270,7 +6243,7 @@ def curve_tangent(a: float, b: float, c: float, def curve_tightness(tightness: float, /) -> None: - """Modifies the quality of forms created with ``curve()`` and ``curve_vertex()``. + """Modifies the quality of forms created with `curve()` and `curve_vertex()`. Underlying Processing method: PApplet.curveTightness @@ -6283,13 +6256,13 @@ def curve_tightness(tightness: float, /) -> None: Notes ----- - Modifies the quality of forms created with ``curve()`` and ``curve_vertex()``. - The parameter ``tightness`` determines how the curve fits to the vertex points. - The value 0.0 is the default value for ``tightness`` (this value defines the - curves to be Catmull-Rom splines) and the value 1.0 connects all the points with - straight lines. Values within the range -5.0 and 5.0 will deform the curves but - will leave them recognizable and as values increase in magnitude, they will - continue to deform. + Modifies the quality of forms created with `curve()` and `curve_vertex()`. The + parameter `tightness` determines how the curve fits to the vertex points. The + value 0.0 is the default value for `tightness` (this value defines the curves to + be Catmull-Rom splines) and the value 1.0 connects all the points with straight + lines. Values within the range -5.0 and 5.0 will deform the curves but will + leave them recognizable and as values increase in magnitude, they will continue + to deform. """ return _py5sketch.curve_tightness(tightness) @@ -6324,14 +6297,14 @@ def curve_vertex(x: float, y: float, /) -> None: ----- Specifies vertex coordinates for curves. This method may only be used between - ``begin_shape()`` and ``end_shape()`` and only when there is no ``MODE`` - parameter specified to ``begin_shape()``. The first and last points in a series - of ``curve_vertex()`` lines will be used to guide the beginning and end of the - curve. A minimum of four points is required to draw a tiny curve between the - second and third points. Adding a fifth point with ``curve_vertex()`` will draw - the curve between the second, third, and fourth points. The ``curve_vertex()`` - method is an implementation of Catmull-Rom splines. Using the 3D version - requires rendering with ``P3D``. + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. The first and last points in a series of + `curve_vertex()` lines will be used to guide the beginning and end of the curve. + A minimum of four points is required to draw a tiny curve between the second and + third points. Adding a fifth point with `curve_vertex()` will draw the curve + between the second, third, and fourth points. The `curve_vertex()` method is an + implementation of Catmull-Rom splines. Using the 3D version requires rendering + with `P3D`. """ pass @@ -6366,14 +6339,14 @@ def curve_vertex(x: float, y: float, z: float, /) -> None: ----- Specifies vertex coordinates for curves. This method may only be used between - ``begin_shape()`` and ``end_shape()`` and only when there is no ``MODE`` - parameter specified to ``begin_shape()``. The first and last points in a series - of ``curve_vertex()`` lines will be used to guide the beginning and end of the - curve. A minimum of four points is required to draw a tiny curve between the - second and third points. Adding a fifth point with ``curve_vertex()`` will draw - the curve between the second, third, and fourth points. The ``curve_vertex()`` - method is an implementation of Catmull-Rom splines. Using the 3D version - requires rendering with ``P3D``. + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. The first and last points in a series of + `curve_vertex()` lines will be used to guide the beginning and end of the curve. + A minimum of four points is required to draw a tiny curve between the second and + third points. Adding a fifth point with `curve_vertex()` will draw the curve + between the second, third, and fourth points. The `curve_vertex()` method is an + implementation of Catmull-Rom splines. Using the 3D version requires rendering + with `P3D`. """ pass @@ -6407,14 +6380,14 @@ def curve_vertex(*args): ----- Specifies vertex coordinates for curves. This method may only be used between - ``begin_shape()`` and ``end_shape()`` and only when there is no ``MODE`` - parameter specified to ``begin_shape()``. The first and last points in a series - of ``curve_vertex()`` lines will be used to guide the beginning and end of the - curve. A minimum of four points is required to draw a tiny curve between the - second and third points. Adding a fifth point with ``curve_vertex()`` will draw - the curve between the second, third, and fourth points. The ``curve_vertex()`` - method is an implementation of Catmull-Rom splines. Using the 3D version - requires rendering with ``P3D``. + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. The first and last points in a series of + `curve_vertex()` lines will be used to guide the beginning and end of the curve. + A minimum of four points is required to draw a tiny curve between the second and + third points. Adding a fifth point with `curve_vertex()` will draw the curve + between the second, third, and fourth points. The `curve_vertex()` method is an + implementation of Catmull-Rom splines. Using the 3D version requires rendering + with `P3D`. """ return _py5sketch.curve_vertex(*args) @@ -6434,13 +6407,12 @@ def curve_vertices(coordinates: npt.NDArray[np.floating], /) -> None: ----- Create a collection of curve vertices. The purpose of this method is to provide - an alternative to repeatedly calling ``curve_vertex()`` in a loop. For a large - number of curve vertices, the performance of ``curve_vertices()`` will be much + an alternative to repeatedly calling `curve_vertex()` in a loop. For a large + number of curve vertices, the performance of `curve_vertices()` will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each - curve vertex. There should be two or three columns for 2D or 3D points, - respectively. + The `coordinates` parameter should be a numpy array with one row for each curve + vertex. There should be two or three columns for 2D or 3D points, respectively. """ return _py5sketch.curve_vertices(coordinates) @@ -6453,7 +6425,7 @@ def day() -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``day()`` function returns + Py5 communicates with the clock on your computer. The `day()` function returns the current day as a value from 1 - 31. """ return Sketch.day() @@ -6492,13 +6464,13 @@ def directional_light(v1: float, v2: float, v3: float, Adds a directional light. Directional light comes from one direction: it is stronger when hitting a surface squarely, and weaker if it hits at a gentle angle. After hitting a surface, directional light scatters in all directions. - Lights need to be included in the ``draw()`` to remain persistent in a looping - program. Placing them in the ``setup()`` of a looping program will cause them to - only have an effect the first time through the loop. The ``v1``, ``v2``, and - ``v3`` parameters are interpreted as either ``RGB`` or ``HSB`` values, depending - on the current color mode. The ``nx``, ``ny``, and ``nz`` parameters specify the - direction the light is facing. For example, setting ``ny`` to -1 will cause the - geometry to be lit from below (since the light would be facing directly upward). + Lights need to be included in the `draw()` to remain persistent in a looping + program. Placing them in the `setup()` of a looping program will cause them to + only have an effect the first time through the loop. The `v1`, `v2`, and `v3` + parameters are interpreted as either `RGB` or `HSB` values, depending on the + current color mode. The `nx`, `ny`, and `nz` parameters specify the direction + the light is facing. For example, setting `ny` to -1 will cause the geometry to + be lit from below (since the light would be facing directly upward). """ return _py5sketch.directional_light(v1, v2, v3, nx, ny, nz) @@ -6627,14 +6599,14 @@ def ellipse(a: float, b: float, c: float, d: float, /) -> None: Draws an ellipse (oval) to the screen. An ellipse with equal width and height is a circle. By default, the first two parameters set the location, and the third and fourth parameters set the shape's width and height. The origin may be - changed with the ``ellipse_mode()`` function. + changed with the `ellipse_mode()` function. """ return _py5sketch.ellipse(a, b, c, d) def ellipse_mode(mode: int, /) -> None: """Modifies the location from which ellipses are drawn by changing the way in which - parameters given to ``ellipse()`` are intepreted. + parameters given to `ellipse()` are intepreted. Underlying Processing method: PApplet.ellipseMode @@ -6648,22 +6620,22 @@ def ellipse_mode(mode: int, /) -> None: ----- Modifies the location from which ellipses are drawn by changing the way in which - parameters given to ``ellipse()`` are intepreted. + parameters given to `ellipse()` are intepreted. - The default mode is ``ellipse_mode(CENTER)``, which interprets the first two - parameters of ``ellipse()`` as the shape's center point, while the third and + The default mode is `ellipse_mode(CENTER)`, which interprets the first two + parameters of `ellipse()` as the shape's center point, while the third and fourth parameters are its width and height. - ``ellipse_mode(RADIUS)`` also uses the first two parameters of ``ellipse()`` as - the shape's center point, but uses the third and fourth parameters to specify - half of the shapes's width and height. + `ellipse_mode(RADIUS)` also uses the first two parameters of `ellipse()` as the + shape's center point, but uses the third and fourth parameters to specify half + of the shapes's width and height. - ``ellipse_mode(CORNER)`` interprets the first two parameters of ``ellipse()`` as - the upper-left corner of the shape, while the third and fourth parameters are - its width and height. + `ellipse_mode(CORNER)` interprets the first two parameters of `ellipse()` as the + upper-left corner of the shape, while the third and fourth parameters are its + width and height. - ``ellipse_mode(CORNERS)`` interprets the first two parameters of ``ellipse()`` - as the location of one corner of the ellipse's bounding box, and the third and + `ellipse_mode(CORNERS)` interprets the first two parameters of `ellipse()` as + the location of one corner of the ellipse's bounding box, and the third and fourth parameters as the location of the opposite corner. The parameter must be written in ALL CAPS because Python is a case-sensitive @@ -6710,8 +6682,8 @@ def emissive(gray: float, /) -> None: ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``ambient()``, ``specular()``, and - ``shininess()`` to set the material properties of shapes. + screen. Use in combination with `ambient()`, `specular()`, and `shininess()` to + set the material properties of shapes. """ pass @@ -6754,8 +6726,8 @@ def emissive(v1: float, v2: float, v3: float, /) -> None: ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``ambient()``, ``specular()``, and - ``shininess()`` to set the material properties of shapes. + screen. Use in combination with `ambient()`, `specular()`, and `shininess()` to + set the material properties of shapes. """ pass @@ -6798,8 +6770,8 @@ def emissive(rgb: int, /) -> None: ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``ambient()``, ``specular()``, and - ``shininess()`` to set the material properties of shapes. + screen. Use in combination with `ambient()`, `specular()`, and `shininess()` to + set the material properties of shapes. """ pass @@ -6841,84 +6813,83 @@ def emissive(*args): ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``ambient()``, ``specular()``, and - ``shininess()`` to set the material properties of shapes. + screen. Use in combination with `ambient()`, `specular()`, and `shininess()` to + set the material properties of shapes. """ return _py5sketch.emissive(*args) def end_camera() -> None: - """The ``begin_camera()`` and ``end_camera()`` methods enable advanced - customization of the camera space. + """The `begin_camera()` and `end_camera()` methods enable advanced customization of + the camera space. Underlying Processing method: PApplet.endCamera Notes ----- - The ``begin_camera()`` and ``end_camera()`` methods enable advanced - customization of the camera space. Please see the reference for - ``begin_camera()`` for a description of how the methods are used. + The `begin_camera()` and `end_camera()` methods enable advanced customization of + the camera space. Please see the reference for `begin_camera()` for a + description of how the methods are used. """ return _py5sketch.end_camera() def end_contour() -> None: - """Use the ``begin_contour()`` and ``end_contour()`` methods to create negative - shapes within shapes such as the center of the letter 'O'. + """Use the `begin_contour()` and `end_contour()` methods to create negative shapes + within shapes such as the center of the letter 'O'. Underlying Processing method: PApplet.endContour Notes ----- - Use the ``begin_contour()`` and ``end_contour()`` methods to create negative - shapes within shapes such as the center of the letter 'O'. The - ``begin_contour()`` method begins recording vertices for the shape and - ``end_contour()`` stops recording. The vertices that define a negative shape - must "wind" in the opposite direction from the exterior shape. First draw - vertices for the exterior shape in clockwise order, then for internal shapes, - draw vertices counterclockwise. + Use the `begin_contour()` and `end_contour()` methods to create negative shapes + within shapes such as the center of the letter 'O'. The `begin_contour()` method + begins recording vertices for the shape and `end_contour()` stops recording. The + vertices that define a negative shape must "wind" in the opposite direction from + the exterior shape. First draw vertices for the exterior shape in clockwise + order, then for internal shapes, draw vertices counterclockwise. - These methods can only be used within a ``begin_shape()`` & ``end_shape()`` pair - and transformations such as ``translate()``, ``rotate()``, and ``scale()`` do - not work within a ``begin_contour()`` & ``end_contour()`` pair. It is also not - possible to use other shapes, such as ``ellipse()`` or ``rect()`` within. + These methods can only be used within a `begin_shape()` & `end_shape()` pair and + transformations such as `translate()`, `rotate()`, and `scale()` do not work + within a `begin_contour()` & `end_contour()` pair. It is also not possible to + use other shapes, such as `ellipse()` or `rect()` within. """ return _py5sketch.end_contour() def end_raw() -> None: - """Complement to ``begin_raw()``; they must always be used together. + """Complement to `begin_raw()`; they must always be used together. Underlying Processing method: PApplet.endRaw Notes ----- - Complement to ``begin_raw()``; they must always be used together. See the - ``begin_raw()`` reference for details. + Complement to `begin_raw()`; they must always be used together. See the + `begin_raw()` reference for details. """ return _py5sketch.end_raw() def end_record() -> None: - """Stops the recording process started by ``begin_record()`` and closes the file. + """Stops the recording process started by `begin_record()` and closes the file. Underlying Processing method: PApplet.endRecord Notes ----- - Stops the recording process started by ``begin_record()`` and closes the file. + Stops the recording process started by `begin_record()` and closes the file. """ return _py5sketch.end_record() @overload def end_shape() -> None: - """The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. + """The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. Underlying Processing method: PApplet.endShape @@ -6939,19 +6910,19 @@ def end_shape() -> None: Notes ----- - The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. When ``end_shape()`` is called, all of image - data defined since the previous call to ``begin_shape()`` is written into the - image buffer. The constant ``CLOSE`` as the value for the ``MODE`` parameter to - close the shape (to connect the beginning and the end). + The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. When `end_shape()` is called, all of image data + defined since the previous call to `begin_shape()` is written into the image + buffer. The constant `CLOSE` as the value for the `MODE` parameter to close the + shape (to connect the beginning and the end). """ pass @overload def end_shape(mode: int, /) -> None: - """The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. + """The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. Underlying Processing method: PApplet.endShape @@ -6972,18 +6943,18 @@ def end_shape(mode: int, /) -> None: Notes ----- - The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. When ``end_shape()`` is called, all of image - data defined since the previous call to ``begin_shape()`` is written into the - image buffer. The constant ``CLOSE`` as the value for the ``MODE`` parameter to - close the shape (to connect the beginning and the end). + The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. When `end_shape()` is called, all of image data + defined since the previous call to `begin_shape()` is written into the image + buffer. The constant `CLOSE` as the value for the `MODE` parameter to close the + shape (to connect the beginning and the end). """ pass def end_shape(*args): - """The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. + """The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. Underlying Processing method: PApplet.endShape @@ -7004,11 +6975,11 @@ def end_shape(*args): Notes ----- - The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. When ``end_shape()`` is called, all of image - data defined since the previous call to ``begin_shape()`` is written into the - image buffer. The constant ``CLOSE`` as the value for the ``MODE`` parameter to - close the shape (to connect the beginning and the end). + The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. When `end_shape()` is called, all of image data + defined since the previous call to `begin_shape()` is written into the image + buffer. The constant `CLOSE` as the value for the `MODE` parameter to close the + shape (to connect the beginning and the end). """ return _py5sketch.end_shape(*args) @@ -7021,17 +6992,17 @@ def exit_sketch() -> None: Notes ----- - Quits/stops/exits the program. Programs without a ``draw()`` function stop - automatically after the last line has run, but programs with ``draw()`` run - continuously until the program is manually stopped or ``exit_sketch()`` is run. + Quits/stops/exits the program. Programs without a `draw()` function stop + automatically after the last line has run, but programs with `draw()` run + continuously until the program is manually stopped or `exit_sketch()` is run. - Rather than terminating immediately, ``exit_sketch()`` will cause the Sketch to - exit after ``draw()`` has completed (or after ``setup()`` completes if called - during the ``setup()`` function). + Rather than terminating immediately, `exit_sketch()` will cause the Sketch to + exit after `draw()` has completed (or after `setup()` completes if called during + the `setup()` function). - For Python programmers, this is *not* the same as ``sys.exit()``. Further, - ``sys.exit()`` should not be used because closing out an application while - ``draw()`` is running may cause a crash (particularly with ``P3D``). + For Python programmers, this is *not* the same as `sys.exit()`. Further, + `sys.exit()` should not be used because closing out an application while + `draw()` is running may cause a crash (particularly with `P3D`). """ return _py5sketch.exit_sketch() @@ -7078,32 +7049,30 @@ def fill(gray: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -7150,32 +7119,30 @@ def fill(gray: float, alpha: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -7222,32 +7189,30 @@ def fill(v1: float, v2: float, v3: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -7294,32 +7259,30 @@ def fill(v1: float, v2: float, v3: float, alpha: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -7366,32 +7329,30 @@ def fill(rgb: int, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -7438,32 +7399,30 @@ def fill(rgb: int, alpha: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -7509,32 +7468,30 @@ def fill(*args): Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ return _py5sketch.fill(*args) @@ -7570,8 +7527,8 @@ def apply_filter(kind: int, /) -> None: ----- Filters the display window using a preset filter or with a custom shader. Using - a shader with ``apply_filter()`` is much faster than without. Shaders require - the ``P2D`` or ``P3D`` renderer in ``size()``. + a shader with `apply_filter()` is much faster than without. Shaders require the + `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -7625,8 +7582,8 @@ def apply_filter(kind: int, param: float, /) -> None: ----- Filters the display window using a preset filter or with a custom shader. Using - a shader with ``apply_filter()`` is much faster than without. Shaders require - the ``P2D`` or ``P3D`` renderer in ``size()``. + a shader with `apply_filter()` is much faster than without. Shaders require the + `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -7680,8 +7637,8 @@ def apply_filter(shader: Py5Shader, /) -> None: ----- Filters the display window using a preset filter or with a custom shader. Using - a shader with ``apply_filter()`` is much faster than without. Shaders require - the ``P2D`` or ``P3D`` renderer in ``size()``. + a shader with `apply_filter()` is much faster than without. Shaders require the + `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -7734,8 +7691,8 @@ def apply_filter(*args): ----- Filters the display window using a preset filter or with a custom shader. Using - a shader with ``apply_filter()`` is much faster than without. Shaders require - the ``P2D`` or ``P3D`` renderer in ``size()``. + a shader with `apply_filter()` is much faster than without. Shaders require the + `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -7788,10 +7745,10 @@ def frame_rate(fps: float, /) -> None: ----- Specifies the number of frames to be displayed every second. For example, the - function call ``frame_rate(30)`` will attempt to refresh 30 times a second. If - the processor is not fast enough to maintain the specified rate, the frame rate - will not be achieved. Setting the frame rate within ``setup()`` is recommended. - The default rate is 60 frames per second. + function call `frame_rate(30)` will attempt to refresh 30 times a second. If the + processor is not fast enough to maintain the specified rate, the frame rate will + not be achieved. Setting the frame rate within `setup()` is recommended. The + default rate is 60 frames per second. """ return _py5sketch.frame_rate(fps) @@ -7836,7 +7793,7 @@ def frustum(left: float, right: float, bottom: float, Setting the frustum has the effect of changing the *perspective* with which the scene is rendered. This can be achieved more simply in many cases by using - ``perspective()``. + `perspective()`. Note that the near value must be greater than zero (as the point of the frustum "pyramid" cannot converge "behind" the viewer). Similarly, the far value must @@ -7878,26 +7835,26 @@ def full_screen() -> None: ----- Open a Sketch using the full size of the computer's display. This is intended to - be called from the ``settings()`` function. The ``size()`` and ``full_screen()`` + be called from the `settings()` function. The `size()` and `full_screen()` functions cannot both be used in the same program. When programming in module mode and imported mode, py5 will allow calls to - ``full_screen()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``full_screen()``, or calls - to ``size()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. - - When ``full_screen()`` is used without a parameter on a computer with multiple + `full_screen()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `full_screen()`, or calls to + `size()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + When `full_screen()` is used without a parameter on a computer with multiple monitors, it will (probably) draw the Sketch to the primary display. When it is used with a single parameter, this number defines the screen to display to program on (e.g. 1, 2, 3...). When used with two parameters, the first defines - the renderer to use (e.g. P2D) and the second defines the screen. The ``SPAN`` + the renderer to use (e.g. P2D) and the second defines the screen. The `SPAN` parameter can be used in place of a screen number to draw the Sketch as a full- screen window across all of the attached displays if there are more than one. """ @@ -7933,26 +7890,26 @@ def full_screen(display: int, /) -> None: ----- Open a Sketch using the full size of the computer's display. This is intended to - be called from the ``settings()`` function. The ``size()`` and ``full_screen()`` + be called from the `settings()` function. The `size()` and `full_screen()` functions cannot both be used in the same program. When programming in module mode and imported mode, py5 will allow calls to - ``full_screen()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``full_screen()``, or calls - to ``size()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. - - When ``full_screen()`` is used without a parameter on a computer with multiple + `full_screen()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `full_screen()`, or calls to + `size()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + When `full_screen()` is used without a parameter on a computer with multiple monitors, it will (probably) draw the Sketch to the primary display. When it is used with a single parameter, this number defines the screen to display to program on (e.g. 1, 2, 3...). When used with two parameters, the first defines - the renderer to use (e.g. P2D) and the second defines the screen. The ``SPAN`` + the renderer to use (e.g. P2D) and the second defines the screen. The `SPAN` parameter can be used in place of a screen number to draw the Sketch as a full- screen window across all of the attached displays if there are more than one. """ @@ -7988,26 +7945,26 @@ def full_screen(renderer: str, /) -> None: ----- Open a Sketch using the full size of the computer's display. This is intended to - be called from the ``settings()`` function. The ``size()`` and ``full_screen()`` + be called from the `settings()` function. The `size()` and `full_screen()` functions cannot both be used in the same program. When programming in module mode and imported mode, py5 will allow calls to - ``full_screen()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``full_screen()``, or calls - to ``size()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. - - When ``full_screen()`` is used without a parameter on a computer with multiple + `full_screen()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `full_screen()`, or calls to + `size()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + When `full_screen()` is used without a parameter on a computer with multiple monitors, it will (probably) draw the Sketch to the primary display. When it is used with a single parameter, this number defines the screen to display to program on (e.g. 1, 2, 3...). When used with two parameters, the first defines - the renderer to use (e.g. P2D) and the second defines the screen. The ``SPAN`` + the renderer to use (e.g. P2D) and the second defines the screen. The `SPAN` parameter can be used in place of a screen number to draw the Sketch as a full- screen window across all of the attached displays if there are more than one. """ @@ -8043,26 +8000,26 @@ def full_screen(renderer: str, display: int, /) -> None: ----- Open a Sketch using the full size of the computer's display. This is intended to - be called from the ``settings()`` function. The ``size()`` and ``full_screen()`` + be called from the `settings()` function. The `size()` and `full_screen()` functions cannot both be used in the same program. When programming in module mode and imported mode, py5 will allow calls to - ``full_screen()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``full_screen()``, or calls - to ``size()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. - - When ``full_screen()`` is used without a parameter on a computer with multiple + `full_screen()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `full_screen()`, or calls to + `size()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + When `full_screen()` is used without a parameter on a computer with multiple monitors, it will (probably) draw the Sketch to the primary display. When it is used with a single parameter, this number defines the screen to display to program on (e.g. 1, 2, 3...). When used with two parameters, the first defines - the renderer to use (e.g. P2D) and the second defines the screen. The ``SPAN`` + the renderer to use (e.g. P2D) and the second defines the screen. The `SPAN` parameter can be used in place of a screen number to draw the Sketch as a full- screen window across all of the attached displays if there are more than one. """ @@ -8097,26 +8054,26 @@ def full_screen(*args): ----- Open a Sketch using the full size of the computer's display. This is intended to - be called from the ``settings()`` function. The ``size()`` and ``full_screen()`` + be called from the `settings()` function. The `size()` and `full_screen()` functions cannot both be used in the same program. When programming in module mode and imported mode, py5 will allow calls to - ``full_screen()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``full_screen()``, or calls - to ``size()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. - - When ``full_screen()`` is used without a parameter on a computer with multiple + `full_screen()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `full_screen()`, or calls to + `size()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + When `full_screen()` is used without a parameter on a computer with multiple monitors, it will (probably) draw the Sketch to the primary display. When it is used with a single parameter, this number defines the screen to display to program on (e.g. 1, 2, 3...). When used with two parameters, the first defines - the renderer to use (e.g. P2D) and the second defines the screen. The ``SPAN`` + the renderer to use (e.g. P2D) and the second defines the screen. The `SPAN` parameter can be used in place of a screen number to draw the Sketch as a full- screen window across all of the attached displays if there are more than one. """ @@ -8124,7 +8081,7 @@ def full_screen(*args): @overload -def get() -> Py5Image: +def get_pixels() -> Py5Image: """Reads the color of any pixel or grabs a section of the drawing surface. Underlying Processing method: PApplet.get @@ -8134,9 +8091,9 @@ def get() -> Py5Image: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -8157,33 +8114,33 @@ def get() -> Py5Image: ----- Reads the color of any pixel or grabs a section of the drawing surface. If no - parameters are specified, the entire drawing surface is returned. Use the ``x`` - and ``y`` parameters to get the value of one pixel. Get a section of the display - window by specifying additional ``w`` and ``h`` parameters. When getting an - image, the ``x`` and ``y`` parameters define the coordinates for the upper-left - corner of the returned image, regardless of the current ``image_mode()``. + parameters are specified, the entire drawing surface is returned. Use the `x` + and `y` parameters to get the value of one pixel. Get a section of the display + window by specifying additional `w` and `h` parameters. When getting an image, + the `x` and `y` parameters define the coordinates for the upper-left corner of + the returned image, regardless of the current `image_mode()`. If the pixel requested is outside of the image window, black is returned. The numbers returned are scaled according to the current color ranges, but only - ``RGB`` values are returned by this function. For example, even though you may - have drawn a shape with ``color_mode(HSB)``, the numbers returned will be in - ``RGB`` format. + `RGB` values are returned by this function. For example, even though you may + have drawn a shape with `color_mode(HSB)`, the numbers returned will be in `RGB` + format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``pixels[]`` or ``np_pixels[]``. The - equivalent statement to ``get(x, y)`` using ``pixels[]`` is - ``pixels[y*width+x]``. Using ``np_pixels[]`` it is ``np_pixels[y, x]``. See the - reference for ``pixels[]`` and ``np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `pixels[]` or `np_pixels[]`. The + equivalent statement to `get_pixels(x, y)` using `pixels[]` is + `pixels[y*width+x]`. Using `np_pixels[]` it is `np_pixels[y, x]`. See the + reference for `pixels[]` and `np_pixels[]` for more information. """ pass @overload -def get(x: int, y: int, /) -> int: +def get_pixels(x: int, y: int, /) -> int: """Reads the color of any pixel or grabs a section of the drawing surface. Underlying Processing method: PApplet.get @@ -8193,9 +8150,9 @@ def get(x: int, y: int, /) -> int: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -8216,33 +8173,33 @@ def get(x: int, y: int, /) -> int: ----- Reads the color of any pixel or grabs a section of the drawing surface. If no - parameters are specified, the entire drawing surface is returned. Use the ``x`` - and ``y`` parameters to get the value of one pixel. Get a section of the display - window by specifying additional ``w`` and ``h`` parameters. When getting an - image, the ``x`` and ``y`` parameters define the coordinates for the upper-left - corner of the returned image, regardless of the current ``image_mode()``. + parameters are specified, the entire drawing surface is returned. Use the `x` + and `y` parameters to get the value of one pixel. Get a section of the display + window by specifying additional `w` and `h` parameters. When getting an image, + the `x` and `y` parameters define the coordinates for the upper-left corner of + the returned image, regardless of the current `image_mode()`. If the pixel requested is outside of the image window, black is returned. The numbers returned are scaled according to the current color ranges, but only - ``RGB`` values are returned by this function. For example, even though you may - have drawn a shape with ``color_mode(HSB)``, the numbers returned will be in - ``RGB`` format. + `RGB` values are returned by this function. For example, even though you may + have drawn a shape with `color_mode(HSB)`, the numbers returned will be in `RGB` + format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``pixels[]`` or ``np_pixels[]``. The - equivalent statement to ``get(x, y)`` using ``pixels[]`` is - ``pixels[y*width+x]``. Using ``np_pixels[]`` it is ``np_pixels[y, x]``. See the - reference for ``pixels[]`` and ``np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `pixels[]` or `np_pixels[]`. The + equivalent statement to `get_pixels(x, y)` using `pixels[]` is + `pixels[y*width+x]`. Using `np_pixels[]` it is `np_pixels[y, x]`. See the + reference for `pixels[]` and `np_pixels[]` for more information. """ pass @overload -def get(x: int, y: int, w: int, h: int, /) -> Py5Image: +def get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image: """Reads the color of any pixel or grabs a section of the drawing surface. Underlying Processing method: PApplet.get @@ -8252,9 +8209,9 @@ def get(x: int, y: int, w: int, h: int, /) -> Py5Image: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -8275,32 +8232,32 @@ def get(x: int, y: int, w: int, h: int, /) -> Py5Image: ----- Reads the color of any pixel or grabs a section of the drawing surface. If no - parameters are specified, the entire drawing surface is returned. Use the ``x`` - and ``y`` parameters to get the value of one pixel. Get a section of the display - window by specifying additional ``w`` and ``h`` parameters. When getting an - image, the ``x`` and ``y`` parameters define the coordinates for the upper-left - corner of the returned image, regardless of the current ``image_mode()``. + parameters are specified, the entire drawing surface is returned. Use the `x` + and `y` parameters to get the value of one pixel. Get a section of the display + window by specifying additional `w` and `h` parameters. When getting an image, + the `x` and `y` parameters define the coordinates for the upper-left corner of + the returned image, regardless of the current `image_mode()`. If the pixel requested is outside of the image window, black is returned. The numbers returned are scaled according to the current color ranges, but only - ``RGB`` values are returned by this function. For example, even though you may - have drawn a shape with ``color_mode(HSB)``, the numbers returned will be in - ``RGB`` format. + `RGB` values are returned by this function. For example, even though you may + have drawn a shape with `color_mode(HSB)`, the numbers returned will be in `RGB` + format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``pixels[]`` or ``np_pixels[]``. The - equivalent statement to ``get(x, y)`` using ``pixels[]`` is - ``pixels[y*width+x]``. Using ``np_pixels[]`` it is ``np_pixels[y, x]``. See the - reference for ``pixels[]`` and ``np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `pixels[]` or `np_pixels[]`. The + equivalent statement to `get_pixels(x, y)` using `pixels[]` is + `pixels[y*width+x]`. Using `np_pixels[]` it is `np_pixels[y, x]`. See the + reference for `pixels[]` and `np_pixels[]` for more information. """ pass -def get(*args): +def get_pixels(*args): """Reads the color of any pixel or grabs a section of the drawing surface. Underlying Processing method: PApplet.get @@ -8310,9 +8267,9 @@ def get(*args): You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -8333,29 +8290,29 @@ def get(*args): ----- Reads the color of any pixel or grabs a section of the drawing surface. If no - parameters are specified, the entire drawing surface is returned. Use the ``x`` - and ``y`` parameters to get the value of one pixel. Get a section of the display - window by specifying additional ``w`` and ``h`` parameters. When getting an - image, the ``x`` and ``y`` parameters define the coordinates for the upper-left - corner of the returned image, regardless of the current ``image_mode()``. + parameters are specified, the entire drawing surface is returned. Use the `x` + and `y` parameters to get the value of one pixel. Get a section of the display + window by specifying additional `w` and `h` parameters. When getting an image, + the `x` and `y` parameters define the coordinates for the upper-left corner of + the returned image, regardless of the current `image_mode()`. If the pixel requested is outside of the image window, black is returned. The numbers returned are scaled according to the current color ranges, but only - ``RGB`` values are returned by this function. For example, even though you may - have drawn a shape with ``color_mode(HSB)``, the numbers returned will be in - ``RGB`` format. + `RGB` values are returned by this function. For example, even though you may + have drawn a shape with `color_mode(HSB)`, the numbers returned will be in `RGB` + format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``pixels[]`` or ``np_pixels[]``. The - equivalent statement to ``get(x, y)`` using ``pixels[]`` is - ``pixels[y*width+x]``. Using ``np_pixels[]`` it is ``np_pixels[y, x]``. See the - reference for ``pixels[]`` and ``np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `pixels[]` or `np_pixels[]`. The + equivalent statement to `get_pixels(x, y)` using `pixels[]` is + `pixels[y*width+x]`. Using `np_pixels[]` it is `np_pixels[y, x]`. See the + reference for `pixels[]` and `np_pixels[]` for more information. """ - return _py5sketch.get(*args) + return _py5sketch.get_pixels(*args) def get_frame_rate() -> float: @@ -8369,27 +8326,26 @@ def get_frame_rate() -> float: Get the running Sketch's current frame rate. This is measured in frames per second (fps) and uses an exponential moving average. The returned value will not be accurate until after the Sketch has run for a few seconds. You can set the - target frame rate with ``frame_rate()``. + target frame rate with `frame_rate()`. - This method provides the same information as Processing's ``frameRate`` - variable. Python can't have a variable and a method with the same name, so a new - method was created to provide access to that variable. + This method provides the same information as Processing's `frameRate` variable. + Python can't have a variable and a method with the same name, so a new method + was created to provide access to that variable. """ return _py5sketch.get_frame_rate() def get_graphics() -> Py5Graphics: - """Get the ``Py5Graphics`` object used by the Sketch. + """Get the `Py5Graphics` object used by the Sketch. Underlying Processing method: PApplet.getGraphics Notes ----- - Get the ``Py5Graphics`` object used by the Sketch. Internally, all of - Processing's drawing functionality comes from interaction with PGraphics - objects, and this will provide direct access to the PGraphics object used by the - Sketch. + Get the `Py5Graphics` object used by the Sketch. Internally, all of Processing's + drawing functionality comes from interaction with PGraphics objects, and this + will provide direct access to the PGraphics object used by the Sketch. """ return _py5sketch.get_graphics() @@ -8417,7 +8373,7 @@ def get_matrix() -> npt.NDArray[np.floating]: Notes ----- - Get the current matrix as a numpy array. Use the ``target`` parameter to put the + Get the current matrix as a numpy array. Use the `target` parameter to put the matrix data in a properly sized and typed numpy array. """ pass @@ -8447,7 +8403,7 @@ def get_matrix(target: npt.NDArray[np.floating], / Notes ----- - Get the current matrix as a numpy array. Use the ``target`` parameter to put the + Get the current matrix as a numpy array. Use the `target` parameter to put the matrix data in a properly sized and typed numpy array. """ pass @@ -8475,27 +8431,27 @@ def get_matrix(*args): Notes ----- - Get the current matrix as a numpy array. Use the ``target`` parameter to put the + Get the current matrix as a numpy array. Use the `target` parameter to put the matrix data in a properly sized and typed numpy array. """ return _py5sketch.get_matrix(*args) def get_surface() -> Py5Surface: - """Get the ``Py5Surface`` object used for the Sketch. + """Get the `Py5Surface` object used for the Sketch. Underlying Processing method: PApplet.getSurface Notes ----- - Get the ``Py5Surface`` object used for the Sketch. + Get the `Py5Surface` object used for the Sketch. """ return _py5sketch.get_surface() def green(rgb: int, /) -> float: - """Extracts the green value from a color, scaled to match current ``color_mode()``. + """Extracts the green value from a color, scaled to match current `color_mode()`. Underlying Processing method: PApplet.green @@ -8508,14 +8464,14 @@ def green(rgb: int, /) -> float: Notes ----- - Extracts the green value from a color, scaled to match current ``color_mode()``. + Extracts the green value from a color, scaled to match current `color_mode()`. - The ``green()`` function is easy to use and understand, but it is slower than a - technique called bit shifting. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``green()`` but with greater speed by using the - right shift operator (``>>``) with a bit mask. For example, ``green(c)`` and ``c - >> 8 & 0xFF`` both extract the green value from a color variable ``c`` but the - later is faster. + The `green()` function is easy to use and understand, but it is slower than a + technique called bit shifting. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `green()` but with greater speed by using the right + shift operator (`>>`) with a bit mask. For example, `green(c)` and `c >> 8 & + 0xFF` both extract the green value from a color variable `c` but the later is + faster. """ return _py5sketch.green(rgb) @@ -8539,67 +8495,66 @@ def hint(which: int, /) -> None: graphics are drawn. In the course of developing Processing, the developers had to make hard decisions about tradeoffs between performance and visual quality. They put significant effort into determining what makes most sense for the - largest number of users, and then use functions like ``hint()`` to allow people - to tune the settings for their particular Sketch. Implementing a ``hint()`` is a - last resort that's used when a more elegant solution cannot be found. Some - options might graduate to standard features instead of hints over time, or be - added and removed between (major) releases. + largest number of users, and then use functions like `hint()` to allow people to + tune the settings for their particular Sketch. Implementing a `hint()` is a last + resort that's used when a more elegant solution cannot be found. Some options + might graduate to standard features instead of hints over time, or be added and + removed between (major) releases. Hints used by the Default Renderer ---------------------------------- - * ``ENABLE_STROKE_PURE``: Fixes a problem with shapes that have a stroke and are - rendered using small steps (for instance, using ``vertex()`` with points that - are close to one another), or are drawn at small sizes. + * `ENABLE_STROKE_PURE`: Fixes a problem with shapes that have a stroke and are + rendered using small steps (for instance, using `vertex()` with points that are + close to one another), or are drawn at small sizes. - Hints for use with ``P2D`` and ``P3D`` + Hints for use with `P2D` and `P3D` -------------------------------------- - * ``DISABLE_OPENGL_ERRORS``: Speeds up the ``P3D`` renderer setting by not - checking for errors while running. - * ``DISABLE_TEXTURE_MIPMAPS``: Disable generation of texture mipmaps in ``P2D`` - or ``P3D``. This results in lower quality - but faster - rendering of texture - images when they appear smaller than their native resolutions (the mipmaps are - scaled-down versions of a texture that make it look better when drawing it at a - small size). However, the difference in performance is fairly minor on recent - desktop video cards. + * `DISABLE_OPENGL_ERRORS`: Speeds up the `P3D` renderer setting by not checking + for errors while running. + * `DISABLE_TEXTURE_MIPMAPS`: Disable generation of texture mipmaps in `P2D` or + `P3D`. This results in lower quality - but faster - rendering of texture images + when they appear smaller than their native resolutions (the mipmaps are scaled- + down versions of a texture that make it look better when drawing it at a small + size). However, the difference in performance is fairly minor on recent desktop + video cards. - Hints for use with ``P3D`` only + Hints for use with `P3D` only ------------------------------- - * ``DISABLE_DEPTH_MASK``: Disables writing into the depth buffer. This means - that a shape drawn with this hint can be hidden by another shape drawn later, + * `DISABLE_DEPTH_MASK`: Disables writing into the depth buffer. This means that + a shape drawn with this hint can be hidden by another shape drawn later, irrespective of their distances to the camera. Note that this is different from disabling the depth test. The depth test is still applied, as long as the - ``DISABLE_DEPTH_TEST`` hint is not called, but the depth values of the objects - are not recorded. This is useful when drawing a semi-transparent 3D object - without depth sorting, in order to avoid visual glitches due the faces of the - object being at different distances from the camera, but still having the object + `DISABLE_DEPTH_TEST` hint is not called, but the depth values of the objects are + not recorded. This is useful when drawing a semi-transparent 3D object without + depth sorting, in order to avoid visual glitches due the faces of the object + being at different distances from the camera, but still having the object properly occluded by the rest of the objects in the scene. - * ``ENABLE_DEPTH_SORT``: Enable primitive z-sorting of triangles and lines in - ``P3D``. This can slow performance considerably, and the algorithm is not yet + * `ENABLE_DEPTH_SORT`: Enable primitive z-sorting of triangles and lines in + `P3D`. This can slow performance considerably, and the algorithm is not yet perfect. - * ``DISABLE_DEPTH_TEST``: Disable the zbuffer, allowing you to draw on top of + * `DISABLE_DEPTH_TEST`: Disable the zbuffer, allowing you to draw on top of everything at will. When depth testing is disabled, items will be drawn to the screen sequentially, like a painting. This hint is most often used to draw in 3D, then draw in 2D on top of it (for instance, to draw GUI controls in 2D on top of a 3D interface). When called, this will also clear the depth buffer. - Restore the default with ``hint(ENABLE_DEPTH_TEST)``, but note that with the - depth buffer cleared, any 3D drawing that happens later in will ignore existing - shapes on the screen. - * ``DISABLE_OPTIMIZED_STROKE``: Forces the ``P3D`` renderer to draw each shape + Restore the default with `hint(ENABLE_DEPTH_TEST)`, but note that with the depth + buffer cleared, any 3D drawing that happens later in will ignore existing shapes + on the screen. + * `DISABLE_OPTIMIZED_STROKE`: Forces the `P3D` renderer to draw each shape (including its strokes) separately, instead of batching them into larger groups for better performance. One consequence of this is that 2D items drawn with - ``P3D`` are correctly stacked on the screen, depending on the order in which - they were drawn. Otherwise, glitches such as the stroke lines being drawn on top - of the interior of all the shapes will occur. However, this hint can make - rendering substantially slower, so it is recommended to use it only when drawing - a small amount of shapes. For drawing two-dimensional scenes, use the ``P2D`` - renderer instead, which doesn't need the hint to properly stack shapes and their - strokes. - * ``ENABLE_STROKE_PERSPECTIVE``: Enables stroke geometry (lines and points) to - be affected by the perspective, meaning that they will look smaller as they move + `P3D` are correctly stacked on the screen, depending on the order in which they + were drawn. Otherwise, glitches such as the stroke lines being drawn on top of + the interior of all the shapes will occur. However, this hint can make rendering + substantially slower, so it is recommended to use it only when drawing a small + amount of shapes. For drawing two-dimensional scenes, use the `P2D` renderer + instead, which doesn't need the hint to properly stack shapes and their strokes. + * `ENABLE_STROKE_PERSPECTIVE`: Enables stroke geometry (lines and points) to be + affected by the perspective, meaning that they will look smaller as they move away from the camera. """ return _py5sketch.hint(which) @@ -8613,8 +8568,8 @@ def hour() -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``hour()`` function - returns the current hour as a value from 0 - 23. + Py5 communicates with the clock on your computer. The `hour()` function returns + the current hour as a value from 0 - 23. """ return Sketch.hour() @@ -8640,7 +8595,7 @@ def hue(rgb: int, /) -> float: @overload def image(img: Py5Image, a: float, b: float, /) -> None: - """The ``image()`` function draws an image to the display window. + """The `image()` function draws an image to the display window. Underlying Processing method: PApplet.image @@ -8686,29 +8641,29 @@ def image(img: Py5Image, a: float, b: float, /) -> None: Notes ----- - The ``image()`` function draws an image to the display window. Images must be in + The `image()` function draws an image to the display window. Images must be in the Sketch's "data" directory to load correctly. Py5 currently works with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``image_mode()`` function can be used to change the way - these parameters draw the image. + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `image_mode()` function can be used to change the way these + parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `texture_mode()` setting. - The color of an image may be modified with the ``tint()`` function. This - function will maintain transparency for GIF and PNG images. + The color of an image may be modified with the `tint()` function. This function + will maintain transparency for GIF and PNG images. """ pass @overload def image(img: Py5Image, a: float, b: float, c: float, d: float, /) -> None: - """The ``image()`` function draws an image to the display window. + """The `image()` function draws an image to the display window. Underlying Processing method: PApplet.image @@ -8754,22 +8709,22 @@ def image(img: Py5Image, a: float, b: float, c: float, d: float, /) -> None: Notes ----- - The ``image()`` function draws an image to the display window. Images must be in + The `image()` function draws an image to the display window. Images must be in the Sketch's "data" directory to load correctly. Py5 currently works with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``image_mode()`` function can be used to change the way - these parameters draw the image. + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `image_mode()` function can be used to change the way these + parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `texture_mode()` setting. - The color of an image may be modified with the ``tint()`` function. This - function will maintain transparency for GIF and PNG images. + The color of an image may be modified with the `tint()` function. This function + will maintain transparency for GIF and PNG images. """ pass @@ -8777,7 +8732,7 @@ def image(img: Py5Image, a: float, b: float, c: float, d: float, /) -> None: @overload def image(img: Py5Image, a: float, b: float, c: float, d: float, u1: int, v1: int, u2: int, v2: int, /) -> None: - """The ``image()`` function draws an image to the display window. + """The `image()` function draws an image to the display window. Underlying Processing method: PApplet.image @@ -8823,28 +8778,28 @@ def image(img: Py5Image, a: float, b: float, c: float, d: float, Notes ----- - The ``image()`` function draws an image to the display window. Images must be in + The `image()` function draws an image to the display window. Images must be in the Sketch's "data" directory to load correctly. Py5 currently works with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``image_mode()`` function can be used to change the way - these parameters draw the image. + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `image_mode()` function can be used to change the way these + parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `texture_mode()` setting. - The color of an image may be modified with the ``tint()`` function. This - function will maintain transparency for GIF and PNG images. + The color of an image may be modified with the `tint()` function. This function + will maintain transparency for GIF and PNG images. """ pass def image(*args): - """The ``image()`` function draws an image to the display window. + """The `image()` function draws an image to the display window. Underlying Processing method: PApplet.image @@ -8890,29 +8845,29 @@ def image(*args): Notes ----- - The ``image()`` function draws an image to the display window. Images must be in + The `image()` function draws an image to the display window. Images must be in the Sketch's "data" directory to load correctly. Py5 currently works with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``image_mode()`` function can be used to change the way - these parameters draw the image. + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `image_mode()` function can be used to change the way these + parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `texture_mode()` setting. - The color of an image may be modified with the ``tint()`` function. This - function will maintain transparency for GIF and PNG images. + The color of an image may be modified with the `tint()` function. This function + will maintain transparency for GIF and PNG images. """ return _py5sketch.image(*args) def image_mode(mode: int, /) -> None: """Modifies the location from which images are drawn by changing the way in which - parameters given to ``image()`` are intepreted. + parameters given to `image()` are intepreted. Underlying Processing method: PApplet.imageMode @@ -8926,20 +8881,19 @@ def image_mode(mode: int, /) -> None: ----- Modifies the location from which images are drawn by changing the way in which - parameters given to ``image()`` are intepreted. + parameters given to `image()` are intepreted. - The default mode is ``image_mode(CORNER)``, which interprets the second and - third parameters of ``image()`` as the upper-left corner of the image. If two - additional parameters are specified, they are used to set the image's width and - height. + The default mode is `image_mode(CORNER)`, which interprets the second and third + parameters of `image()` as the upper-left corner of the image. If two additional + parameters are specified, they are used to set the image's width and height. - ``image_mode(CORNERS)`` interprets the second and third parameters of - ``image()`` as the location of one corner, and the fourth and fifth parameters - as the opposite corner. + `image_mode(CORNERS)` interprets the second and third parameters of `image()` as + the location of one corner, and the fourth and fifth parameters as the opposite + corner. - ``image_mode(CENTER)`` interprets the second and third parameters of ``image()`` - as the image's center point. If two additional parameters are specified, they - are used to set the image's width and height. + `image_mode(CENTER)` interprets the second and third parameters of `image()` as + the image's center point. If two additional parameters are specified, they are + used to set the image's width and height. The parameter must be written in ALL CAPS because Python is a case-sensitive language. @@ -8979,13 +8933,13 @@ def lerp_color(c1: int, c2: int, amt: float, /) -> int: Notes ----- - Calculates a color between two colors at a specific increment. The ``amt`` + Calculates a color between two colors at a specific increment. The `amt` parameter is the amount to interpolate between the two values where 0.0 is equal to the first point, 0.1 is very near the first point, 0.5 is halfway in between, etc. An amount below 0 will be treated as 0. Likewise, amounts above 1 will be capped - at 1. This is different from the behavior of ``lerp()``, but necessary because + at 1. This is different from the behavior of `lerp()`, but necessary because otherwise numbers outside the range will produce strange and unexpected colors. """ pass @@ -9023,13 +8977,13 @@ def lerp_color(c1: int, c2: int, amt: float, mode: int, /) -> int: Notes ----- - Calculates a color between two colors at a specific increment. The ``amt`` + Calculates a color between two colors at a specific increment. The `amt` parameter is the amount to interpolate between the two values where 0.0 is equal to the first point, 0.1 is very near the first point, 0.5 is halfway in between, etc. An amount below 0 will be treated as 0. Likewise, amounts above 1 will be capped - at 1. This is different from the behavior of ``lerp()``, but necessary because + at 1. This is different from the behavior of `lerp()`, but necessary because otherwise numbers outside the range will produce strange and unexpected colors. """ pass @@ -9066,13 +9020,13 @@ def lerp_color(*args): Notes ----- - Calculates a color between two colors at a specific increment. The ``amt`` + Calculates a color between two colors at a specific increment. The `amt` parameter is the amount to interpolate between the two values where 0.0 is equal to the first point, 0.1 is very near the first point, 0.5 is halfway in between, etc. An amount below 0 will be treated as 0. Likewise, amounts above 1 will be capped - at 1. This is different from the behavior of ``lerp()``, but necessary because + at 1. This is different from the behavior of `lerp()`, but necessary because otherwise numbers outside the range will produce strange and unexpected colors. """ return _py5sketch.lerp_color(*args) @@ -9099,11 +9053,11 @@ def light_falloff(constant: float, linear: float, quadratic: float, /) -> None: ----- Sets the falloff rates for point lights, spot lights, and ambient lights. Like - ``fill()``, it affects only the elements which are created after it in the code. - The default value is ``light_falloff(1.0, 0.0, 0.0)``, and the parameters are - used to calculate the falloff with the equation ``falloff = 1 / (CONSTANT + d * - ``LINEAR`` + (d*d) * QUADRATIC)``, where ``d`` is the distance from light - position to vertex position. + `fill()`, it affects only the elements which are created after it in the code. + The default value is `light_falloff(1.0, 0.0, 0.0)`, and the parameters are used + to calculate the falloff with the equation `falloff = 1 / (CONSTANT + d * + `LINEAR` + (d*d) * QUADRATIC)`, where `d` is the distance from light position to + vertex position. Thinking about an ambient light with a falloff can be tricky. If you want a region of your scene to be lit ambiently with one color and another region to be @@ -9134,12 +9088,12 @@ def light_specular(v1: float, v2: float, v3: float, /) -> None: Notes ----- - Sets the specular color for lights. Like ``fill()``, it affects only the - elements which are created after it in the code. Specular refers to light which - bounces off a surface in a preferred direction (rather than bouncing in all - directions like a diffuse light) and is used for creating highlights. The - specular quality of a light interacts with the specular material qualities set - through the ``specular()`` and ``shininess()`` functions. + Sets the specular color for lights. Like `fill()`, it affects only the elements + which are created after it in the code. Specular refers to light which bounces + off a surface in a preferred direction (rather than bouncing in all directions + like a diffuse light) and is used for creating highlights. The specular quality + of a light interacts with the specular material qualities set through the + `specular()` and `shininess()` functions. """ return _py5sketch.light_specular(v1, v2, v3) @@ -9153,11 +9107,11 @@ def lights() -> None: ----- Sets the default ambient light, directional light, falloff, and specular values. - The defaults are ``ambientLight(128, 128, 128)`` and ``directionalLight(128, - 128, 128, 0, 0, -1)``, ``lightFalloff(1, 0, 0)``, and ``lightSpecular(0, 0, - 0)``. Lights need to be included in the ``draw()`` to remain persistent in a - looping program. Placing them in the ``setup()`` of a looping program will cause - them to only have an effect the first time through the loop. + The defaults are `ambientLight(128, 128, 128)` and `directionalLight(128, 128, + 128, 0, 0, -1)`, `lightFalloff(1, 0, 0)`, and `lightSpecular(0, 0, 0)`. Lights + need to be included in the `draw()` to remain persistent in a looping program. + Placing them in the `setup()` of a looping program will cause them to only have + an effect the first time through the loop. """ return _py5sketch.lights() @@ -9201,13 +9155,13 @@ def line(x1: float, y1: float, x2: float, y2: float, /) -> None: ----- Draws a line (a direct path between two points) to the screen. The version of - ``line()`` with four parameters draws the line in 2D. To color a line, use the - ``stroke()`` function. A line cannot be filled, therefore the ``fill()`` - function will not affect the color of a line. 2D lines are drawn with a width of - one pixel by default, but this can be changed with the ``stroke_weight()`` - function. The version with six parameters allows the line to be placed anywhere - within XYZ space. Drawing this shape in 3D with the ``z`` parameter requires the - ``P3D`` parameter in combination with ``size()`` as shown in the third example. + `line()` with four parameters draws the line in 2D. To color a line, use the + `stroke()` function. A line cannot be filled, therefore the `fill()` function + will not affect the color of a line. 2D lines are drawn with a width of one + pixel by default, but this can be changed with the `stroke_weight()` function. + The version with six parameters allows the line to be placed anywhere within XYZ + space. Drawing this shape in 3D with the `z` parameter requires the `P3D` + parameter in combination with `size()` as shown in the third example. """ pass @@ -9252,13 +9206,13 @@ def line(x1: float, y1: float, z1: float, x2: float, ----- Draws a line (a direct path between two points) to the screen. The version of - ``line()`` with four parameters draws the line in 2D. To color a line, use the - ``stroke()`` function. A line cannot be filled, therefore the ``fill()`` - function will not affect the color of a line. 2D lines are drawn with a width of - one pixel by default, but this can be changed with the ``stroke_weight()`` - function. The version with six parameters allows the line to be placed anywhere - within XYZ space. Drawing this shape in 3D with the ``z`` parameter requires the - ``P3D`` parameter in combination with ``size()`` as shown in the third example. + `line()` with four parameters draws the line in 2D. To color a line, use the + `stroke()` function. A line cannot be filled, therefore the `fill()` function + will not affect the color of a line. 2D lines are drawn with a width of one + pixel by default, but this can be changed with the `stroke_weight()` function. + The version with six parameters allows the line to be placed anywhere within XYZ + space. Drawing this shape in 3D with the `z` parameter requires the `P3D` + parameter in combination with `size()` as shown in the third example. """ pass @@ -9301,13 +9255,13 @@ def line(*args): ----- Draws a line (a direct path between two points) to the screen. The version of - ``line()`` with four parameters draws the line in 2D. To color a line, use the - ``stroke()`` function. A line cannot be filled, therefore the ``fill()`` - function will not affect the color of a line. 2D lines are drawn with a width of - one pixel by default, but this can be changed with the ``stroke_weight()`` - function. The version with six parameters allows the line to be placed anywhere - within XYZ space. Drawing this shape in 3D with the ``z`` parameter requires the - ``P3D`` parameter in combination with ``size()`` as shown in the third example. + `line()` with four parameters draws the line in 2D. To color a line, use the + `stroke()` function. A line cannot be filled, therefore the `fill()` function + will not affect the color of a line. 2D lines are drawn with a width of one + pixel by default, but this can be changed with the `stroke_weight()` function. + The version with six parameters allows the line to be placed anywhere within XYZ + space. Drawing this shape in 3D with the `z` parameter requires the `P3D` + parameter in combination with `size()` as shown in the third example. """ return _py5sketch.line(*args) @@ -9327,19 +9281,19 @@ def lines(coordinates: npt.NDArray[np.floating], /) -> None: ----- Draw a collection of lines to the screen. The purpose of this method is to - provide an alternative to repeatedly calling ``line()`` in a loop. For a large - number of lines, the performance of ``lines()`` will be much faster. + provide an alternative to repeatedly calling `line()` in a loop. For a large + number of lines, the performance of `lines()` will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each - line. The first few columns are for the first point of each line and the next - few columns are for the second point of each line. There will be four or six - columns for 2D or 3D points, respectively. + The `coordinates` parameter should be a numpy array with one row for each line. + The first few columns are for the first point of each line and the next few + columns are for the second point of each line. There will be four or six columns + for 2D or 3D points, respectively. """ return _py5sketch.lines(coordinates) def load_font(filename: str, /) -> Py5Font: - """Loads a .vlw formatted font into a ``Py5Font`` object. + """Loads a .vlw formatted font into a `Py5Font` object. Underlying Processing method: PApplet.loadFont @@ -9352,20 +9306,20 @@ def load_font(filename: str, /) -> Py5Font: Notes ----- - Loads a .vlw formatted font into a ``Py5Font`` object. Create a .vlw font with - the ``create_font_file()`` function. This tool creates a texture for each - alphanumeric character and then adds them as a .vlw file to the current Sketch's - data folder. Because the letters are defined as textures (and not vector data) - the size at which the fonts are created must be considered in relation to the - size at which they are drawn. For example, load a 32pt font if the Sketch - displays the font at 32 pixels or smaller. Conversely, if a 12pt font is loaded - and displayed at 48pts, the letters will be distorted because the program will - be stretching a small graphic to a large size. + Loads a .vlw formatted font into a `Py5Font` object. Create a .vlw font with the + `create_font_file()` function. This tool creates a texture for each alphanumeric + character and then adds them as a .vlw file to the current Sketch's data folder. + Because the letters are defined as textures (and not vector data) the size at + which the fonts are created must be considered in relation to the size at which + they are drawn. For example, load a 32pt font if the Sketch displays the font at + 32 pixels or smaller. Conversely, if a 12pt font is loaded and displayed at + 48pts, the letters will be distorted because the program will be stretching a + small graphic to a large size. - Like ``load_image()`` and other functions that load data, the ``load_font()`` - function should not be used inside ``draw()``, because it will slow down the + Like `load_image()` and other functions that load data, the `load_font()` + function should not be used inside `draw()`, because it will slow down the Sketch considerably, as the font will be re-loaded from the disk (or network) on - each frame. It's recommended to load files inside ``setup()``. + each frame. It's recommended to load files inside `setup()`. To load correctly, fonts must be located in the "data" folder of the current Sketch. Alternatively, the file maybe be loaded from anywhere on the local @@ -9373,38 +9327,38 @@ def load_font(filename: str, /) -> Py5Font: or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. - Use ``create_font()`` (instead of ``load_font()``) to enable vector data to be - used with the default renderer setting. This can be helpful when many font sizes - are needed, or when using any renderer based on the default renderer, such as - the ``PDF`` renderer. + Use `create_font()` (instead of `load_font()`) to enable vector data to be used + with the default renderer setting. This can be helpful when many font sizes are + needed, or when using any renderer based on the default renderer, such as the + `PDF` renderer. """ return _py5sketch.load_font(filename) def load_pixels() -> None: - """Loads the pixel data of the current display window into the ``pixels[]`` array. + """Loads the pixel data of the current display window into the `pixels[]` array. Underlying Processing method: PApplet.loadPixels Notes ----- - Loads the pixel data of the current display window into the ``pixels[]`` array. + Loads the pixel data of the current display window into the `pixels[]` array. This function must always be called before reading from or writing to - ``pixels[]``. Subsequent changes to the display window will not be reflected in - ``pixels[]`` until ``load_pixels()`` is called again. + `pixels[]`. Subsequent changes to the display window will not be reflected in + `pixels[]` until `load_pixels()` is called again. """ return _py5sketch.load_pixels() @overload def load_shader(frag_filename: str, /) -> Py5Shader: - """Loads a shader into a ``Py5Shader`` object. + """Loads a shader into a `Py5Shader` object. Underlying Processing method: PApplet.loadShader @@ -9428,26 +9382,26 @@ def load_shader(frag_filename: str, /) -> Py5Shader: Notes ----- - Loads a shader into a ``Py5Shader`` object. The shader file must be located in - the Sketch's "data" directory to load correctly. Shaders are compatible with the - ``P2D`` and ``P3D`` renderers, but not with the default renderer. + Loads a shader into a `Py5Shader` object. The shader file must be located in the + Sketch's "data" directory to load correctly. Shaders are compatible with the + `P2D` and `P3D` renderers, but not with the default renderer. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. """ pass @overload def load_shader(frag_filename: str, vert_filename: str, /) -> Py5Shader: - """Loads a shader into a ``Py5Shader`` object. + """Loads a shader into a `Py5Shader` object. Underlying Processing method: PApplet.loadShader @@ -9471,25 +9425,25 @@ def load_shader(frag_filename: str, vert_filename: str, /) -> Py5Shader: Notes ----- - Loads a shader into a ``Py5Shader`` object. The shader file must be located in - the Sketch's "data" directory to load correctly. Shaders are compatible with the - ``P2D`` and ``P3D`` renderers, but not with the default renderer. + Loads a shader into a `Py5Shader` object. The shader file must be located in the + Sketch's "data" directory to load correctly. Shaders are compatible with the + `P2D` and `P3D` renderers, but not with the default renderer. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. """ pass def load_shader(*args): - """Loads a shader into a ``Py5Shader`` object. + """Loads a shader into a `Py5Shader` object. Underlying Processing method: PApplet.loadShader @@ -9513,26 +9467,26 @@ def load_shader(*args): Notes ----- - Loads a shader into a ``Py5Shader`` object. The shader file must be located in - the Sketch's "data" directory to load correctly. Shaders are compatible with the - ``P2D`` and ``P3D`` renderers, but not with the default renderer. + Loads a shader into a `Py5Shader` object. The shader file must be located in the + Sketch's "data" directory to load correctly. Shaders are compatible with the + `P2D` and `P3D` renderers, but not with the default renderer. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. """ return _py5sketch.load_shader(*args) @overload def load_shape(filename: str, /) -> Py5Shape: - """Loads geometry into a variable of type ``Py5Shape``. + """Loads geometry into a variable of type `Py5Shape`. Underlying Processing method: PApplet.loadShape @@ -9556,28 +9510,27 @@ def load_shape(filename: str, /) -> Py5Shape: Notes ----- - Loads geometry into a variable of type ``Py5Shape``. SVG and OBJ files may be + Loads geometry into a variable of type `Py5Shape`. SVG and OBJ files may be loaded. To load correctly, the file must be located in the data directory of the - current Sketch. In most cases, ``load_shape()`` should be used inside - ``setup()`` because loading shapes inside ``draw()`` will reduce the speed of a - Sketch. + current Sketch. In most cases, `load_shape()` should be used inside `setup()` + because loading shapes inside `draw()` will reduce the speed of a Sketch. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause errors if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause errors if your code does not + check whether the value returned is `None`. """ pass @overload def load_shape(filename: str, options: str, /) -> Py5Shape: - """Loads geometry into a variable of type ``Py5Shape``. + """Loads geometry into a variable of type `Py5Shape`. Underlying Processing method: PApplet.loadShape @@ -9601,27 +9554,26 @@ def load_shape(filename: str, options: str, /) -> Py5Shape: Notes ----- - Loads geometry into a variable of type ``Py5Shape``. SVG and OBJ files may be + Loads geometry into a variable of type `Py5Shape`. SVG and OBJ files may be loaded. To load correctly, the file must be located in the data directory of the - current Sketch. In most cases, ``load_shape()`` should be used inside - ``setup()`` because loading shapes inside ``draw()`` will reduce the speed of a - Sketch. + current Sketch. In most cases, `load_shape()` should be used inside `setup()` + because loading shapes inside `draw()` will reduce the speed of a Sketch. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause errors if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause errors if your code does not + check whether the value returned is `None`. """ pass def load_shape(*args): - """Loads geometry into a variable of type ``Py5Shape``. + """Loads geometry into a variable of type `Py5Shape`. Underlying Processing method: PApplet.loadShape @@ -9645,27 +9597,26 @@ def load_shape(*args): Notes ----- - Loads geometry into a variable of type ``Py5Shape``. SVG and OBJ files may be + Loads geometry into a variable of type `Py5Shape`. SVG and OBJ files may be loaded. To load correctly, the file must be located in the data directory of the - current Sketch. In most cases, ``load_shape()`` should be used inside - ``setup()`` because loading shapes inside ``draw()`` will reduce the speed of a - Sketch. + current Sketch. In most cases, `load_shape()` should be used inside `setup()` + because loading shapes inside `draw()` will reduce the speed of a Sketch. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause errors if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause errors if your code does not + check whether the value returned is `None`. """ return _py5sketch.load_shape(*args) def loop() -> None: - """By default, py5 loops through ``draw()`` continuously, executing the code within + """By default, py5 loops through `draw()` continuously, executing the code within it. Underlying Processing method: PApplet.loop @@ -9673,9 +9624,9 @@ def loop() -> None: Notes ----- - By default, py5 loops through ``draw()`` continuously, executing the code within - it. However, the ``draw()`` loop may be stopped by calling ``no_loop()``. In - that case, the ``draw()`` loop can be resumed with ``loop()``. + By default, py5 loops through `draw()` continuously, executing the code within + it. However, the `draw()` loop may be stopped by calling `no_loop()`. In that + case, the `draw()` loop can be resumed with `loop()`. """ return _py5sketch.loop() @@ -9704,7 +9655,7 @@ def minute() -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``minute()`` function + Py5 communicates with the clock on your computer. The `minute()` function returns the current minute as a value from 0 - 59. """ return Sketch.minute() @@ -9736,11 +9687,11 @@ def model_x(x: float, y: float, z: float, /) -> float: space relative to the location of the original point once the transformations are no longer in use. - In the example, the ``model_x()``, ``model_y()``, and ``model_z()`` functions - record the location of a box in space after being placed using a series of - translate and rotate commands. After ``pop_matrix()`` is called, those - transformations no longer apply, but the (x, y, z) coordinate returned by the - model functions is used to place another box in the same location. + In the example, the `model_x()`, `model_y()`, and `model_z()` functions record + the location of a box in space after being placed using a series of translate + and rotate commands. After `pop_matrix()` is called, those transformations no + longer apply, but the (x, y, z) coordinate returned by the model functions is + used to place another box in the same location. """ return _py5sketch.model_x(x, y, z) @@ -9771,11 +9722,11 @@ def model_y(x: float, y: float, z: float, /) -> float: space relative to the location of the original point once the transformations are no longer in use. - In the example, the ``model_x()``, ``model_y()``, and ``model_z()`` functions - record the location of a box in space after being placed using a series of - translate and rotate commands. After ``pop_matrix()`` is called, those - transformations no longer apply, but the (x, y, z) coordinate returned by the - model functions is used to place another box in the same location. + In the example, the `model_x()`, `model_y()`, and `model_z()` functions record + the location of a box in space after being placed using a series of translate + and rotate commands. After `pop_matrix()` is called, those transformations no + longer apply, but the (x, y, z) coordinate returned by the model functions is + used to place another box in the same location. """ return _py5sketch.model_y(x, y, z) @@ -9806,11 +9757,11 @@ def model_z(x: float, y: float, z: float, /) -> float: space relative to the location of the original point once the transformations are no longer in use. - In the example, the ``model_x()``, ``model_y()``, and ``model_z()`` functions - record the location of a box in space after being placed using a series of - translate and rotate commands. After ``pop_matrix()`` is called, those - transformations no longer apply, but the (x, y, z) coordinate returned by the - model functions is used to place another box in the same location. + In the example, the `model_x()`, `model_y()`, and `model_z()` functions record + the location of a box in space after being placed using a series of translate + and rotate commands. After `pop_matrix()` is called, those transformations no + longer apply, but the (x, y, z) coordinate returned by the model functions is + used to place another box in the same location. """ return _py5sketch.model_z(x, y, z) @@ -9823,21 +9774,21 @@ def month() -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``month()`` function - returns the current month as a value from 1 - 12. + Py5 communicates with the clock on your computer. The `month()` function returns + the current month as a value from 1 - 12. """ return Sketch.month() def no_clip() -> None: - """Disables the clipping previously started by the ``clip()`` function. + """Disables the clipping previously started by the `clip()` function. Underlying Processing method: PApplet.noClip Notes ----- - Disables the clipping previously started by the ``clip()`` function. + Disables the clipping previously started by the `clip()` function. """ return _py5sketch.no_clip() @@ -9864,7 +9815,7 @@ def no_fill() -> None: Notes ----- - Disables filling geometry. If both ``no_stroke()`` and ``no_fill()`` are called, + Disables filling geometry. If both `no_stroke()` and `no_fill()` are called, nothing will be drawn to the screen. """ return _py5sketch.no_fill() @@ -9879,7 +9830,7 @@ def no_lights() -> None: ----- Disable all lighting. Lighting is turned off by default and enabled with the - ``lights()`` function. This function can be used to disable lighting so that 2D + `lights()` function. This function can be used to disable lighting so that 2D geometry (which does not require lighting) can be drawn after a set of lighted 3D geometry. """ @@ -9887,27 +9838,27 @@ def no_lights() -> None: def no_loop() -> None: - """Stops py5 from continuously executing the code within ``draw()``. + """Stops py5 from continuously executing the code within `draw()`. Underlying Processing method: PApplet.noLoop Notes ----- - Stops py5 from continuously executing the code within ``draw()``. If ``loop()`` - is called, the code in ``draw()`` begins to run continuously again. If using - ``no_loop()`` in ``setup()``, it should be the last line inside the block. + Stops py5 from continuously executing the code within `draw()`. If `loop()` is + called, the code in `draw()` begins to run continuously again. If using + `no_loop()` in `setup()`, it should be the last line inside the block. - When ``no_loop()`` is used, it's not possible to manipulate or access the screen - inside event handling functions such as ``mouse_pressed()`` or - ``key_pressed()``. Instead, use those functions to call ``redraw()`` or - ``loop()``, which will run ``draw()``, which can update the screen properly. - This means that when ``no_loop()`` has been called, no drawing can happen, and - functions like ``save_frame()`` or ``load_pixels()`` may not be used. + When `no_loop()` is used, it's not possible to manipulate or access the screen + inside event handling functions such as `mouse_pressed()` or `key_pressed()`. + Instead, use those functions to call `redraw()` or `loop()`, which will run + `draw()`, which can update the screen properly. This means that when `no_loop()` + has been called, no drawing can happen, and functions like `save_frame()` or + `load_pixels()` may not be used. - Note that if the Sketch is resized, ``redraw()`` will be called to update the - Sketch, even after ``no_loop()`` has been specified. Otherwise, the Sketch would - enter an odd state until ``loop()`` was called. + Note that if the Sketch is resized, `redraw()` will be called to update the + Sketch, even after `no_loop()` has been specified. Otherwise, the Sketch would + enter an odd state until `loop()` was called. """ return _py5sketch.no_loop() @@ -9923,24 +9874,24 @@ def no_smooth() -> None: Draws all geometry and fonts with jagged (aliased) edges and images with hard edges between the pixels when enlarged rather than interpolating pixels. Note - that ``smooth()`` is active by default, so it is necessary to call - ``no_smooth()`` to disable smoothing of geometry, fonts, and images. + that `smooth()` is active by default, so it is necessary to call `no_smooth()` + to disable smoothing of geometry, fonts, and images. - The ``no_smooth()`` function can only be called once within a Sketch. It is - intended to be called from the ``settings()`` function. The ``smooth()`` - function follows the same rules. + The `no_smooth()` function can only be called once within a Sketch. It is + intended to be called from the `settings()` function. The `smooth()` function + follows the same rules. When programming in module mode and imported mode, py5 will allow calls to - ``no_smooth()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``no_smooth()``, or calls - to ``size()``, ``full_screen()``, ``smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. + `no_smooth()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `no_smooth()`, or calls to + `size()`, `full_screen()`, `smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. """ return _py5sketch.no_smooth() @@ -9953,8 +9904,8 @@ def no_stroke() -> None: Notes ----- - Disables drawing the stroke (outline). If both ``no_stroke()`` and ``no_fill()`` - are called, nothing will be drawn to the screen. + Disables drawing the stroke (outline). If both `no_stroke()` and `no_fill()` are + called, nothing will be drawn to the screen. """ return _py5sketch.no_stroke() @@ -9977,7 +9928,7 @@ def no_tint() -> None: @overload def noise_detail(lod: int, /) -> None: """Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. + produced by the `noise()` function. Underlying Processing method: PApplet.noiseDetail @@ -10002,20 +9953,20 @@ def noise_detail(lod: int, /) -> None: ----- Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. Similar to harmonics in physics, - Processing noise is computed over several octaves. Lower octaves contribute more - to the output signal and as such define the overall intensity of the noise, - whereas higher octaves create finer-grained details in the noise sequence. + produced by the `noise()` function. Similar to harmonics in physics, Processing + noise is computed over several octaves. Lower octaves contribute more to the + output signal and as such define the overall intensity of the noise, whereas + higher octaves create finer-grained details in the noise sequence. By default, noise is computed over 4 octaves with each octave contributing exactly half than its predecessor, starting at 50% strength for the first octave. This falloff amount can be changed by adding an additional function - parameter. For example, a ``falloff`` factor of 0.75 means each octave will now + parameter. For example, a `falloff` factor of 0.75 means each octave will now have 75% impact (25% less) of the previous lower octave. While any number between 0.0 and 1.0 is valid, note that values greater than 0.5 may result in noise() returning values greater than 1.0 or less than 0.0. - By changing these parameters, the signal created by the ``noise()`` function can + By changing these parameters, the signal created by the `noise()` function can be adapted to fit very specific needs and characteristics. """ pass @@ -10024,7 +9975,7 @@ def noise_detail(lod: int, /) -> None: @overload def noise_detail(lod: int, falloff: float, /) -> None: """Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. + produced by the `noise()` function. Underlying Processing method: PApplet.noiseDetail @@ -10049,20 +10000,20 @@ def noise_detail(lod: int, falloff: float, /) -> None: ----- Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. Similar to harmonics in physics, - Processing noise is computed over several octaves. Lower octaves contribute more - to the output signal and as such define the overall intensity of the noise, - whereas higher octaves create finer-grained details in the noise sequence. + produced by the `noise()` function. Similar to harmonics in physics, Processing + noise is computed over several octaves. Lower octaves contribute more to the + output signal and as such define the overall intensity of the noise, whereas + higher octaves create finer-grained details in the noise sequence. By default, noise is computed over 4 octaves with each octave contributing exactly half than its predecessor, starting at 50% strength for the first octave. This falloff amount can be changed by adding an additional function - parameter. For example, a ``falloff`` factor of 0.75 means each octave will now + parameter. For example, a `falloff` factor of 0.75 means each octave will now have 75% impact (25% less) of the previous lower octave. While any number between 0.0 and 1.0 is valid, note that values greater than 0.5 may result in noise() returning values greater than 1.0 or less than 0.0. - By changing these parameters, the signal created by the ``noise()`` function can + By changing these parameters, the signal created by the `noise()` function can be adapted to fit very specific needs and characteristics. """ pass @@ -10070,7 +10021,7 @@ def noise_detail(lod: int, falloff: float, /) -> None: def noise_detail(*args): """Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. + produced by the `noise()` function. Underlying Processing method: PApplet.noiseDetail @@ -10095,27 +10046,27 @@ def noise_detail(*args): ----- Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. Similar to harmonics in physics, - Processing noise is computed over several octaves. Lower octaves contribute more - to the output signal and as such define the overall intensity of the noise, - whereas higher octaves create finer-grained details in the noise sequence. + produced by the `noise()` function. Similar to harmonics in physics, Processing + noise is computed over several octaves. Lower octaves contribute more to the + output signal and as such define the overall intensity of the noise, whereas + higher octaves create finer-grained details in the noise sequence. By default, noise is computed over 4 octaves with each octave contributing exactly half than its predecessor, starting at 50% strength for the first octave. This falloff amount can be changed by adding an additional function - parameter. For example, a ``falloff`` factor of 0.75 means each octave will now + parameter. For example, a `falloff` factor of 0.75 means each octave will now have 75% impact (25% less) of the previous lower octave. While any number between 0.0 and 1.0 is valid, note that values greater than 0.5 may result in noise() returning values greater than 1.0 or less than 0.0. - By changing these parameters, the signal created by the ``noise()`` function can + By changing these parameters, the signal created by the `noise()` function can be adapted to fit very specific needs and characteristics. """ return _py5sketch.noise_detail(*args) def noise_seed(seed: int, /) -> None: - """Sets the seed value for ``noise()``. + """Sets the seed value for `noise()`. Underlying Processing method: PApplet.noiseSeed @@ -10128,7 +10079,7 @@ def noise_seed(seed: int, /) -> None: Notes ----- - Sets the seed value for ``noise()``. By default, ``noise()`` produces different + Sets the seed value for `noise()`. By default, `noise()` produces different results each time the program is run. Set the seed parameter to a constant to return the same pseudo-random numbers each time the Sketch is run. """ @@ -10156,11 +10107,11 @@ def normal(nx: float, ny: float, nz: float, /) -> None: ----- Sets the current normal vector. Used for drawing three dimensional shapes and - surfaces, ``normal()`` specifies a vector perpendicular to a shape's surface + surfaces, `normal()` specifies a vector perpendicular to a shape's surface which, in turn, determines how lighting affects it. Py5 attempts to automatically assign normals to shapes, but since that's imperfect, this is a better option when you want more control. This function is identical to - ``gl_normal3f()`` in OpenGL. + `gl_normal3f()` in OpenGL. """ return _py5sketch.normal(nx, ny, nz) @@ -10210,7 +10161,7 @@ def ortho() -> None: clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. """ pass @@ -10260,7 +10211,7 @@ def ortho(left: float, right: float, bottom: float, top: float, /) -> None: clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. """ pass @@ -10311,7 +10262,7 @@ def ortho(left: float, right: float, bottom: float, clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. """ pass @@ -10360,13 +10311,13 @@ def ortho(*args): clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. """ return _py5sketch.ortho(*args) def os_noise_seed(seed: int, /) -> None: - """Sets the seed value for ``os_noise()``. + """Sets the seed value for `os_noise()`. Parameters ---------- @@ -10377,7 +10328,7 @@ def os_noise_seed(seed: int, /) -> None: Notes ----- - Sets the seed value for ``os_noise()``. By default, ``os_noise()`` produces + Sets the seed value for `os_noise()`. By default, `os_noise()` produces different results each time the program is run. Set the seed parameter to a constant to return the same pseudo-random numbers each time the Sketch is run. """ @@ -10424,8 +10375,8 @@ def perspective() -> None: perspective of the world more accurately than orthographic projection. The version of perspective without parameters sets the default perspective and the version with four parameters allows the programmer to set the area precisely. - The default values are: ``perspective(PI/3.0, width/height, cameraZ/10.0, - cameraZ*10.0)`` where cameraZ is ``((height/2.0) / tan(PI*60.0/360.0))``. + The default values are: `perspective(PI/3.0, width/height, cameraZ/10.0, + cameraZ*10.0)` where cameraZ is `((height/2.0) / tan(PI*60.0/360.0))`. """ pass @@ -10471,8 +10422,8 @@ def perspective(fovy: float, aspect: float, perspective of the world more accurately than orthographic projection. The version of perspective without parameters sets the default perspective and the version with four parameters allows the programmer to set the area precisely. - The default values are: ``perspective(PI/3.0, width/height, cameraZ/10.0, - cameraZ*10.0)`` where cameraZ is ``((height/2.0) / tan(PI*60.0/360.0))``. + The default values are: `perspective(PI/3.0, width/height, cameraZ/10.0, + cameraZ*10.0)` where cameraZ is `((height/2.0) / tan(PI*60.0/360.0))`. """ pass @@ -10516,8 +10467,8 @@ def perspective(*args): perspective of the world more accurately than orthographic projection. The version of perspective without parameters sets the default perspective and the version with four parameters allows the programmer to set the area precisely. - The default values are: ``perspective(PI/3.0, width/height, cameraZ/10.0, - cameraZ*10.0)`` where cameraZ is ``((height/2.0) / tan(PI*60.0/360.0))``. + The default values are: `perspective(PI/3.0, width/height, cameraZ/10.0, + cameraZ*10.0)` where cameraZ is `((height/2.0) / tan(PI*60.0/360.0))`. """ return _py5sketch.perspective(*args) @@ -10541,28 +10492,28 @@ def pixel_density(density: int, /) -> None: This function makes it possible for py5 to render using all of the pixels on high resolutions screens like Apple Retina displays and Windows High-DPI displays. This function can only be run once within a program. It is intended to - be called from the ``settings()`` function. + be called from the `settings()` function. When programming in module mode and imported mode, py5 will allow calls to - ``pixel_density()`` from the ``setup()`` function if it is called at the - beginning of ``setup()``. This allows the user to omit the ``settings()`` - function, much like what can be done while programming in the Processing IDE. - Py5 does this by inspecting the ``setup()`` function and attempting to split it - into synthetic ``settings()`` and ``setup()`` functions if both were not created - by the user and the real ``setup()`` function contains a call to - ``pixel_density()``, or calls to ``size()``, ``full_screen()``, ``smooth()``, or - ``no_smooth()``. Calls to those functions must be at the very beginning of - ``setup()``, before any other Python code (but comments are ok). This feature is - not available when programming in class mode. - - The ``pixel_density()`` should only be used with hardcoded numbers (in almost - all cases this number will be 2) or in combination with ``display_density()`` as - in the second example. + `pixel_density()` from the `setup()` function if it is called at the beginning + of `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `pixel_density()`, or calls to + `size()`, `full_screen()`, `smooth()`, or `no_smooth()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + The `pixel_density()` should only be used with hardcoded numbers (in almost all + cases this number will be 2) or in combination with `display_density()` as in + the second example. When the pixel density is set to more than 1, it changes all of the pixel - operations including the way ``get()``, ``blend()``, ``copy()``, - ``update_pixels()``, and ``update_np_pixels()`` all work. See the reference for - ``pixel_width`` and ``pixel_height`` for more information. + operations including the way `get_pixels()`, `set_pixels()`, `blend()`, + `copy()`, `update_pixels()`, and `update_np_pixels()` all work. See the + reference for `pixel_width` and `pixel_height` for more information. """ return _py5sketch.pixel_density(density) @@ -10599,19 +10550,18 @@ def point(x: float, y: float, /) -> None: Draws a point, a coordinate in space at the dimension of one pixel. The first parameter is the horizontal value for the point, the second value is the vertical value for the point, and the optional third value is the depth value. - Drawing this shape in 3D with the ``z`` parameter requires the ``P3D`` parameter - in combination with ``size()`` as shown in the second example. + Drawing this shape in 3D with the `z` parameter requires the `P3D` parameter in + combination with `size()` as shown in the second example. - Use ``stroke()`` to set the color of a ``point()``. + Use `stroke()` to set the color of a `point()`. - Point appears round with the default ``stroke_cap(ROUND)`` and square with - ``stroke_cap(PROJECT)``. Points are invisible with ``stroke_cap(SQUARE)`` (no - cap). + Point appears round with the default `stroke_cap(ROUND)` and square with + `stroke_cap(PROJECT)`. Points are invisible with `stroke_cap(SQUARE)` (no cap). - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the screen, depending on the graphics settings of the computer. Workarounds include - setting the pixel using the ``pixels[]`` or ``np_pixels[]`` arrays or drawing - the point using either ``circle()`` or ``square()``. + setting the pixel using the `pixels[]` or `np_pixels[]` arrays or drawing the + point using either `circle()` or `square()`. """ pass @@ -10648,19 +10598,18 @@ def point(x: float, y: float, z: float, /) -> None: Draws a point, a coordinate in space at the dimension of one pixel. The first parameter is the horizontal value for the point, the second value is the vertical value for the point, and the optional third value is the depth value. - Drawing this shape in 3D with the ``z`` parameter requires the ``P3D`` parameter - in combination with ``size()`` as shown in the second example. + Drawing this shape in 3D with the `z` parameter requires the `P3D` parameter in + combination with `size()` as shown in the second example. - Use ``stroke()`` to set the color of a ``point()``. + Use `stroke()` to set the color of a `point()`. - Point appears round with the default ``stroke_cap(ROUND)`` and square with - ``stroke_cap(PROJECT)``. Points are invisible with ``stroke_cap(SQUARE)`` (no - cap). + Point appears round with the default `stroke_cap(ROUND)` and square with + `stroke_cap(PROJECT)`. Points are invisible with `stroke_cap(SQUARE)` (no cap). - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the screen, depending on the graphics settings of the computer. Workarounds include - setting the pixel using the ``pixels[]`` or ``np_pixels[]`` arrays or drawing - the point using either ``circle()`` or ``square()``. + setting the pixel using the `pixels[]` or `np_pixels[]` arrays or drawing the + point using either `circle()` or `square()`. """ pass @@ -10696,19 +10645,18 @@ def point(*args): Draws a point, a coordinate in space at the dimension of one pixel. The first parameter is the horizontal value for the point, the second value is the vertical value for the point, and the optional third value is the depth value. - Drawing this shape in 3D with the ``z`` parameter requires the ``P3D`` parameter - in combination with ``size()`` as shown in the second example. + Drawing this shape in 3D with the `z` parameter requires the `P3D` parameter in + combination with `size()` as shown in the second example. - Use ``stroke()`` to set the color of a ``point()``. + Use `stroke()` to set the color of a `point()`. - Point appears round with the default ``stroke_cap(ROUND)`` and square with - ``stroke_cap(PROJECT)``. Points are invisible with ``stroke_cap(SQUARE)`` (no - cap). + Point appears round with the default `stroke_cap(ROUND)` and square with + `stroke_cap(PROJECT)`. Points are invisible with `stroke_cap(SQUARE)` (no cap). - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the screen, depending on the graphics settings of the computer. Workarounds include - setting the pixel using the ``pixels[]`` or ``np_pixels[]`` arrays or drawing - the point using either ``circle()`` or ``square()``. + setting the pixel using the `pixels[]` or `np_pixels[]` arrays or drawing the + point using either `circle()` or `square()`. """ return _py5sketch.point(*args) @@ -10743,12 +10691,12 @@ def point_light(v1: float, v2: float, v3: float, Notes ----- - Adds a point light. Lights need to be included in the ``draw()`` to remain - persistent in a looping program. Placing them in the ``setup()`` of a looping + Adds a point light. Lights need to be included in the `draw()` to remain + persistent in a looping program. Placing them in the `setup()` of a looping program will cause them to only have an effect the first time through the loop. - The ``v1``, ``v2``, and ``v3`` parameters are interpreted as either RGB or HSB - values, depending on the current color mode. The ``x``, ``y``, and ``z`` - parameters set the position of the light. + The `v1`, `v2`, and `v3` parameters are interpreted as either RGB or HSB values, + depending on the current color mode. The `x`, `y`, and `z` parameters set the + position of the light. """ return _py5sketch.point_light(v1, v2, v3, x, y, z) @@ -10770,41 +10718,41 @@ def points(coordinates: npt.NDArray[np.floating], /) -> None: Draw a collection of points, each a coordinate in space at the dimension of one pixel. The purpose of this method is to provide an alternative to repeatedly - calling ``point()`` in a loop. For a large number of points, the performance of - ``points()`` will be much faster. + calling `point()` in a loop. For a large number of points, the performance of + `points()` will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each - point. There should be two or three columns for 2D or 3D points, respectively. + The `coordinates` parameter should be a numpy array with one row for each point. + There should be two or three columns for 2D or 3D points, respectively. """ return _py5sketch.points(coordinates) def pop() -> None: - """The ``pop()`` function restores the previous drawing style settings and - transformations after ``push()`` has changed them. + """The `pop()` function restores the previous drawing style settings and + transformations after `push()` has changed them. Underlying Processing method: PApplet.pop Notes ----- - The ``pop()`` function restores the previous drawing style settings and - transformations after ``push()`` has changed them. Note that these functions are + The `pop()` function restores the previous drawing style settings and + transformations after `push()` has changed them. Note that these functions are always used together. They allow you to change the style and transformation settings and later return to what you had. When a new state is started with - ``push()``, it builds on the current style and transform information. + `push()`, it builds on the current style and transform information. - ``push()`` stores information related to the current transformation state and - style settings controlled by the following functions: ``rotate()``, - ``translate()``, ``scale()``, ``fill()``, ``stroke()``, ``tint()``, - ``stroke_weight()``, ``stroke_cap()``, ``stroke_join()``, ``image_mode()``, - ``rect_mode()``, ``ellipse_mode()``, ``color_mode()``, ``text_align()``, - ``text_font()``, ``text_mode()``, ``text_size()``, and ``text_leading()``. + `push()` stores information related to the current transformation state and + style settings controlled by the following functions: `rotate()`, `translate()`, + `scale()`, `fill()`, `stroke()`, `tint()`, `stroke_weight()`, `stroke_cap()`, + `stroke_join()`, `image_mode()`, `rect_mode()`, `ellipse_mode()`, + `color_mode()`, `text_align()`, `text_font()`, `text_mode()`, `text_size()`, and + `text_leading()`. - The ``push()`` and ``pop()`` functions can be used in place of - ``push_matrix()``, ``pop_matrix()``, ``push_style()``, and ``pop_style()``. The - difference is that ``push()`` and ``pop()`` control both the transformations - (rotate, scale, translate) and the drawing styles at the same time. + The `push()` and `pop()` functions can be used in place of `push_matrix()`, + `pop_matrix()`, `push_style()`, and `pop_style()`. The difference is that + `push()` and `pop()` control both the transformations (rotate, scale, translate) + and the drawing styles at the same time. """ return _py5sketch.pop() @@ -10819,31 +10767,29 @@ def pop_matrix() -> None: Pops the current transformation matrix off the matrix stack. Understanding pushing and popping requires understanding the concept of a matrix stack. The - ``push_matrix()`` function saves the current coordinate system to the stack and - ``pop_matrix()`` restores the prior coordinate system. ``push_matrix()`` and - ``pop_matrix()`` are used in conjuction with the other transformation functions + `push_matrix()` function saves the current coordinate system to the stack and + `pop_matrix()` restores the prior coordinate system. `push_matrix()` and + `pop_matrix()` are used in conjuction with the other transformation functions and may be embedded to control the scope of the transformations. """ return _py5sketch.pop_matrix() def pop_style() -> None: - """The ``push_style()`` function saves the current style settings and - ``pop_style()`` restores the prior settings; these functions are always used - together. + """The `push_style()` function saves the current style settings and `pop_style()` + restores the prior settings; these functions are always used together. Underlying Processing method: PApplet.popStyle Notes ----- - The ``push_style()`` function saves the current style settings and - ``pop_style()`` restores the prior settings; these functions are always used - together. They allow you to change the style settings and later return to what - you had. When a new style is started with ``push_style()``, it builds on the - current style information. The ``push_style()`` and ``pop_style()`` method pairs - can be nested to provide more control (see the second example for a - demonstration.) + The `push_style()` function saves the current style settings and `pop_style()` + restores the prior settings; these functions are always used together. They + allow you to change the style settings and later return to what you had. When a + new style is started with `push_style()`, it builds on the current style + information. The `push_style()` and `pop_style()` method pairs can be nested to + provide more control (see the second example for a demonstration.) """ return _py5sketch.pop_style() @@ -10888,35 +10834,34 @@ def print_projection() -> None: def push() -> None: - """The ``push()`` function saves the current drawing style settings and - transformations, while ``pop()`` restores these settings. + """The `push()` function saves the current drawing style settings and + transformations, while `pop()` restores these settings. Underlying Processing method: PApplet.push Notes ----- - The ``push()`` function saves the current drawing style settings and - transformations, while ``pop()`` restores these settings. Note that these + The `push()` function saves the current drawing style settings and + transformations, while `pop()` restores these settings. Note that these functions are always used together. They allow you to change the style and transformation settings and later return to what you had. When a new state is - started with ``push()``, it builds on the current style and transform - information. - - ``push()`` stores information related to the current transformation state and - style settings controlled by the following functions: ``rotate()``, - ``translate()``, ``scale()``, ``fill()``, ``stroke()``, ``tint()``, - ``stroke_weight()``, ``stroke_cap()``, ``stroke_join()``, ``image_mode()``, - ``rect_mode()``, ``ellipse_mode()``, ``color_mode()``, ``text_align()``, - ``text_font()``, ``text_mode()``, ``text_size()``, and ``text_leading()``. - - The ``push()`` and ``pop()`` functions can be used in place of - ``push_matrix()``, ``pop_matrix()``, ``push_style()``, and ``pop_style()``. The - difference is that ``push()`` and ``pop()`` control both the transformations - (rotate, scale, translate) and the drawing styles at the same time. - - This method can be used as a context manager to ensure that ``pop()`` always - gets called, as shown in the last example. + started with `push()`, it builds on the current style and transform information. + + `push()` stores information related to the current transformation state and + style settings controlled by the following functions: `rotate()`, `translate()`, + `scale()`, `fill()`, `stroke()`, `tint()`, `stroke_weight()`, `stroke_cap()`, + `stroke_join()`, `image_mode()`, `rect_mode()`, `ellipse_mode()`, + `color_mode()`, `text_align()`, `text_font()`, `text_mode()`, `text_size()`, and + `text_leading()`. + + The `push()` and `pop()` functions can be used in place of `push_matrix()`, + `pop_matrix()`, `push_style()`, and `pop_style()`. The difference is that + `push()` and `pop()` control both the transformations (rotate, scale, translate) + and the drawing styles at the same time. + + This method can be used as a context manager to ensure that `pop()` always gets + called, as shown in the last example. """ return _py5sketch.push() @@ -10930,45 +10875,44 @@ def push_matrix() -> None: ----- Pushes the current transformation matrix onto the matrix stack. Understanding - ``push_matrix()`` and ``pop_matrix()`` requires understanding the concept of a - matrix stack. The ``push_matrix()`` function saves the current coordinate system - to the stack and ``pop_matrix()`` restores the prior coordinate system. - ``push_matrix()`` and ``pop_matrix()`` are used in conjuction with the other + `push_matrix()` and `pop_matrix()` requires understanding the concept of a + matrix stack. The `push_matrix()` function saves the current coordinate system + to the stack and `pop_matrix()` restores the prior coordinate system. + `push_matrix()` and `pop_matrix()` are used in conjuction with the other transformation functions and may be embedded to control the scope of the transformations. - This method can be used as a context manager to ensure that ``pop_matrix()`` + This method can be used as a context manager to ensure that `pop_matrix()` always gets called, as shown in the last example. """ return _py5sketch.push_matrix() def push_style() -> None: - """The ``push_style()`` function saves the current style settings and - ``pop_style()`` restores the prior settings. + """The `push_style()` function saves the current style settings and `pop_style()` + restores the prior settings. Underlying Processing method: PApplet.pushStyle Notes ----- - The ``push_style()`` function saves the current style settings and - ``pop_style()`` restores the prior settings. Note that these functions are - always used together. They allow you to change the style settings and later - return to what you had. When a new style is started with ``push_style()``, it - builds on the current style information. The ``push_style()`` and - ``pop_style()`` method pairs can be nested to provide more control. (See the - second example for a demonstration.) + The `push_style()` function saves the current style settings and `pop_style()` + restores the prior settings. Note that these functions are always used together. + They allow you to change the style settings and later return to what you had. + When a new style is started with `push_style()`, it builds on the current style + information. The `push_style()` and `pop_style()` method pairs can be nested to + provide more control. (See the second example for a demonstration.) The style information controlled by the following functions are included in the - style: ``fill()``, ``stroke()``, ``tint()``, ``stroke_weight()``, - ``stroke_cap()``, ``stroke_join()``, ``image_mode()``, ``rect_mode()``, - ``ellipse_mode()``, ``shape_mode()``, ``color_mode()``, ``text_align()``, - ``text_font()``, ``text_mode()``, ``text_size()``, ``text_leading()``, - ``emissive()``, ``specular()``, ``shininess()``, and ``ambient()``. + style: `fill()`, `stroke()`, `tint()`, `stroke_weight()`, `stroke_cap()`, + `stroke_join()`, `image_mode()`, `rect_mode()`, `ellipse_mode()`, + `shape_mode()`, `color_mode()`, `text_align()`, `text_font()`, `text_mode()`, + `text_size()`, `text_leading()`, `emissive()`, `specular()`, `shininess()`, and + `ambient()`. - This method can be used as a context manager to ensure that ``pop_style()`` - always gets called, as shown in the last example. + This method can be used as a context manager to ensure that `pop_style()` always + gets called, as shown in the last example. """ return _py5sketch.push_style() @@ -11056,13 +11000,13 @@ def quadratic_vertex(cx: float, cy: float, x3: float, y3: float, /) -> None: ----- Specifies vertex coordinates for quadratic Bezier curves. Each call to - ``quadratic_vertex()`` defines the position of one control point and one anchor + `quadratic_vertex()` defines the position of one control point and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time - ``quadratic_vertex()`` is used within a ``begin_shape()`` call, it must be - prefaced with a call to ``vertex()`` to set the first anchor point. This method - must be used between ``begin_shape()`` and ``end_shape()`` and only when there - is no ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version - requires rendering with ``P3D``. + `quadratic_vertex()` is used within a `begin_shape()` call, it must be prefaced + with a call to `vertex()` to set the first anchor point. This method must be + used between `begin_shape()` and `end_shape()` and only when there is no `MODE` + parameter specified to `begin_shape()`. Using the 3D version requires rendering + with `P3D`. """ pass @@ -11107,13 +11051,13 @@ def quadratic_vertex(cx: float, cy: float, cz: float, ----- Specifies vertex coordinates for quadratic Bezier curves. Each call to - ``quadratic_vertex()`` defines the position of one control point and one anchor + `quadratic_vertex()` defines the position of one control point and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time - ``quadratic_vertex()`` is used within a ``begin_shape()`` call, it must be - prefaced with a call to ``vertex()`` to set the first anchor point. This method - must be used between ``begin_shape()`` and ``end_shape()`` and only when there - is no ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version - requires rendering with ``P3D``. + `quadratic_vertex()` is used within a `begin_shape()` call, it must be prefaced + with a call to `vertex()` to set the first anchor point. This method must be + used between `begin_shape()` and `end_shape()` and only when there is no `MODE` + parameter specified to `begin_shape()`. Using the 3D version requires rendering + with `P3D`. """ pass @@ -11156,13 +11100,13 @@ def quadratic_vertex(*args): ----- Specifies vertex coordinates for quadratic Bezier curves. Each call to - ``quadratic_vertex()`` defines the position of one control point and one anchor + `quadratic_vertex()` defines the position of one control point and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time - ``quadratic_vertex()`` is used within a ``begin_shape()`` call, it must be - prefaced with a call to ``vertex()`` to set the first anchor point. This method - must be used between ``begin_shape()`` and ``end_shape()`` and only when there - is no ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version - requires rendering with ``P3D``. + `quadratic_vertex()` is used within a `begin_shape()` call, it must be prefaced + with a call to `vertex()` to set the first anchor point. This method must be + used between `begin_shape()` and `end_shape()` and only when there is no `MODE` + parameter specified to `begin_shape()`. Using the 3D version requires rendering + with `P3D`. """ return _py5sketch.quadratic_vertex(*args) @@ -11182,11 +11126,11 @@ def quadratic_vertices(coordinates: npt.NDArray[np.floating], /) -> None: ----- Create a collection of quadratic vertices. The purpose of this method is to - provide an alternative to repeatedly calling ``quadratic_vertex()`` in a loop. - For a large number of quadratic vertices, the performance of - ``quadratic_vertices()`` will be much faster. + provide an alternative to repeatedly calling `quadratic_vertex()` in a loop. For + a large number of quadratic vertices, the performance of `quadratic_vertices()` + will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each + The `coordinates` parameter should be a numpy array with one row for each quadratic vertex. The first few columns are for the control point and the next few columns are for the anchor point. There should be four or six columns for 2D or 3D points, respectively. @@ -11246,7 +11190,7 @@ def rect(a: float, b: float, c: float, d: float, /) -> None: angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, however, may be changed with - the ``rect_mode()`` function. + the `rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -11311,7 +11255,7 @@ def rect(a: float, b: float, c: float, d: float, r: float, /) -> None: angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, however, may be changed with - the ``rect_mode()`` function. + the `rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -11377,7 +11321,7 @@ def rect(a: float, b: float, c: float, d: float, tl: float, angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, however, may be changed with - the ``rect_mode()`` function. + the `rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -11441,7 +11385,7 @@ def rect(*args): angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, however, may be changed with - the ``rect_mode()`` function. + the `rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -11456,7 +11400,7 @@ def rect(*args): def rect_mode(mode: int, /) -> None: """Modifies the location from which rectangles are drawn by changing the way in - which parameters given to ``rect()`` are intepreted. + which parameters given to `rect()` are intepreted. Underlying Processing method: PApplet.rectMode @@ -11470,21 +11414,21 @@ def rect_mode(mode: int, /) -> None: ----- Modifies the location from which rectangles are drawn by changing the way in - which parameters given to ``rect()`` are intepreted. + which parameters given to `rect()` are intepreted. - The default mode is ``rect_mode(CORNER)``, which interprets the first two - parameters of ``rect()`` as the upper-left corner of the shape, while the third + The default mode is `rect_mode(CORNER)`, which interprets the first two + parameters of `rect()` as the upper-left corner of the shape, while the third and fourth parameters are its width and height. - ``rect_mode(CORNERS)`` interprets the first two parameters of ``rect()`` as the + `rect_mode(CORNERS)` interprets the first two parameters of `rect()` as the location of one corner, and the third and fourth parameters as the location of the opposite corner. - ``rect_mode(CENTER)`` interprets the first two parameters of ``rect()`` as the + `rect_mode(CENTER)` interprets the first two parameters of `rect()` as the shape's center point, while the third and fourth parameters are its width and height. - ``rect_mode(RADIUS)`` also uses the first two parameters of ``rect()`` as the + `rect_mode(RADIUS)` also uses the first two parameters of `rect()` as the shape's center point, but uses the third and fourth parameters to specify half of the shapes's width and height. @@ -11495,7 +11439,7 @@ def rect_mode(mode: int, /) -> None: def red(rgb: int, /) -> float: - """Extracts the red value from a color, scaled to match current ``color_mode()``. + """Extracts the red value from a color, scaled to match current `color_mode()`. Underlying Processing method: PApplet.red @@ -11508,36 +11452,36 @@ def red(rgb: int, /) -> float: Notes ----- - Extracts the red value from a color, scaled to match current ``color_mode()``. + Extracts the red value from a color, scaled to match current `color_mode()`. - The ``red()`` function is easy to use and understand, but it is slower than a - technique called bit shifting. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``red()`` but with greater speed by using the right - shift operator (``>>``) with a bit mask. For example, ``red(c)`` and ``c >> 16 & - 0xFF`` both extract the red value from a color variable ``c`` but the later is + The `red()` function is easy to use and understand, but it is slower than a + technique called bit shifting. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `red()` but with greater speed by using the right + shift operator (`>>`) with a bit mask. For example, `red(c)` and `c >> 16 & + 0xFF` both extract the red value from a color variable `c` but the later is faster. """ return _py5sketch.red(rgb) def redraw() -> None: - """Executes the code within ``draw()`` one time. + """Executes the code within `draw()` one time. Underlying Processing method: PApplet.redraw Notes ----- - Executes the code within ``draw()`` one time. This functions allows the program - to update the display window only when necessary, for example when an event - registered by ``mouse_pressed()`` or ``key_pressed()`` occurs. + Executes the code within `draw()` one time. This functions allows the program to + update the display window only when necessary, for example when an event + registered by `mouse_pressed()` or `key_pressed()` occurs. - In structuring a program, it only makes sense to call ``redraw()`` within events - such as ``mouse_pressed()``. This is because ``redraw()`` does not run - ``draw()`` immediately (it only sets a flag that indicates an update is needed). + In structuring a program, it only makes sense to call `redraw()` within events + such as `mouse_pressed()`. This is because `redraw()` does not run `draw()` + immediately (it only sets a flag that indicates an update is needed). - The ``redraw()`` function does not work properly when called inside ``draw()``. - To enable/disable animations, use ``loop()`` and ``no_loop()``. + The `redraw()` function does not work properly when called inside `draw()`. To + enable/disable animations, use `loop()` and `no_loop()`. """ return _py5sketch.redraw() @@ -11551,7 +11495,7 @@ def reset_matrix() -> None: ----- Replaces the current matrix with the identity matrix. The equivalent function in - OpenGL is ``gl_load_identity()``. + OpenGL is `gl_load_identity()`. """ return _py5sketch.reset_matrix() @@ -11579,8 +11523,8 @@ def reset_shader() -> None: Notes ----- - Restores the default shaders. Code that runs after ``reset_shader()`` will not - be affected by previously defined shaders. + Restores the default shaders. Code that runs after `reset_shader()` will not be + affected by previously defined shaders. """ pass @@ -11608,8 +11552,8 @@ def reset_shader(kind: int, /) -> None: Notes ----- - Restores the default shaders. Code that runs after ``reset_shader()`` will not - be affected by previously defined shaders. + Restores the default shaders. Code that runs after `reset_shader()` will not be + affected by previously defined shaders. """ pass @@ -11636,15 +11580,15 @@ def reset_shader(*args): Notes ----- - Restores the default shaders. Code that runs after ``reset_shader()`` will not - be affected by previously defined shaders. + Restores the default shaders. Code that runs after `reset_shader()` will not be + affected by previously defined shaders. """ return _py5sketch.reset_shader(*args) @overload def rotate(angle: float, /) -> None: - """Rotates the amount specified by the ``angle`` parameter. + """Rotates the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotate @@ -11674,28 +11618,28 @@ def rotate(angle: float, /) -> None: Notes ----- - Rotates the amount specified by the ``angle`` parameter. Angles must be - specified in radians (values from ``0`` to ``TWO_PI``), or they can be converted - from degrees to radians with the ``radians()`` function. + Rotates the amount specified by the `angle` parameter. Angles must be specified + in radians (values from `0` to `TWO_PI`), or they can be converted from degrees + to radians with the `radians()` function. The coordinates are always rotated around their relative position to the origin. Positive numbers rotate objects in a clockwise direction and negative numbers rotate in the couterclockwise direction. Transformations apply to everything that happens afterward, and subsequent calls to the function compound the - effect. For example, calling ``rotate(PI/2.0)`` once and then calling - ``rotate(PI/2.0)`` a second time is the same as a single ``rotate(PI)``. All - tranformations are reset when ``draw()`` begins again. + effect. For example, calling `rotate(PI/2.0)` once and then calling + `rotate(PI/2.0)` a second time is the same as a single `rotate(PI)`. All + tranformations are reset when `draw()` begins again. - Technically, ``rotate()`` multiplies the current transformation matrix by a - rotation matrix. This function can be further controlled by ``push_matrix()`` - and ``pop_matrix()``. + Technically, `rotate()` multiplies the current transformation matrix by a + rotation matrix. This function can be further controlled by `push_matrix()` and + `pop_matrix()`. """ pass @overload def rotate(angle: float, x: float, y: float, z: float, /) -> None: - """Rotates the amount specified by the ``angle`` parameter. + """Rotates the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotate @@ -11725,27 +11669,27 @@ def rotate(angle: float, x: float, y: float, z: float, /) -> None: Notes ----- - Rotates the amount specified by the ``angle`` parameter. Angles must be - specified in radians (values from ``0`` to ``TWO_PI``), or they can be converted - from degrees to radians with the ``radians()`` function. + Rotates the amount specified by the `angle` parameter. Angles must be specified + in radians (values from `0` to `TWO_PI`), or they can be converted from degrees + to radians with the `radians()` function. The coordinates are always rotated around their relative position to the origin. Positive numbers rotate objects in a clockwise direction and negative numbers rotate in the couterclockwise direction. Transformations apply to everything that happens afterward, and subsequent calls to the function compound the - effect. For example, calling ``rotate(PI/2.0)`` once and then calling - ``rotate(PI/2.0)`` a second time is the same as a single ``rotate(PI)``. All - tranformations are reset when ``draw()`` begins again. + effect. For example, calling `rotate(PI/2.0)` once and then calling + `rotate(PI/2.0)` a second time is the same as a single `rotate(PI)`. All + tranformations are reset when `draw()` begins again. - Technically, ``rotate()`` multiplies the current transformation matrix by a - rotation matrix. This function can be further controlled by ``push_matrix()`` - and ``pop_matrix()``. + Technically, `rotate()` multiplies the current transformation matrix by a + rotation matrix. This function can be further controlled by `push_matrix()` and + `pop_matrix()`. """ pass def rotate(*args): - """Rotates the amount specified by the ``angle`` parameter. + """Rotates the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotate @@ -11775,27 +11719,27 @@ def rotate(*args): Notes ----- - Rotates the amount specified by the ``angle`` parameter. Angles must be - specified in radians (values from ``0`` to ``TWO_PI``), or they can be converted - from degrees to radians with the ``radians()`` function. + Rotates the amount specified by the `angle` parameter. Angles must be specified + in radians (values from `0` to `TWO_PI`), or they can be converted from degrees + to radians with the `radians()` function. The coordinates are always rotated around their relative position to the origin. Positive numbers rotate objects in a clockwise direction and negative numbers rotate in the couterclockwise direction. Transformations apply to everything that happens afterward, and subsequent calls to the function compound the - effect. For example, calling ``rotate(PI/2.0)`` once and then calling - ``rotate(PI/2.0)`` a second time is the same as a single ``rotate(PI)``. All - tranformations are reset when ``draw()`` begins again. + effect. For example, calling `rotate(PI/2.0)` once and then calling + `rotate(PI/2.0)` a second time is the same as a single `rotate(PI)`. All + tranformations are reset when `draw()` begins again. - Technically, ``rotate()`` multiplies the current transformation matrix by a - rotation matrix. This function can be further controlled by ``push_matrix()`` - and ``pop_matrix()``. + Technically, `rotate()` multiplies the current transformation matrix by a + rotation matrix. This function can be further controlled by `push_matrix()` and + `pop_matrix()`. """ return _py5sketch.rotate(*args) def rotate_x(angle: float, /) -> None: - """Rotates around the x-axis the amount specified by the ``angle`` parameter. + """Rotates around the x-axis the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotateX @@ -11808,23 +11752,23 @@ def rotate_x(angle: float, /) -> None: Notes ----- - Rotates around the x-axis the amount specified by the ``angle`` parameter. - Angles should be specified in radians (values from ``0`` to ``TWO_PI``) or - converted from degrees to radians with the ``radians()`` function. Coordinates - are always rotated around their relative position to the origin. Positive - numbers rotate in a clockwise direction and negative numbers rotate in a - counterclockwise direction. Transformations apply to everything that happens - after and subsequent calls to the function accumulates the effect. For example, - calling ``rotate_x(PI/2)`` and then ``rotate_x(PI/2)`` is the same as - ``rotate_x(PI)``. If ``rotate_x()`` is run within the ``draw()``, the - transformation is reset when the loop begins again. This function requires using - ``P3D`` as a third parameter to ``size()`` as shown in the example. + Rotates around the x-axis the amount specified by the `angle` parameter. Angles + should be specified in radians (values from `0` to `TWO_PI`) or converted from + degrees to radians with the `radians()` function. Coordinates are always rotated + around their relative position to the origin. Positive numbers rotate in a + clockwise direction and negative numbers rotate in a counterclockwise direction. + Transformations apply to everything that happens after and subsequent calls to + the function accumulates the effect. For example, calling `rotate_x(PI/2)` and + then `rotate_x(PI/2)` is the same as `rotate_x(PI)`. If `rotate_x()` is run + within the `draw()`, the transformation is reset when the loop begins again. + This function requires using `P3D` as a third parameter to `size()` as shown in + the example. """ return _py5sketch.rotate_x(angle) def rotate_y(angle: float, /) -> None: - """Rotates around the y-axis the amount specified by the ``angle`` parameter. + """Rotates around the y-axis the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotateY @@ -11837,23 +11781,23 @@ def rotate_y(angle: float, /) -> None: Notes ----- - Rotates around the y-axis the amount specified by the ``angle`` parameter. - Angles should be specified in radians (values from ``0`` to ``TWO_PI``) or - converted from degrees to radians with the ``radians()`` function. Coordinates - are always rotated around their relative position to the origin. Positive - numbers rotate in a clockwise direction and negative numbers rotate in a - counterclockwise direction. Transformations apply to everything that happens - after and subsequent calls to the function accumulates the effect. For example, - calling ``rotate_y(PI/2)`` and then ``rotate_y(PI/2)`` is the same as - ``rotate_y(PI)``. If ``rotate_y()`` is run within the ``draw()``, the - transformation is reset when the loop begins again. This function requires using - ``P3D`` as a third parameter to ``size()`` as shown in the example. + Rotates around the y-axis the amount specified by the `angle` parameter. Angles + should be specified in radians (values from `0` to `TWO_PI`) or converted from + degrees to radians with the `radians()` function. Coordinates are always rotated + around their relative position to the origin. Positive numbers rotate in a + clockwise direction and negative numbers rotate in a counterclockwise direction. + Transformations apply to everything that happens after and subsequent calls to + the function accumulates the effect. For example, calling `rotate_y(PI/2)` and + then `rotate_y(PI/2)` is the same as `rotate_y(PI)`. If `rotate_y()` is run + within the `draw()`, the transformation is reset when the loop begins again. + This function requires using `P3D` as a third parameter to `size()` as shown in + the example. """ return _py5sketch.rotate_y(angle) def rotate_z(angle: float, /) -> None: - """Rotates around the z-axis the amount specified by the ``angle`` parameter. + """Rotates around the z-axis the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotateZ @@ -11866,17 +11810,17 @@ def rotate_z(angle: float, /) -> None: Notes ----- - Rotates around the z-axis the amount specified by the ``angle`` parameter. - Angles should be specified in radians (values from ``0`` to ``TWO_PI``) or - converted from degrees to radians with the ``radians()`` function. Coordinates - are always rotated around their relative position to the origin. Positive - numbers rotate in a clockwise direction and negative numbers rotate in a - counterclockwise direction. Transformations apply to everything that happens - after and subsequent calls to the function accumulates the effect. For example, - calling ``rotate_z(PI/2)`` and then ``rotate_z(PI/2)`` is the same as - ``rotate_z(PI)``. If ``rotate_z()`` is run within the ``draw()``, the - transformation is reset when the loop begins again. This function requires using - ``P3D`` as a third parameter to ``size()`` as shown in the example. + Rotates around the z-axis the amount specified by the `angle` parameter. Angles + should be specified in radians (values from `0` to `TWO_PI`) or converted from + degrees to radians with the `radians()` function. Coordinates are always rotated + around their relative position to the origin. Positive numbers rotate in a + clockwise direction and negative numbers rotate in a counterclockwise direction. + Transformations apply to everything that happens after and subsequent calls to + the function accumulates the effect. For example, calling `rotate_z(PI/2)` and + then `rotate_z(PI/2)` is the same as `rotate_z(PI)`. If `rotate_z()` is run + within the `draw()`, the transformation is reset when the loop begins again. + This function requires using `P3D` as a third parameter to `size()` as shown in + the example. """ return _py5sketch.rotate_z(angle) @@ -11937,15 +11881,15 @@ def scale(s: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. If ``scale()`` is called within - ``draw()``, the transformation is reset when the loop begins again. Using this - function with the ``z`` parameter requires using ``P3D`` as a parameter for - ``size()``, as shown in the third example. This function can be further - controlled with ``push_matrix()`` and ``pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. If `scale()` is called within + `draw()`, the transformation is reset when the loop begins again. Using this + function with the `z` parameter requires using `P3D` as a parameter for + `size()`, as shown in the third example. This function can be further controlled + with `push_matrix()` and `pop_matrix()`. """ pass @@ -11987,15 +11931,15 @@ def scale(x: float, y: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. If ``scale()`` is called within - ``draw()``, the transformation is reset when the loop begins again. Using this - function with the ``z`` parameter requires using ``P3D`` as a parameter for - ``size()``, as shown in the third example. This function can be further - controlled with ``push_matrix()`` and ``pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. If `scale()` is called within + `draw()`, the transformation is reset when the loop begins again. Using this + function with the `z` parameter requires using `P3D` as a parameter for + `size()`, as shown in the third example. This function can be further controlled + with `push_matrix()` and `pop_matrix()`. """ pass @@ -12037,15 +11981,15 @@ def scale(x: float, y: float, z: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. If ``scale()`` is called within - ``draw()``, the transformation is reset when the loop begins again. Using this - function with the ``z`` parameter requires using ``P3D`` as a parameter for - ``size()``, as shown in the third example. This function can be further - controlled with ``push_matrix()`` and ``pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. If `scale()` is called within + `draw()`, the transformation is reset when the loop begins again. Using this + function with the `z` parameter requires using `P3D` as a parameter for + `size()`, as shown in the third example. This function can be further controlled + with `push_matrix()` and `pop_matrix()`. """ pass @@ -12086,15 +12030,15 @@ def scale(*args): Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. If ``scale()`` is called within - ``draw()``, the transformation is reset when the loop begins again. Using this - function with the ``z`` parameter requires using ``P3D`` as a parameter for - ``size()``, as shown in the third example. This function can be further - controlled with ``push_matrix()`` and ``pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. If `scale()` is called within + `draw()`, the transformation is reset when the loop begins again. Using this + function with the `z` parameter requires using `P3D` as a parameter for + `size()`, as shown in the third example. This function can be further controlled + with `push_matrix()` and `pop_matrix()`. """ return _py5sketch.scale(*args) @@ -12348,15 +12292,164 @@ def second() -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``second()`` function + Py5 communicates with the clock on your computer. The `second()` function returns the current second as a value from 0 - 59. """ return Sketch.second() +@overload +def set_pixels(x: int, y: int, c: int, /) -> None: + """Changes the color of any pixel or writes an image directly into the drawing + surface. + + Underlying Processing method: Sketch.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Sketch window + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the drawing + surface. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `image_mode()`. + + Setting the color of a single pixel with `py5.set_pixels(x, y)` is easy, but not + as fast as putting the data directly into `pixels[]`. The equivalent statement + to `py5.set_pixels(x, y, 0)` using `pixels[]` is `py5.pixels[y*py5.width+x] = + 0`. See the reference for `pixels[]` for more information. + """ + pass + + +@overload +def set_pixels(x: int, y: int, img: Py5Image, /) -> None: + """Changes the color of any pixel or writes an image directly into the drawing + surface. + + Underlying Processing method: Sketch.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Sketch window + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the drawing + surface. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `image_mode()`. + + Setting the color of a single pixel with `py5.set_pixels(x, y)` is easy, but not + as fast as putting the data directly into `pixels[]`. The equivalent statement + to `py5.set_pixels(x, y, 0)` using `pixels[]` is `py5.pixels[y*py5.width+x] = + 0`. See the reference for `pixels[]` for more information. + """ + pass + + +def set_pixels(*args): + """Changes the color of any pixel or writes an image directly into the drawing + surface. + + Underlying Processing method: Sketch.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Sketch window + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the drawing + surface. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `image_mode()`. + + Setting the color of a single pixel with `py5.set_pixels(x, y)` is easy, but not + as fast as putting the data directly into `pixels[]`. The equivalent statement + to `py5.set_pixels(x, y, 0)` using `pixels[]` is `py5.pixels[y*py5.width+x] = + 0`. See the reference for `pixels[]` for more information. + """ + return _py5sketch.set_pixels(*args) + + @overload def set_matrix(source: npt.NDArray[np.floating], /) -> None: - """Set the current matrix to the one specified through the parameter ``source``. + """Set the current matrix to the one specified through the parameter `source`. Underlying Processing method: PApplet.setMatrix @@ -12369,16 +12462,16 @@ def set_matrix(source: npt.NDArray[np.floating], /) -> None: Notes ----- - Set the current matrix to the one specified through the parameter ``source``. - Inside the Processing code it will call ``reset_matrix()`` followed by - ``apply_matrix()``. This will be very slow because ``apply_matrix()`` will try - to calculate the inverse of the transform, so avoid it whenever possible. + Set the current matrix to the one specified through the parameter `source`. + Inside the Processing code it will call `reset_matrix()` followed by + `apply_matrix()`. This will be very slow because `apply_matrix()` will try to + calculate the inverse of the transform, so avoid it whenever possible. """ pass def set_matrix(*args): - """Set the current matrix to the one specified through the parameter ``source``. + """Set the current matrix to the one specified through the parameter `source`. Underlying Processing method: PApplet.setMatrix @@ -12391,10 +12484,10 @@ def set_matrix(*args): Notes ----- - Set the current matrix to the one specified through the parameter ``source``. - Inside the Processing code it will call ``reset_matrix()`` followed by - ``apply_matrix()``. This will be very slow because ``apply_matrix()`` will try - to calculate the inverse of the transform, so avoid it whenever possible. + Set the current matrix to the one specified through the parameter `source`. + Inside the Processing code it will call `reset_matrix()` followed by + `apply_matrix()`. This will be very slow because `apply_matrix()` will try to + calculate the inverse of the transform, so avoid it whenever possible. """ return _py5sketch.set_matrix(*args) @@ -12425,8 +12518,8 @@ def shader(shader: Py5Shader, /) -> None: Notes ----- - Applies the shader specified by the parameters. It's compatible with the ``P2D`` - and ``P3D`` renderers, but not with the default renderer. + Applies the shader specified by the parameters. It's compatible with the `P2D` + and `P3D` renderers, but not with the default renderer. """ pass @@ -12457,8 +12550,8 @@ def shader(shader: Py5Shader, kind: int, /) -> None: Notes ----- - Applies the shader specified by the parameters. It's compatible with the ``P2D`` - and ``P3D`` renderers, but not with the default renderer. + Applies the shader specified by the parameters. It's compatible with the `P2D` + and `P3D` renderers, but not with the default renderer. """ pass @@ -12488,8 +12581,8 @@ def shader(*args): Notes ----- - Applies the shader specified by the parameters. It's compatible with the ``P2D`` - and ``P3D`` renderers, but not with the default renderer. + Applies the shader specified by the parameters. It's compatible with the `P2D` + and `P3D` renderers, but not with the default renderer. """ return _py5sketch.shader(*args) @@ -12538,11 +12631,11 @@ def shape(shape: Py5Shape, /) -> None: Draws shapes to the display window. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and custom- - created shapes. The ``shape`` parameter specifies the shape to display and the + created shapes. The `shape` parameter specifies the shape to display and the coordinate parameters define the location of the shape from its upper-left - corner. The shape is displayed at its original size unless the ``c`` and ``d`` - parameters specify a different size. The ``shape_mode()`` function can be used - to change the way these parameters are interpreted. + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `shape_mode()` function can be used to + change the way these parameters are interpreted. """ pass @@ -12591,11 +12684,11 @@ def shape(shape: Py5Shape, x: float, y: float, /) -> None: Draws shapes to the display window. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and custom- - created shapes. The ``shape`` parameter specifies the shape to display and the + created shapes. The `shape` parameter specifies the shape to display and the coordinate parameters define the location of the shape from its upper-left - corner. The shape is displayed at its original size unless the ``c`` and ``d`` - parameters specify a different size. The ``shape_mode()`` function can be used - to change the way these parameters are interpreted. + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `shape_mode()` function can be used to + change the way these parameters are interpreted. """ pass @@ -12644,11 +12737,11 @@ def shape(shape: Py5Shape, a: float, b: float, c: float, d: float, /) -> None: Draws shapes to the display window. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and custom- - created shapes. The ``shape`` parameter specifies the shape to display and the + created shapes. The `shape` parameter specifies the shape to display and the coordinate parameters define the location of the shape from its upper-left - corner. The shape is displayed at its original size unless the ``c`` and ``d`` - parameters specify a different size. The ``shape_mode()`` function can be used - to change the way these parameters are interpreted. + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `shape_mode()` function can be used to + change the way these parameters are interpreted. """ pass @@ -12696,11 +12789,11 @@ def shape(*args): Draws shapes to the display window. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and custom- - created shapes. The ``shape`` parameter specifies the shape to display and the + created shapes. The `shape` parameter specifies the shape to display and the coordinate parameters define the location of the shape from its upper-left - corner. The shape is displayed at its original size unless the ``c`` and ``d`` - parameters specify a different size. The ``shape_mode()`` function can be used - to change the way these parameters are interpreted. + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `shape_mode()` function can be used to + change the way these parameters are interpreted. """ return _py5sketch.shape(*args) @@ -12720,22 +12813,20 @@ def shape_mode(mode: int, /) -> None: ----- Modifies the location from which shapes draw. The default mode is - ``shape_mode(CORNER)``, which specifies the location to be the upper left corner - of the shape and uses the third and fourth parameters of ``shape()`` to specify - the width and height. The syntax ``shape_mode(CORNERS)`` uses the first and - second parameters of ``shape()`` to set the location of one corner and uses the - third and fourth parameters to set the opposite corner. The syntax - ``shape_mode(CENTER)`` draws the shape from its center point and uses the third - and forth parameters of ``shape()`` to specify the width and height. The - parameter must be written in ALL CAPS because Python is a case sensitive - language. + `shape_mode(CORNER)`, which specifies the location to be the upper left corner + of the shape and uses the third and fourth parameters of `shape()` to specify + the width and height. The syntax `shape_mode(CORNERS)` uses the first and second + parameters of `shape()` to set the location of one corner and uses the third and + fourth parameters to set the opposite corner. The syntax `shape_mode(CENTER)` + draws the shape from its center point and uses the third and forth parameters of + `shape()` to specify the width and height. The parameter must be written in ALL + CAPS because Python is a case sensitive language. """ return _py5sketch.shape_mode(mode) def shear_x(angle: float, /) -> None: - """Shears a shape around the x-axis the amount specified by the ``angle`` - parameter. + """Shears a shape around the x-axis the amount specified by the `angle` parameter. Underlying Processing method: PApplet.shearX @@ -12748,26 +12839,25 @@ def shear_x(angle: float, /) -> None: Notes ----- - Shears a shape around the x-axis the amount specified by the ``angle`` - parameter. Angles should be specified in radians (values from ``0`` to - ``TWO_PI``) or converted to radians with the ``radians()`` function. Objects are - always sheared around their relative position to the origin and positive numbers - shear objects in a clockwise direction. Transformations apply to everything that - happens after and subsequent calls to the function accumulates the effect. For - example, calling ``shear_x(PI/2)`` and then ``shear_x(PI/2)`` is the same as - ``shear_x(PI)``. If ``shear_x()`` is called within the ``draw()``, the - transformation is reset when the loop begins again. + Shears a shape around the x-axis the amount specified by the `angle` parameter. + Angles should be specified in radians (values from `0` to `TWO_PI`) or converted + to radians with the `radians()` function. Objects are always sheared around + their relative position to the origin and positive numbers shear objects in a + clockwise direction. Transformations apply to everything that happens after and + subsequent calls to the function accumulates the effect. For example, calling + `shear_x(PI/2)` and then `shear_x(PI/2)` is the same as `shear_x(PI)`. If + `shear_x()` is called within the `draw()`, the transformation is reset when the + loop begins again. - Technically, ``shear_x()`` multiplies the current transformation matrix by a - rotation matrix. This function can be further controlled by the - ``push_matrix()`` and ``pop_matrix()`` functions. + Technically, `shear_x()` multiplies the current transformation matrix by a + rotation matrix. This function can be further controlled by the `push_matrix()` + and `pop_matrix()` functions. """ return _py5sketch.shear_x(angle) def shear_y(angle: float, /) -> None: - """Shears a shape around the y-axis the amount specified by the ``angle`` - parameter. + """Shears a shape around the y-axis the amount specified by the `angle` parameter. Underlying Processing method: PApplet.shearY @@ -12780,19 +12870,19 @@ def shear_y(angle: float, /) -> None: Notes ----- - Shears a shape around the y-axis the amount specified by the ``angle`` - parameter. Angles should be specified in radians (values from ``0`` to - ``TWO_PI``) or converted to radians with the ``radians()`` function. Objects are - always sheared around their relative position to the origin and positive numbers - shear objects in a clockwise direction. Transformations apply to everything that - happens after and subsequent calls to the function accumulates the effect. For - example, calling ``shear_y(PI/2)`` and then ``shear_y(PI/2)`` is the same as - ``shear_y(PI)``. If ``shear_y()`` is called within the ``draw()``, the - transformation is reset when the loop begins again. + Shears a shape around the y-axis the amount specified by the `angle` parameter. + Angles should be specified in radians (values from `0` to `TWO_PI`) or converted + to radians with the `radians()` function. Objects are always sheared around + their relative position to the origin and positive numbers shear objects in a + clockwise direction. Transformations apply to everything that happens after and + subsequent calls to the function accumulates the effect. For example, calling + `shear_y(PI/2)` and then `shear_y(PI/2)` is the same as `shear_y(PI)`. If + `shear_y()` is called within the `draw()`, the transformation is reset when the + loop begins again. - Technically, ``shear_y()`` multiplies the current transformation matrix by a - rotation matrix. This function can be further controlled by the - ``push_matrix()`` and ``pop_matrix()`` functions. + Technically, `shear_y()` multiplies the current transformation matrix by a + rotation matrix. This function can be further controlled by the `push_matrix()` + and `pop_matrix()` functions. """ return _py5sketch.shear_y(angle) @@ -12812,8 +12902,8 @@ def shininess(shine: float, /) -> None: ----- Sets the amount of gloss in the surface of shapes. Use in combination with - ``ambient()``, ``specular()``, and ``emissive()`` to set the material properties - of shapes. + `ambient()`, `specular()`, and `emissive()` to set the material properties of + shapes. """ return _py5sketch.shininess(shine) @@ -12852,68 +12942,67 @@ def size(width: int, height: int, /) -> None: ----- Defines the dimension of the display window width and height in units of pixels. - This is intended to be called from the ``settings()`` function. + This is intended to be called from the `settings()` function. When programming in module mode and imported mode, py5 will allow calls to - ``size()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `size()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``size()``, or calls to - ``full_screen()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls - to those functions must be at the very beginning of ``setup()``, before any - other Python code (but comments are ok). This feature is not available when - programming in class mode. - - The built-in variables ``width`` and ``height`` are set by the parameters passed - to this function. For example, running ``size(640, 480)`` will assign 640 to the - ``width`` variable and 480 to the height ``variable``. If ``size()`` is not - used, the window will be given a default size of 100 x 100 pixels. - - The ``size()`` function can only be used once inside a Sketch, and it cannot be + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `size()`, or calls to + `full_screen()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + The built-in variables `width` and `height` are set by the parameters passed to + this function. For example, running `size(640, 480)` will assign 640 to the + `width` variable and 480 to the height `variable`. If `size()` is not used, the + window will be given a default size of 100 x 100 pixels. + + The `size()` function can only be used once inside a Sketch, and it cannot be used for resizing. - To run a Sketch at the full dimensions of a screen, use the ``full_screen()`` - function, rather than the older way of using ``size(display_width, - display_height)``. + To run a Sketch at the full dimensions of a screen, use the `full_screen()` + function, rather than the older way of using `size(display_width, + display_height)`. The maximum width and height is limited by your operating system, and is usually the width and height of your actual screen. On some machines it may simply be the number of pixels on your current screen, meaning that a screen of 800 x 600 - could support ``size(1600, 300)``, since that is the same number of pixels. This + could support `size(1600, 300)`, since that is the same number of pixels. This varies widely, so you'll have to try different rendering modes and sizes until you get what you're looking for. If you need something larger, use - ``create_graphics`` to create a non-visible drawing surface. + `create_graphics` to create a non-visible drawing surface. The minimum width and height is around 100 pixels in each direction. This is the smallest that is supported across Windows, macOS, and Linux. We enforce the minimum size so that Sketches will run identically on different machines. - The ``renderer`` parameter selects which rendering engine to use. For example, - if you will be drawing 3D shapes, use ``P3D``. In addition to the default - renderer, other renderers are: + The `renderer` parameter selects which rendering engine to use. For example, if + you will be drawing 3D shapes, use `P3D`. In addition to the default renderer, + other renderers are: - * ``P2D`` (Processing 2D): 2D graphics renderer that makes use of OpenGL- + * `P2D` (Processing 2D): 2D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``P3D`` (Processing 3D): 3D graphics renderer that makes use of OpenGL- + * `P3D` (Processing 3D): 3D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``FX2D`` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for + * `FX2D` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for some applications, but has some compatibility quirks. - * ``PDF``: The ``PDF`` renderer draws 2D graphics directly to an Acrobat PDF - file. This produces excellent results when you need vector shapes for high- - resolution output or printing. - * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This - is great for importing into other vector programs or using for digital - fabrication. - - When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you - must use the ``path`` parameter to specify the file to write the output to. No - window will open while the Sketch is running. You must also call - ``exit_sketch()`` to exit the Sketch and write the completed output to the file. - Without this call, the Sketch will not exit and the output file will be empty. - If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` - renderer and the strategy described in ``begin_raw()``. + * `PDF`: The `PDF` renderer draws 2D graphics directly to an Acrobat PDF file. + This produces excellent results when you need vector shapes for high-resolution + output or printing. + * `SVG`: The `SVG` renderer draws 2D graphics directly to an SVG file. This is + great for importing into other vector programs or using for digital fabrication. + + When using the `PDF` and `SVG` renderers with the `size()` method, you must use + the `path` parameter to specify the file to write the output to. No window will + open while the Sketch is running. You must also call `exit_sketch()` to exit the + Sketch and write the completed output to the file. Without this call, the Sketch + will not exit and the output file will be empty. If you would like to draw 3D + objects to a PDF or SVG file, use the `P3D` renderer and the strategy described + in `begin_raw()`. """ pass @@ -12952,68 +13041,67 @@ def size(width: int, height: int, renderer: str, /) -> None: ----- Defines the dimension of the display window width and height in units of pixels. - This is intended to be called from the ``settings()`` function. + This is intended to be called from the `settings()` function. When programming in module mode and imported mode, py5 will allow calls to - ``size()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `size()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``size()``, or calls to - ``full_screen()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls - to those functions must be at the very beginning of ``setup()``, before any - other Python code (but comments are ok). This feature is not available when - programming in class mode. - - The built-in variables ``width`` and ``height`` are set by the parameters passed - to this function. For example, running ``size(640, 480)`` will assign 640 to the - ``width`` variable and 480 to the height ``variable``. If ``size()`` is not - used, the window will be given a default size of 100 x 100 pixels. - - The ``size()`` function can only be used once inside a Sketch, and it cannot be + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `size()`, or calls to + `full_screen()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + The built-in variables `width` and `height` are set by the parameters passed to + this function. For example, running `size(640, 480)` will assign 640 to the + `width` variable and 480 to the height `variable`. If `size()` is not used, the + window will be given a default size of 100 x 100 pixels. + + The `size()` function can only be used once inside a Sketch, and it cannot be used for resizing. - To run a Sketch at the full dimensions of a screen, use the ``full_screen()`` - function, rather than the older way of using ``size(display_width, - display_height)``. + To run a Sketch at the full dimensions of a screen, use the `full_screen()` + function, rather than the older way of using `size(display_width, + display_height)`. The maximum width and height is limited by your operating system, and is usually the width and height of your actual screen. On some machines it may simply be the number of pixels on your current screen, meaning that a screen of 800 x 600 - could support ``size(1600, 300)``, since that is the same number of pixels. This + could support `size(1600, 300)`, since that is the same number of pixels. This varies widely, so you'll have to try different rendering modes and sizes until you get what you're looking for. If you need something larger, use - ``create_graphics`` to create a non-visible drawing surface. + `create_graphics` to create a non-visible drawing surface. The minimum width and height is around 100 pixels in each direction. This is the smallest that is supported across Windows, macOS, and Linux. We enforce the minimum size so that Sketches will run identically on different machines. - The ``renderer`` parameter selects which rendering engine to use. For example, - if you will be drawing 3D shapes, use ``P3D``. In addition to the default - renderer, other renderers are: + The `renderer` parameter selects which rendering engine to use. For example, if + you will be drawing 3D shapes, use `P3D`. In addition to the default renderer, + other renderers are: - * ``P2D`` (Processing 2D): 2D graphics renderer that makes use of OpenGL- + * `P2D` (Processing 2D): 2D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``P3D`` (Processing 3D): 3D graphics renderer that makes use of OpenGL- + * `P3D` (Processing 3D): 3D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``FX2D`` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for + * `FX2D` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for some applications, but has some compatibility quirks. - * ``PDF``: The ``PDF`` renderer draws 2D graphics directly to an Acrobat PDF - file. This produces excellent results when you need vector shapes for high- - resolution output or printing. - * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This - is great for importing into other vector programs or using for digital - fabrication. - - When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you - must use the ``path`` parameter to specify the file to write the output to. No - window will open while the Sketch is running. You must also call - ``exit_sketch()`` to exit the Sketch and write the completed output to the file. - Without this call, the Sketch will not exit and the output file will be empty. - If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` - renderer and the strategy described in ``begin_raw()``. + * `PDF`: The `PDF` renderer draws 2D graphics directly to an Acrobat PDF file. + This produces excellent results when you need vector shapes for high-resolution + output or printing. + * `SVG`: The `SVG` renderer draws 2D graphics directly to an SVG file. This is + great for importing into other vector programs or using for digital fabrication. + + When using the `PDF` and `SVG` renderers with the `size()` method, you must use + the `path` parameter to specify the file to write the output to. No window will + open while the Sketch is running. You must also call `exit_sketch()` to exit the + Sketch and write the completed output to the file. Without this call, the Sketch + will not exit and the output file will be empty. If you would like to draw 3D + objects to a PDF or SVG file, use the `P3D` renderer and the strategy described + in `begin_raw()`. """ pass @@ -13052,68 +13140,67 @@ def size(width: int, height: int, renderer: str, path: str, /) -> None: ----- Defines the dimension of the display window width and height in units of pixels. - This is intended to be called from the ``settings()`` function. + This is intended to be called from the `settings()` function. When programming in module mode and imported mode, py5 will allow calls to - ``size()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `size()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``size()``, or calls to - ``full_screen()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls - to those functions must be at the very beginning of ``setup()``, before any - other Python code (but comments are ok). This feature is not available when - programming in class mode. - - The built-in variables ``width`` and ``height`` are set by the parameters passed - to this function. For example, running ``size(640, 480)`` will assign 640 to the - ``width`` variable and 480 to the height ``variable``. If ``size()`` is not - used, the window will be given a default size of 100 x 100 pixels. - - The ``size()`` function can only be used once inside a Sketch, and it cannot be + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `size()`, or calls to + `full_screen()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + The built-in variables `width` and `height` are set by the parameters passed to + this function. For example, running `size(640, 480)` will assign 640 to the + `width` variable and 480 to the height `variable`. If `size()` is not used, the + window will be given a default size of 100 x 100 pixels. + + The `size()` function can only be used once inside a Sketch, and it cannot be used for resizing. - To run a Sketch at the full dimensions of a screen, use the ``full_screen()`` - function, rather than the older way of using ``size(display_width, - display_height)``. + To run a Sketch at the full dimensions of a screen, use the `full_screen()` + function, rather than the older way of using `size(display_width, + display_height)`. The maximum width and height is limited by your operating system, and is usually the width and height of your actual screen. On some machines it may simply be the number of pixels on your current screen, meaning that a screen of 800 x 600 - could support ``size(1600, 300)``, since that is the same number of pixels. This + could support `size(1600, 300)`, since that is the same number of pixels. This varies widely, so you'll have to try different rendering modes and sizes until you get what you're looking for. If you need something larger, use - ``create_graphics`` to create a non-visible drawing surface. + `create_graphics` to create a non-visible drawing surface. The minimum width and height is around 100 pixels in each direction. This is the smallest that is supported across Windows, macOS, and Linux. We enforce the minimum size so that Sketches will run identically on different machines. - The ``renderer`` parameter selects which rendering engine to use. For example, - if you will be drawing 3D shapes, use ``P3D``. In addition to the default - renderer, other renderers are: + The `renderer` parameter selects which rendering engine to use. For example, if + you will be drawing 3D shapes, use `P3D`. In addition to the default renderer, + other renderers are: - * ``P2D`` (Processing 2D): 2D graphics renderer that makes use of OpenGL- + * `P2D` (Processing 2D): 2D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``P3D`` (Processing 3D): 3D graphics renderer that makes use of OpenGL- + * `P3D` (Processing 3D): 3D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``FX2D`` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for + * `FX2D` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for some applications, but has some compatibility quirks. - * ``PDF``: The ``PDF`` renderer draws 2D graphics directly to an Acrobat PDF - file. This produces excellent results when you need vector shapes for high- - resolution output or printing. - * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This - is great for importing into other vector programs or using for digital - fabrication. - - When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you - must use the ``path`` parameter to specify the file to write the output to. No - window will open while the Sketch is running. You must also call - ``exit_sketch()`` to exit the Sketch and write the completed output to the file. - Without this call, the Sketch will not exit and the output file will be empty. - If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` - renderer and the strategy described in ``begin_raw()``. + * `PDF`: The `PDF` renderer draws 2D graphics directly to an Acrobat PDF file. + This produces excellent results when you need vector shapes for high-resolution + output or printing. + * `SVG`: The `SVG` renderer draws 2D graphics directly to an SVG file. This is + great for importing into other vector programs or using for digital fabrication. + + When using the `PDF` and `SVG` renderers with the `size()` method, you must use + the `path` parameter to specify the file to write the output to. No window will + open while the Sketch is running. You must also call `exit_sketch()` to exit the + Sketch and write the completed output to the file. Without this call, the Sketch + will not exit and the output file will be empty. If you would like to draw 3D + objects to a PDF or SVG file, use the `P3D` renderer and the strategy described + in `begin_raw()`. """ pass @@ -13151,68 +13238,67 @@ def size(*args): ----- Defines the dimension of the display window width and height in units of pixels. - This is intended to be called from the ``settings()`` function. + This is intended to be called from the `settings()` function. When programming in module mode and imported mode, py5 will allow calls to - ``size()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `size()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``size()``, or calls to - ``full_screen()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls - to those functions must be at the very beginning of ``setup()``, before any - other Python code (but comments are ok). This feature is not available when - programming in class mode. - - The built-in variables ``width`` and ``height`` are set by the parameters passed - to this function. For example, running ``size(640, 480)`` will assign 640 to the - ``width`` variable and 480 to the height ``variable``. If ``size()`` is not - used, the window will be given a default size of 100 x 100 pixels. - - The ``size()`` function can only be used once inside a Sketch, and it cannot be + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `size()`, or calls to + `full_screen()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + The built-in variables `width` and `height` are set by the parameters passed to + this function. For example, running `size(640, 480)` will assign 640 to the + `width` variable and 480 to the height `variable`. If `size()` is not used, the + window will be given a default size of 100 x 100 pixels. + + The `size()` function can only be used once inside a Sketch, and it cannot be used for resizing. - To run a Sketch at the full dimensions of a screen, use the ``full_screen()`` - function, rather than the older way of using ``size(display_width, - display_height)``. + To run a Sketch at the full dimensions of a screen, use the `full_screen()` + function, rather than the older way of using `size(display_width, + display_height)`. The maximum width and height is limited by your operating system, and is usually the width and height of your actual screen. On some machines it may simply be the number of pixels on your current screen, meaning that a screen of 800 x 600 - could support ``size(1600, 300)``, since that is the same number of pixels. This + could support `size(1600, 300)`, since that is the same number of pixels. This varies widely, so you'll have to try different rendering modes and sizes until you get what you're looking for. If you need something larger, use - ``create_graphics`` to create a non-visible drawing surface. + `create_graphics` to create a non-visible drawing surface. The minimum width and height is around 100 pixels in each direction. This is the smallest that is supported across Windows, macOS, and Linux. We enforce the minimum size so that Sketches will run identically on different machines. - The ``renderer`` parameter selects which rendering engine to use. For example, - if you will be drawing 3D shapes, use ``P3D``. In addition to the default - renderer, other renderers are: + The `renderer` parameter selects which rendering engine to use. For example, if + you will be drawing 3D shapes, use `P3D`. In addition to the default renderer, + other renderers are: - * ``P2D`` (Processing 2D): 2D graphics renderer that makes use of OpenGL- + * `P2D` (Processing 2D): 2D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``P3D`` (Processing 3D): 3D graphics renderer that makes use of OpenGL- + * `P3D` (Processing 3D): 3D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``FX2D`` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for + * `FX2D` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for some applications, but has some compatibility quirks. - * ``PDF``: The ``PDF`` renderer draws 2D graphics directly to an Acrobat PDF - file. This produces excellent results when you need vector shapes for high- - resolution output or printing. - * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This - is great for importing into other vector programs or using for digital - fabrication. - - When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you - must use the ``path`` parameter to specify the file to write the output to. No - window will open while the Sketch is running. You must also call - ``exit_sketch()`` to exit the Sketch and write the completed output to the file. - Without this call, the Sketch will not exit and the output file will be empty. - If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` - renderer and the strategy described in ``begin_raw()``. + * `PDF`: The `PDF` renderer draws 2D graphics directly to an Acrobat PDF file. + This produces excellent results when you need vector shapes for high-resolution + output or printing. + * `SVG`: The `SVG` renderer draws 2D graphics directly to an SVG file. This is + great for importing into other vector programs or using for digital fabrication. + + When using the `PDF` and `SVG` renderers with the `size()` method, you must use + the `path` parameter to specify the file to write the output to. No window will + open while the Sketch is running. You must also call `exit_sketch()` to exit the + Sketch and write the completed output to the file. Without this call, the Sketch + will not exit and the output file will be empty. If you would like to draw 3D + objects to a PDF or SVG file, use the `P3D` renderer and the strategy described + in `begin_raw()`. """ return _py5sketch.size(*args) @@ -13241,35 +13327,34 @@ def smooth() -> None: ----- Draws all geometry with smooth (anti-aliased) edges. This behavior is the - default, so ``smooth()`` only needs to be used when a program needs to set the - smoothing in a different way. The ``level`` parameter increases the amount of + default, so `smooth()` only needs to be used when a program needs to set the + smoothing in a different way. The `level` parameter increases the amount of smoothness. This is the level of over sampling applied to the graphics buffer. - With the ``P2D`` and ``P3D`` renderers, ``smooth(2)`` is the default, this is - called "2x anti-aliasing." The code ``smooth(4)`` is used for 4x anti-aliasing - and ``smooth(8)`` is specified for "8x anti-aliasing." The maximum anti-aliasing - level is determined by the hardware of the machine that is running the software, - so ``smooth(4)`` and ``smooth(8)`` will not work with every computer. + With the `P2D` and `P3D` renderers, `smooth(2)` is the default, this is called + "2x anti-aliasing." The code `smooth(4)` is used for 4x anti-aliasing and + `smooth(8)` is specified for "8x anti-aliasing." The maximum anti-aliasing level + is determined by the hardware of the machine that is running the software, so + `smooth(4)` and `smooth(8)` will not work with every computer. - The default renderer uses ``smooth(3)`` by default. This is bicubic smoothing. - The other option for the default renderer is ``smooth(2)``, which is bilinear + The default renderer uses `smooth(3)` by default. This is bicubic smoothing. The + other option for the default renderer is `smooth(2)`, which is bilinear smoothing. - The ``smooth()`` function can only be set once within a Sketch. It is intended - to be called from the ``settings()`` function. The ``no_smooth()`` function - follows the same rules. + The `smooth()` function can only be set once within a Sketch. It is intended to + be called from the `settings()` function. The `no_smooth()` function follows the + same rules. When programming in module mode and imported mode, py5 will allow calls to - ``smooth()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `smooth()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``smooth()``, or calls to - ``size()``, ``full_screen()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `smooth()`, or calls to `size()`, + `full_screen()`, `no_smooth()`, or `pixel_density()`. Calls to those functions + must be at the very beginning of `setup()`, before any other Python code (but + comments are ok). This feature is not available when programming in class mode. """ pass @@ -13298,35 +13383,34 @@ def smooth(level: int, /) -> None: ----- Draws all geometry with smooth (anti-aliased) edges. This behavior is the - default, so ``smooth()`` only needs to be used when a program needs to set the - smoothing in a different way. The ``level`` parameter increases the amount of + default, so `smooth()` only needs to be used when a program needs to set the + smoothing in a different way. The `level` parameter increases the amount of smoothness. This is the level of over sampling applied to the graphics buffer. - With the ``P2D`` and ``P3D`` renderers, ``smooth(2)`` is the default, this is - called "2x anti-aliasing." The code ``smooth(4)`` is used for 4x anti-aliasing - and ``smooth(8)`` is specified for "8x anti-aliasing." The maximum anti-aliasing - level is determined by the hardware of the machine that is running the software, - so ``smooth(4)`` and ``smooth(8)`` will not work with every computer. + With the `P2D` and `P3D` renderers, `smooth(2)` is the default, this is called + "2x anti-aliasing." The code `smooth(4)` is used for 4x anti-aliasing and + `smooth(8)` is specified for "8x anti-aliasing." The maximum anti-aliasing level + is determined by the hardware of the machine that is running the software, so + `smooth(4)` and `smooth(8)` will not work with every computer. - The default renderer uses ``smooth(3)`` by default. This is bicubic smoothing. - The other option for the default renderer is ``smooth(2)``, which is bilinear + The default renderer uses `smooth(3)` by default. This is bicubic smoothing. The + other option for the default renderer is `smooth(2)`, which is bilinear smoothing. - The ``smooth()`` function can only be set once within a Sketch. It is intended - to be called from the ``settings()`` function. The ``no_smooth()`` function - follows the same rules. + The `smooth()` function can only be set once within a Sketch. It is intended to + be called from the `settings()` function. The `no_smooth()` function follows the + same rules. When programming in module mode and imported mode, py5 will allow calls to - ``smooth()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `smooth()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``smooth()``, or calls to - ``size()``, ``full_screen()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `smooth()`, or calls to `size()`, + `full_screen()`, `no_smooth()`, or `pixel_density()`. Calls to those functions + must be at the very beginning of `setup()`, before any other Python code (but + comments are ok). This feature is not available when programming in class mode. """ pass @@ -13354,35 +13438,34 @@ def smooth(*args): ----- Draws all geometry with smooth (anti-aliased) edges. This behavior is the - default, so ``smooth()`` only needs to be used when a program needs to set the - smoothing in a different way. The ``level`` parameter increases the amount of + default, so `smooth()` only needs to be used when a program needs to set the + smoothing in a different way. The `level` parameter increases the amount of smoothness. This is the level of over sampling applied to the graphics buffer. - With the ``P2D`` and ``P3D`` renderers, ``smooth(2)`` is the default, this is - called "2x anti-aliasing." The code ``smooth(4)`` is used for 4x anti-aliasing - and ``smooth(8)`` is specified for "8x anti-aliasing." The maximum anti-aliasing - level is determined by the hardware of the machine that is running the software, - so ``smooth(4)`` and ``smooth(8)`` will not work with every computer. + With the `P2D` and `P3D` renderers, `smooth(2)` is the default, this is called + "2x anti-aliasing." The code `smooth(4)` is used for 4x anti-aliasing and + `smooth(8)` is specified for "8x anti-aliasing." The maximum anti-aliasing level + is determined by the hardware of the machine that is running the software, so + `smooth(4)` and `smooth(8)` will not work with every computer. - The default renderer uses ``smooth(3)`` by default. This is bicubic smoothing. - The other option for the default renderer is ``smooth(2)``, which is bilinear + The default renderer uses `smooth(3)` by default. This is bicubic smoothing. The + other option for the default renderer is `smooth(2)`, which is bilinear smoothing. - The ``smooth()`` function can only be set once within a Sketch. It is intended - to be called from the ``settings()`` function. The ``no_smooth()`` function - follows the same rules. + The `smooth()` function can only be set once within a Sketch. It is intended to + be called from the `settings()` function. The `no_smooth()` function follows the + same rules. When programming in module mode and imported mode, py5 will allow calls to - ``smooth()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `smooth()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``smooth()``, or calls to - ``size()``, ``full_screen()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `smooth()`, or calls to `size()`, + `full_screen()`, `no_smooth()`, or `pixel_density()`. Calls to those functions + must be at the very beginning of `setup()`, before any other Python code (but + comments are ok). This feature is not available when programming in class mode. """ return _py5sketch.smooth(*args) @@ -13427,8 +13510,8 @@ def specular(gray: float, /) -> None: Sets the specular color of the materials used for shapes drawn to the screen, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a - diffuse light). Use in combination with ``emissive()``, ``ambient()``, and - ``shininess()`` to set the material properties of shapes. + diffuse light). Use in combination with `emissive()`, `ambient()`, and + `shininess()` to set the material properties of shapes. """ pass @@ -13473,8 +13556,8 @@ def specular(v1: float, v2: float, v3: float, /) -> None: Sets the specular color of the materials used for shapes drawn to the screen, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a - diffuse light). Use in combination with ``emissive()``, ``ambient()``, and - ``shininess()`` to set the material properties of shapes. + diffuse light). Use in combination with `emissive()`, `ambient()`, and + `shininess()` to set the material properties of shapes. """ pass @@ -13519,8 +13602,8 @@ def specular(rgb: int, /) -> None: Sets the specular color of the materials used for shapes drawn to the screen, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a - diffuse light). Use in combination with ``emissive()``, ``ambient()``, and - ``shininess()`` to set the material properties of shapes. + diffuse light). Use in combination with `emissive()`, `ambient()`, and + `shininess()` to set the material properties of shapes. """ pass @@ -13564,8 +13647,8 @@ def specular(*args): Sets the specular color of the materials used for shapes drawn to the screen, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a - diffuse light). Use in combination with ``emissive()``, ``ambient()``, and - ``shininess()`` to set the material properties of shapes. + diffuse light). Use in combination with `emissive()`, `ambient()`, and + `shininess()` to set the material properties of shapes. """ return _py5sketch.specular(*args) @@ -13621,11 +13704,11 @@ def sphere_detail(res: int, /) -> None: Controls the detail used to render a sphere by adjusting the number of vertices of the sphere mesh. The default resolution is 30, which creates a fairly - detailed sphere definition with vertices every ``360/30 = 12`` degrees. If - you're going to render a great number of spheres per frame, it is advised to - reduce the level of detail using this function. The setting stays active until - ``sphere_detail()`` is called again with a new parameter and so should *not* be - called prior to every ``sphere()`` statement, unless you wish to render spheres + detailed sphere definition with vertices every `360/30 = 12` degrees. If you're + going to render a great number of spheres per frame, it is advised to reduce the + level of detail using this function. The setting stays active until + `sphere_detail()` is called again with a new parameter and so should *not* be + called prior to every `sphere()` statement, unless you wish to render spheres with different settings, e.g. using less detail for smaller spheres or ones further away from the camera. To control the detail of the horizontal and vertical resolution independently, use the version of the functions with two @@ -13666,11 +13749,11 @@ def sphere_detail(ures: int, vres: int, /) -> None: Controls the detail used to render a sphere by adjusting the number of vertices of the sphere mesh. The default resolution is 30, which creates a fairly - detailed sphere definition with vertices every ``360/30 = 12`` degrees. If - you're going to render a great number of spheres per frame, it is advised to - reduce the level of detail using this function. The setting stays active until - ``sphere_detail()`` is called again with a new parameter and so should *not* be - called prior to every ``sphere()`` statement, unless you wish to render spheres + detailed sphere definition with vertices every `360/30 = 12` degrees. If you're + going to render a great number of spheres per frame, it is advised to reduce the + level of detail using this function. The setting stays active until + `sphere_detail()` is called again with a new parameter and so should *not* be + called prior to every `sphere()` statement, unless you wish to render spheres with different settings, e.g. using less detail for smaller spheres or ones further away from the camera. To control the detail of the horizontal and vertical resolution independently, use the version of the functions with two @@ -13710,11 +13793,11 @@ def sphere_detail(*args): Controls the detail used to render a sphere by adjusting the number of vertices of the sphere mesh. The default resolution is 30, which creates a fairly - detailed sphere definition with vertices every ``360/30 = 12`` degrees. If - you're going to render a great number of spheres per frame, it is advised to - reduce the level of detail using this function. The setting stays active until - ``sphere_detail()`` is called again with a new parameter and so should *not* be - called prior to every ``sphere()`` statement, unless you wish to render spheres + detailed sphere definition with vertices every `360/30 = 12` degrees. If you're + going to render a great number of spheres per frame, it is advised to reduce the + level of detail using this function. The setting stays active until + `sphere_detail()` is called again with a new parameter and so should *not* be + called prior to every `sphere()` statement, unless you wish to render spheres with different settings, e.g. using less detail for smaller spheres or ones further away from the camera. To control the detail of the horizontal and vertical resolution independently, use the version of the functions with two @@ -13768,15 +13851,14 @@ def spot_light(v1: float, v2: float, v3: float, x: float, y: float, z: float, Notes ----- - Adds a spot light. Lights need to be included in the ``draw()`` to remain - persistent in a looping program. Placing them in the ``setup()`` of a looping + Adds a spot light. Lights need to be included in the `draw()` to remain + persistent in a looping program. Placing them in the `setup()` of a looping program will cause them to only have an effect the first time through the loop. - The ``v1``, ``v2``, and ``v3`` parameters are interpreted as either RGB or HSB - values, depending on the current color mode. The ``x``, ``y``, and ``z`` - parameters specify the position of the light and ``nx``, ``ny``, ``nz`` specify - the direction of light. The ``angle`` parameter affects angle of the spotlight - cone, while ``concentration`` sets the bias of light focusing toward the center - of that cone. + The `v1`, `v2`, and `v3` parameters are interpreted as either RGB or HSB values, + depending on the current color mode. The `x`, `y`, and `z` parameters specify + the position of the light and `nx`, `ny`, `nz` specify the direction of light. + The `angle` parameter affects angle of the spotlight cone, while `concentration` + sets the bias of light focusing toward the center of that cone. """ return _py5sketch.spot_light( v1, v2, v3, x, y, z, nx, ny, nz, angle, concentration) @@ -13806,7 +13888,7 @@ def square(x: float, y: float, extent: float, /) -> None: ninety degrees and each side is the same length. By default, the first two parameters set the location of the upper-left corner, the third sets the width and height. The way these parameters are interpreted, however, may be changed - with the ``rect_mode()`` function. + with the `rect_mode()` function. """ return _py5sketch.square(x, y, extent) @@ -13855,31 +13937,30 @@ def stroke(gray: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -13928,31 +14009,30 @@ def stroke(gray: float, alpha: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -14001,31 +14081,30 @@ def stroke(v1: float, v2: float, v3: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -14074,31 +14153,30 @@ def stroke(v1: float, v2: float, v3: float, alpha: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -14147,31 +14225,30 @@ def stroke(rgb: int, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -14220,31 +14297,30 @@ def stroke(rgb: int, alpha: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -14292,31 +14368,30 @@ def stroke(*args): Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ return _py5sketch.stroke(*args) @@ -14337,10 +14412,10 @@ def stroke_cap(cap: int, /) -> None: Sets the style for rendering line endings. These ends are either squared, extended, or rounded, each of which specified with the corresponding parameters: - ``SQUARE``, ``PROJECT``, and ``ROUND``. The default cap is ``ROUND``. + `SQUARE`, `PROJECT`, and `ROUND`. The default cap is `ROUND`. - To make ``point()`` appear square, use ``stroke_cap(PROJECT)``. Using - ``stroke_cap(SQUARE)`` (no cap) causes points to become invisible. + To make `point()` appear square, use `stroke_cap(PROJECT)`. Using + `stroke_cap(SQUARE)` (no cap) causes points to become invisible. """ return _py5sketch.stroke_cap(cap) @@ -14361,7 +14436,7 @@ def stroke_join(join: int, /) -> None: Sets the style of the joints which connect line segments. These joints are either mitered, beveled, or rounded and specified with the corresponding - parameters ``MITER``, ``BEVEL``, and ``ROUND``. The default joint is ``MITER``. + parameters `MITER`, `BEVEL`, and `ROUND`. The default joint is `MITER`. """ return _py5sketch.stroke_join(join) @@ -14384,10 +14459,10 @@ def stroke_weight(weight: float, /) -> None: Sets the width of the stroke used for lines, points, and the border around shapes. All widths are set in units of pixels. - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the screen, depending on the graphics settings of the computer. Workarounds include - setting the pixel using the ``pixels[]`` or ``np_pixels[]`` arrays or drawing - the point using either ``circle()`` or ``square()``. + setting the pixel using the `pixels[]` or `np_pixels[]` arrays or drawing the + point using either `circle()` or `square()`. """ return _py5sketch.stroke_weight(weight) @@ -14465,19 +14540,19 @@ def text(c: chr, x: float, y: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -14556,19 +14631,19 @@ def text(c: chr, x: float, y: float, z: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -14648,19 +14723,19 @@ def text(chars: list[chr], start: int, stop: int, Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -14740,19 +14815,19 @@ def text(chars: list[chr], start: int, stop: int, Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -14831,19 +14906,19 @@ def text(num: float, x: float, y: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -14922,19 +14997,19 @@ def text(num: float, x: float, y: float, z: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -15013,19 +15088,19 @@ def text(num: int, x: float, y: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -15104,19 +15179,19 @@ def text(num: int, x: float, y: float, z: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -15195,19 +15270,19 @@ def text(str: str, x: float, y: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -15286,19 +15361,19 @@ def text(str: str, x: float, y: float, z: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -15377,19 +15452,19 @@ def text(str: str, x1: float, y1: float, x2: float, y2: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -15467,19 +15542,19 @@ def text(*args): Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ return _py5sketch.text(*args) @@ -15511,27 +15586,26 @@ def text_align(align_x: int, /) -> None: Notes ----- - Sets the current alignment for drawing text. The parameters ``LEFT``, - ``CENTER``, and ``RIGHT`` set the display characteristics of the letters in - relation to the values for the ``x`` and ``y`` parameters of the ``text()`` - function. + Sets the current alignment for drawing text. The parameters `LEFT`, `CENTER`, + and `RIGHT` set the display characteristics of the letters in relation to the + values for the `x` and `y` parameters of the `text()` function. An optional second parameter can be used to vertically align the text. - ``BASELINE`` is the default, and the vertical alignment will be reset to - ``BASELINE`` if the second parameter is not used. The ``TOP`` and ``CENTER`` - parameters are straightforward. The ``BOTTOM`` parameter offsets the line based - on the current ``text_descent()``. For multiple lines, the final line will be - aligned to the bottom, with the previous lines appearing above it. - - When using ``text()`` with width and height parameters, ``BASELINE`` is ignored, - and treated as ``TOP``. (Otherwise, text would by default draw outside the box, - since ``BASELINE`` is the default setting. ``BASELINE`` is not a useful drawing - mode for text drawn in a rectangle.) - - The vertical alignment is based on the value of ``text_ascent()``, which many + `BASELINE` is the default, and the vertical alignment will be reset to + `BASELINE` if the second parameter is not used. The `TOP` and `CENTER` + parameters are straightforward. The `BOTTOM` parameter offsets the line based on + the current `text_descent()`. For multiple lines, the final line will be aligned + to the bottom, with the previous lines appearing above it. + + When using `text()` with width and height parameters, `BASELINE` is ignored, and + treated as `TOP`. (Otherwise, text would by default draw outside the box, since + `BASELINE` is the default setting. `BASELINE` is not a useful drawing mode for + text drawn in a rectangle.) + + The vertical alignment is based on the value of `text_ascent()`, which many fonts do not specify correctly. It may be necessary to use a hack and offset by a few pixels by hand so that the offset looks correct. To do this as less of a - hack, use some percentage of ``text_ascent()`` or ``text_descent()`` so that the + hack, use some percentage of `text_ascent()` or `text_descent()` so that the hack works even if you change the size of the font. """ pass @@ -15563,27 +15637,26 @@ def text_align(align_x: int, align_y: int, /) -> None: Notes ----- - Sets the current alignment for drawing text. The parameters ``LEFT``, - ``CENTER``, and ``RIGHT`` set the display characteristics of the letters in - relation to the values for the ``x`` and ``y`` parameters of the ``text()`` - function. + Sets the current alignment for drawing text. The parameters `LEFT`, `CENTER`, + and `RIGHT` set the display characteristics of the letters in relation to the + values for the `x` and `y` parameters of the `text()` function. An optional second parameter can be used to vertically align the text. - ``BASELINE`` is the default, and the vertical alignment will be reset to - ``BASELINE`` if the second parameter is not used. The ``TOP`` and ``CENTER`` - parameters are straightforward. The ``BOTTOM`` parameter offsets the line based - on the current ``text_descent()``. For multiple lines, the final line will be - aligned to the bottom, with the previous lines appearing above it. - - When using ``text()`` with width and height parameters, ``BASELINE`` is ignored, - and treated as ``TOP``. (Otherwise, text would by default draw outside the box, - since ``BASELINE`` is the default setting. ``BASELINE`` is not a useful drawing - mode for text drawn in a rectangle.) - - The vertical alignment is based on the value of ``text_ascent()``, which many + `BASELINE` is the default, and the vertical alignment will be reset to + `BASELINE` if the second parameter is not used. The `TOP` and `CENTER` + parameters are straightforward. The `BOTTOM` parameter offsets the line based on + the current `text_descent()`. For multiple lines, the final line will be aligned + to the bottom, with the previous lines appearing above it. + + When using `text()` with width and height parameters, `BASELINE` is ignored, and + treated as `TOP`. (Otherwise, text would by default draw outside the box, since + `BASELINE` is the default setting. `BASELINE` is not a useful drawing mode for + text drawn in a rectangle.) + + The vertical alignment is based on the value of `text_ascent()`, which many fonts do not specify correctly. It may be necessary to use a hack and offset by a few pixels by hand so that the offset looks correct. To do this as less of a - hack, use some percentage of ``text_ascent()`` or ``text_descent()`` so that the + hack, use some percentage of `text_ascent()` or `text_descent()` so that the hack works even if you change the size of the font. """ pass @@ -15614,27 +15687,26 @@ def text_align(*args): Notes ----- - Sets the current alignment for drawing text. The parameters ``LEFT``, - ``CENTER``, and ``RIGHT`` set the display characteristics of the letters in - relation to the values for the ``x`` and ``y`` parameters of the ``text()`` - function. + Sets the current alignment for drawing text. The parameters `LEFT`, `CENTER`, + and `RIGHT` set the display characteristics of the letters in relation to the + values for the `x` and `y` parameters of the `text()` function. An optional second parameter can be used to vertically align the text. - ``BASELINE`` is the default, and the vertical alignment will be reset to - ``BASELINE`` if the second parameter is not used. The ``TOP`` and ``CENTER`` - parameters are straightforward. The ``BOTTOM`` parameter offsets the line based - on the current ``text_descent()``. For multiple lines, the final line will be - aligned to the bottom, with the previous lines appearing above it. - - When using ``text()`` with width and height parameters, ``BASELINE`` is ignored, - and treated as ``TOP``. (Otherwise, text would by default draw outside the box, - since ``BASELINE`` is the default setting. ``BASELINE`` is not a useful drawing - mode for text drawn in a rectangle.) - - The vertical alignment is based on the value of ``text_ascent()``, which many + `BASELINE` is the default, and the vertical alignment will be reset to + `BASELINE` if the second parameter is not used. The `TOP` and `CENTER` + parameters are straightforward. The `BOTTOM` parameter offsets the line based on + the current `text_descent()`. For multiple lines, the final line will be aligned + to the bottom, with the previous lines appearing above it. + + When using `text()` with width and height parameters, `BASELINE` is ignored, and + treated as `TOP`. (Otherwise, text would by default draw outside the box, since + `BASELINE` is the default setting. `BASELINE` is not a useful drawing mode for + text drawn in a rectangle.) + + The vertical alignment is based on the value of `text_ascent()`, which many fonts do not specify correctly. It may be necessary to use a hack and offset by a few pixels by hand so that the offset looks correct. To do this as less of a - hack, use some percentage of ``text_ascent()`` or ``text_descent()`` so that the + hack, use some percentage of `text_ascent()` or `text_descent()` so that the hack works even if you change the size of the font. """ return _py5sketch.text_align(*args) @@ -15670,7 +15742,7 @@ def text_descent() -> float: @overload def text_font(which: Py5Font, /) -> None: - """Sets the current font that will be drawn with the ``text()`` function. + """Sets the current font that will be drawn with the `text()` function. Underlying Processing method: PApplet.textFont @@ -15694,25 +15766,25 @@ def text_font(which: Py5Font, /) -> None: Notes ----- - Sets the current font that will be drawn with the ``text()`` function. Fonts - must be created for py5 with ``create_font()`` or loaded with ``load_font()`` - before they can be used. The font set through ``text_font()`` will be used in - all subsequent calls to the ``text()`` function. If no ``size`` parameter is - specified, the font size defaults to the original size (the size in which it was - created with ``create_font_file()``) overriding any previous calls to - ``text_font()`` or ``text_size()``. + Sets the current font that will be drawn with the `text()` function. Fonts must + be created for py5 with `create_font()` or loaded with `load_font()` before they + can be used. The font set through `text_font()` will be used in all subsequent + calls to the `text()` function. If no `size` parameter is specified, the font + size defaults to the original size (the size in which it was created with + `create_font_file()`) overriding any previous calls to `text_font()` or + `text_size()`. - When fonts are rendered as an image texture (as is the case with the ``P2D`` and - ``P3D`` renderers as well as with ``load_font()`` and vlw files), you should - create fonts at the sizes that will be used most commonly. Using ``text_font()`` - without the size parameter will result in the cleanest type. + When fonts are rendered as an image texture (as is the case with the `P2D` and + `P3D` renderers as well as with `load_font()` and vlw files), you should create + fonts at the sizes that will be used most commonly. Using `text_font()` without + the size parameter will result in the cleanest type. """ pass @overload def text_font(which: Py5Font, size: float, /) -> None: - """Sets the current font that will be drawn with the ``text()`` function. + """Sets the current font that will be drawn with the `text()` function. Underlying Processing method: PApplet.textFont @@ -15736,24 +15808,24 @@ def text_font(which: Py5Font, size: float, /) -> None: Notes ----- - Sets the current font that will be drawn with the ``text()`` function. Fonts - must be created for py5 with ``create_font()`` or loaded with ``load_font()`` - before they can be used. The font set through ``text_font()`` will be used in - all subsequent calls to the ``text()`` function. If no ``size`` parameter is - specified, the font size defaults to the original size (the size in which it was - created with ``create_font_file()``) overriding any previous calls to - ``text_font()`` or ``text_size()``. + Sets the current font that will be drawn with the `text()` function. Fonts must + be created for py5 with `create_font()` or loaded with `load_font()` before they + can be used. The font set through `text_font()` will be used in all subsequent + calls to the `text()` function. If no `size` parameter is specified, the font + size defaults to the original size (the size in which it was created with + `create_font_file()`) overriding any previous calls to `text_font()` or + `text_size()`. - When fonts are rendered as an image texture (as is the case with the ``P2D`` and - ``P3D`` renderers as well as with ``load_font()`` and vlw files), you should - create fonts at the sizes that will be used most commonly. Using ``text_font()`` - without the size parameter will result in the cleanest type. + When fonts are rendered as an image texture (as is the case with the `P2D` and + `P3D` renderers as well as with `load_font()` and vlw files), you should create + fonts at the sizes that will be used most commonly. Using `text_font()` without + the size parameter will result in the cleanest type. """ pass def text_font(*args): - """Sets the current font that will be drawn with the ``text()`` function. + """Sets the current font that will be drawn with the `text()` function. Underlying Processing method: PApplet.textFont @@ -15777,18 +15849,18 @@ def text_font(*args): Notes ----- - Sets the current font that will be drawn with the ``text()`` function. Fonts - must be created for py5 with ``create_font()`` or loaded with ``load_font()`` - before they can be used. The font set through ``text_font()`` will be used in - all subsequent calls to the ``text()`` function. If no ``size`` parameter is - specified, the font size defaults to the original size (the size in which it was - created with ``create_font_file()``) overriding any previous calls to - ``text_font()`` or ``text_size()``. + Sets the current font that will be drawn with the `text()` function. Fonts must + be created for py5 with `create_font()` or loaded with `load_font()` before they + can be used. The font set through `text_font()` will be used in all subsequent + calls to the `text()` function. If no `size` parameter is specified, the font + size defaults to the original size (the size in which it was created with + `create_font_file()`) overriding any previous calls to `text_font()` or + `text_size()`. - When fonts are rendered as an image texture (as is the case with the ``P2D`` and - ``P3D`` renderers as well as with ``load_font()`` and vlw files), you should - create fonts at the sizes that will be used most commonly. Using ``text_font()`` - without the size parameter will result in the cleanest type. + When fonts are rendered as an image texture (as is the case with the `P2D` and + `P3D` renderers as well as with `load_font()` and vlw files), you should create + fonts at the sizes that will be used most commonly. Using `text_font()` without + the size parameter will result in the cleanest type. """ return _py5sketch.text_font(*args) @@ -15808,10 +15880,10 @@ def text_leading(leading: float, /) -> None: ----- Sets the spacing between lines of text in units of pixels. This setting will be - used in all subsequent calls to the ``text()`` function. Note, however, that - the leading is reset by ``text_size()``. For example, if the leading is set to - 20 with ``text_leading(20)``, then if ``text_size(48)`` is run at a later point, - the leading will be reset to the default for the text size of 48. + used in all subsequent calls to the `text()` function. Note, however, that the + leading is reset by `text_size()`. For example, if the leading is set to 20 with + `text_leading(20)`, then if `text_size(48)` is run at a later point, the leading + will be reset to the default for the text size of 48. """ return _py5sketch.text_leading(leading) @@ -15832,19 +15904,19 @@ def text_mode(mode: int, /) -> None: ----- Sets the way text draws to the screen, either as texture maps or as vector - geometry. The default ``text_mode(MODEL)``, uses textures to render the fonts. - The ``text_mode(SHAPE)`` mode draws text using the glyph outlines of individual - characters rather than as textures. This mode is only supported with the ``PDF`` - and ``P3D`` renderer settings. With the ``PDF`` renderer, you must call - ``text_mode(SHAPE)`` before any other drawing occurs. If the outlines are not - available, then ``text_mode(SHAPE)`` will be ignored and ``text_mode(MODEL)`` - will be used instead. - - The ``text_mode(SHAPE)`` option in ``P3D`` can be combined with ``begin_raw()`` - to write vector-accurate text to 2D and 3D output files, for instance ``DXF`` or - ``PDF``. The ``SHAPE`` mode is not currently optimized for ``P3D``, so if - recording shape data, use ``text_mode(MODEL)`` until you're ready to capture the - geometry with ``begin_raw()``. + geometry. The default `text_mode(MODEL)`, uses textures to render the fonts. The + `text_mode(SHAPE)` mode draws text using the glyph outlines of individual + characters rather than as textures. This mode is only supported with the `PDF` + and `P3D` renderer settings. With the `PDF` renderer, you must call + `text_mode(SHAPE)` before any other drawing occurs. If the outlines are not + available, then `text_mode(SHAPE)` will be ignored and `text_mode(MODEL)` will + be used instead. + + The `text_mode(SHAPE)` option in `P3D` can be combined with `begin_raw()` to + write vector-accurate text to 2D and 3D output files, for instance `DXF` or + `PDF`. The `SHAPE` mode is not currently optimized for `P3D`, so if recording + shape data, use `text_mode(MODEL)` until you're ready to capture the geometry + with `begin_raw()`. """ return _py5sketch.text_mode(mode) @@ -15864,7 +15936,7 @@ def text_size(size: float, /) -> None: ----- Sets the current font size. This size will be used in all subsequent calls to - the ``text()`` function. Font size is measured in units of pixels. + the `text()` function. Font size is measured in units of pixels. """ return _py5sketch.text_size(size) @@ -16046,11 +16118,11 @@ def texture(image: Py5Image, /) -> None: Notes ----- - Sets a texture to be applied to vertex points. The ``texture()`` method must be - called between ``begin_shape()`` and ``end_shape()`` and before any calls to - ``vertex()``. This method only works with the ``P2D`` and ``P3D`` renderers. + Sets a texture to be applied to vertex points. The `texture()` method must be + called between `begin_shape()` and `end_shape()` and before any calls to + `vertex()`. This method only works with the `P2D` and `P3D` renderers. - When textures are in use, the fill color is ignored. Instead, use ``tint()`` to + When textures are in use, the fill color is ignored. Instead, use `tint()` to specify the color of the texture as it is applied to the shape. """ return _py5sketch.texture(image) @@ -16070,14 +16142,14 @@ def texture_mode(mode: int, /) -> None: Notes ----- - Sets the coordinate space for texture mapping. The default mode is ``IMAGE``, - which refers to the actual pixel coordinates of the image. ``NORMAL`` refers to - a normalized space of values ranging from 0 to 1. This function only works with - the ``P2D`` and ``P3D`` renderers. + Sets the coordinate space for texture mapping. The default mode is `IMAGE`, + which refers to the actual pixel coordinates of the image. `NORMAL` refers to a + normalized space of values ranging from 0 to 1. This function only works with + the `P2D` and `P3D` renderers. - With ``IMAGE``, if an image is 100 x 200 pixels, mapping the image onto the - entire size of a quad would require the points (0,0) (100,0) (100,200) (0,200). - The same mapping in ``NORMAL`` is (0,0) (1,0) (1,1) (0,1). + With `IMAGE`, if an image is 100 x 200 pixels, mapping the image onto the entire + size of a quad would require the points (0,0) (100,0) (100,200) (0,200). The + same mapping in `NORMAL` is (0,0) (1,0) (1,1) (0,1). """ return _py5sketch.texture_mode(mode) @@ -16097,8 +16169,8 @@ def texture_wrap(wrap: int, /) -> None: ----- Defines if textures repeat or draw once within a texture map. The two parameters - are ``CLAMP`` (the default behavior) and ``REPEAT``. This function only works - with the ``P2D`` and ``P3D`` renderers. + are `CLAMP` (the default behavior) and `REPEAT`. This function only works with + the `P2D` and `P3D` renderers. """ return _py5sketch.texture_wrap(wrap) @@ -16149,30 +16221,29 @@ def tint(gray: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -16223,30 +16294,29 @@ def tint(gray: float, alpha: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -16297,30 +16367,29 @@ def tint(v1: float, v2: float, v3: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -16371,30 +16440,29 @@ def tint(v1: float, v2: float, v3: float, alpha: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -16445,30 +16513,29 @@ def tint(rgb: int, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -16519,30 +16586,29 @@ def tint(rgb: int, alpha: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -16592,30 +16658,29 @@ def tint(*args): colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ return _py5sketch.tint(*args) @@ -16649,18 +16714,18 @@ def translate(x: float, y: float, /) -> None: Notes ----- - Specifies an amount to displace objects within the display window. The ``x`` - parameter specifies left/right translation, the ``y`` parameter specifies - up/down translation, and the ``z`` parameter specifies translations toward/away - from the screen. Using this function with the ``z`` parameter requires using - ``P3D`` as a parameter in combination with size as shown in the second example. + Specifies an amount to displace objects within the display window. The `x` + parameter specifies left/right translation, the `y` parameter specifies up/down + translation, and the `z` parameter specifies translations toward/away from the + screen. Using this function with the `z` parameter requires using `P3D` as a + parameter in combination with size as shown in the second example. Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. If ``translate()`` is called within ``draw()``, the - transformation is reset when the loop begins again. This function can be further - controlled by using ``push_matrix()`` and ``pop_matrix()``. + `translate(50, 0)` and then `translate(20, 0)` is the same as `translate(70, + 0)`. If `translate()` is called within `draw()`, the transformation is reset + when the loop begins again. This function can be further controlled by using + `push_matrix()` and `pop_matrix()`. """ pass @@ -16694,18 +16759,18 @@ def translate(x: float, y: float, z: float, /) -> None: Notes ----- - Specifies an amount to displace objects within the display window. The ``x`` - parameter specifies left/right translation, the ``y`` parameter specifies - up/down translation, and the ``z`` parameter specifies translations toward/away - from the screen. Using this function with the ``z`` parameter requires using - ``P3D`` as a parameter in combination with size as shown in the second example. + Specifies an amount to displace objects within the display window. The `x` + parameter specifies left/right translation, the `y` parameter specifies up/down + translation, and the `z` parameter specifies translations toward/away from the + screen. Using this function with the `z` parameter requires using `P3D` as a + parameter in combination with size as shown in the second example. Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. If ``translate()`` is called within ``draw()``, the - transformation is reset when the loop begins again. This function can be further - controlled by using ``push_matrix()`` and ``pop_matrix()``. + `translate(50, 0)` and then `translate(20, 0)` is the same as `translate(70, + 0)`. If `translate()` is called within `draw()`, the transformation is reset + when the loop begins again. This function can be further controlled by using + `push_matrix()` and `pop_matrix()`. """ pass @@ -16738,18 +16803,18 @@ def translate(*args): Notes ----- - Specifies an amount to displace objects within the display window. The ``x`` - parameter specifies left/right translation, the ``y`` parameter specifies - up/down translation, and the ``z`` parameter specifies translations toward/away - from the screen. Using this function with the ``z`` parameter requires using - ``P3D`` as a parameter in combination with size as shown in the second example. + Specifies an amount to displace objects within the display window. The `x` + parameter specifies left/right translation, the `y` parameter specifies up/down + translation, and the `z` parameter specifies translations toward/away from the + screen. Using this function with the `z` parameter requires using `P3D` as a + parameter in combination with size as shown in the second example. Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. If ``translate()`` is called within ``draw()``, the - transformation is reset when the loop begins again. This function can be further - controlled by using ``push_matrix()`` and ``pop_matrix()``. + `translate(50, 0)` and then `translate(20, 0)` is the same as `translate(70, + 0)`. If `translate()` is called within `draw()`, the transformation is reset + when the loop begins again. This function can be further controlled by using + `push_matrix()` and `pop_matrix()`. """ return _py5sketch.translate(*args) @@ -16793,7 +16858,7 @@ def triangle(x1: float, y1: float, x2: float, y2: float, @overload def update_pixels() -> None: - """Updates the display window with the data in the ``pixels[]`` array. + """Updates the display window with the data in the `pixels[]` array. Underlying Processing method: PApplet.updatePixels @@ -16823,17 +16888,17 @@ def update_pixels() -> None: Notes ----- - Updates the display window with the data in the ``pixels[]`` array. Use in - conjunction with ``load_pixels()``. If you're only reading pixels from the - array, there's no need to call ``update_pixels()`` — updating is only necessary - to apply changes. + Updates the display window with the data in the `pixels[]` array. Use in + conjunction with `load_pixels()`. If you're only reading pixels from the array, + there's no need to call `update_pixels()` — updating is only necessary to apply + changes. """ pass @overload def update_pixels(x1: int, y1: int, x2: int, y2: int, /) -> None: - """Updates the display window with the data in the ``pixels[]`` array. + """Updates the display window with the data in the `pixels[]` array. Underlying Processing method: PApplet.updatePixels @@ -16863,16 +16928,16 @@ def update_pixels(x1: int, y1: int, x2: int, y2: int, /) -> None: Notes ----- - Updates the display window with the data in the ``pixels[]`` array. Use in - conjunction with ``load_pixels()``. If you're only reading pixels from the - array, there's no need to call ``update_pixels()`` — updating is only necessary - to apply changes. + Updates the display window with the data in the `pixels[]` array. Use in + conjunction with `load_pixels()`. If you're only reading pixels from the array, + there's no need to call `update_pixels()` — updating is only necessary to apply + changes. """ pass def update_pixels(*args): - """Updates the display window with the data in the ``pixels[]`` array. + """Updates the display window with the data in the `pixels[]` array. Underlying Processing method: PApplet.updatePixels @@ -16902,10 +16967,10 @@ def update_pixels(*args): Notes ----- - Updates the display window with the data in the ``pixels[]`` array. Use in - conjunction with ``load_pixels()``. If you're only reading pixels from the - array, there's no need to call ``update_pixels()`` — updating is only necessary - to apply changes. + Updates the display window with the data in the `pixels[]` array. Use in + conjunction with `load_pixels()`. If you're only reading pixels from the array, + there's no need to call `update_pixels()` — updating is only necessary to apply + changes. """ return _py5sketch.update_pixels(*args) @@ -16952,19 +17017,19 @@ def vertex(x: float, y: float, /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ pass @@ -17011,19 +17076,19 @@ def vertex(x: float, y: float, z: float, /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ pass @@ -17070,19 +17135,19 @@ def vertex(x: float, y: float, u: float, v: float, /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ pass @@ -17129,19 +17194,19 @@ def vertex(x: float, y: float, z: float, u: float, v: float, /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ pass @@ -17188,19 +17253,19 @@ def vertex(v: npt.NDArray[np.floating], /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ pass @@ -17246,19 +17311,19 @@ def vertex(*args): ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ return _py5sketch.vertex(*args) @@ -17278,10 +17343,10 @@ def vertices(coordinates: npt.NDArray[np.floating], /) -> None: ----- Create a collection of vertices. The purpose of this method is to provide an - alternative to repeatedly calling ``vertex()`` in a loop. For a large number of - vertices, the performance of ``vertices()`` will be much faster. + alternative to repeatedly calling `vertex()` in a loop. For a large number of + vertices, the performance of `vertices()` will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each + The `coordinates` parameter should be a numpy array with one row for each vertex. There should be two or three columns for 2D or 3D points, respectively. """ return _py5sketch.vertices(coordinates) @@ -17304,12 +17369,12 @@ def window_move(x: int, y: int, /) -> None: Notes ----- - Set the Sketch's window location. Calling this repeatedly from the ``draw()`` + Set the Sketch's window location. Calling this repeatedly from the `draw()` function may result in a sluggish Sketch. Negative or invalid coordinates are - ignored. To hide a Sketch window, use ``Py5Surface.set_visible()``. + ignored. To hide a Sketch window, use `Py5Surface.set_visible()`. - This method provides the same functionality as ``Py5Surface.set_location()`` but - without the need to interact directly with the ``Py5Surface`` object. + This method provides the same functionality as `Py5Surface.set_location()` but + without the need to interact directly with the `Py5Surface` object. """ return _py5sketch.window_move(x, y) @@ -17338,24 +17403,24 @@ def window_ratio(wide: int, high: int, /) -> None: The usefulness of this feature is demonstrated in the example code. The size of the text will change as the window changes size. Observe the example makes two - calls to ``text_size()`` with fixed values of ``200`` and ``100``. Without this + calls to `text_size()` with fixed values of `200` and `100`. Without this feature, calculating the appropriate text size for all window sizes would be difficult. Similarly, positioning the text in the same relative location would - also involve several calculations. Using ``window_ratio()`` makes resizable + also involve several calculations. Using `window_ratio()` makes resizable Sketches that resize well easier to create. - When using this feature, use ``rmouse_x`` and ``rmouse_y`` to get the cursor - coordinates. The transformations involve calls to ``translate()`` and - ``scale()``, and the parameters to those methods can be accessed with - ``ratio_top``, ``ratio_left``, and ``ratio_scale``. The transformed coordinates - enabled with this feature can be negative for the top and left areas of the - window that do not fit the desired aspect ratio. Experimenting with the example - and seeing how the numbers change will provide more understanding than what can - be explained with words. + When using this feature, use `rmouse_x` and `rmouse_y` to get the cursor + coordinates. The transformations involve calls to `translate()` and `scale()`, + and the parameters to those methods can be accessed with `ratio_top`, + `ratio_left`, and `ratio_scale`. The transformed coordinates enabled with this + feature can be negative for the top and left areas of the window that do not fit + the desired aspect ratio. Experimenting with the example and seeing how the + numbers change will provide more understanding than what can be explained with + words. When calling this method, it is better to do so with values like - ``window_ratio(1280, 720)`` and not ``window_ratio(16, 9)``. The aspect ratio is - the same for both but the latter might result in floating point accuracy issues. + `window_ratio(1280, 720)` and not `window_ratio(16, 9)`. The aspect ratio is the + same for both but the latter might result in floating point accuracy issues. """ return _py5sketch.window_ratio(wide, high) @@ -17379,10 +17444,10 @@ def window_resizable(resizable: bool, /) -> None: By default, the Sketch window is not resizable. Changing the window size will clear the drawing canvas. If you do this, the - ``width`` and ``height`` variables will change. + `width` and `height` variables will change. - This method provides the same functionality as ``Py5Surface.set_resizable()`` - but without the need to interact directly with the ``Py5Surface`` object. + This method provides the same functionality as `Py5Surface.set_resizable()` but + without the need to interact directly with the `Py5Surface` object. """ return _py5sketch.window_resizable(resizable) @@ -17405,13 +17470,13 @@ def window_resize(new_width: int, new_height: int, /) -> None: ----- Set a new width and height for the Sketch window. You do not need to call - ``window_resizable()`` before calling this. + `window_resizable()` before calling this. Changing the window size will clear the drawing canvas. If you do this, the - ``width`` and ``height`` variables will change. + `width` and `height` variables will change. - This method provides the same functionality as ``Py5Surface.set_size()`` but - without the need to interact directly with the ``Py5Surface`` object. + This method provides the same functionality as `Py5Surface.set_size()` but + without the need to interact directly with the `Py5Surface` object. """ return _py5sketch.window_resize(new_width, new_height) @@ -17433,8 +17498,8 @@ def window_title(title: str, /) -> None: Set the Sketch window's title. This will typically appear at the window's title bar. The default window title is "Sketch". - This method provides the same functionality as ``Py5Surface.set_title()`` but - without the need to interact directly with the ``Py5Surface`` object. + This method provides the same functionality as `Py5Surface.set_title()` but + without the need to interact directly with the `Py5Surface` object. """ return _py5sketch.window_title(title) @@ -17447,2924 +17512,2937 @@ def year() -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``year()`` function - returns the current year as an integer (2003, 2004, 2005, etc). + Py5 communicates with the clock on your computer. The `year()` function returns + the current year as an integer (2003, 2004, 2005, etc). """ return Sketch.year() ############################################################################## -# module functions from math.py +# module functions from data.py ############################################################################## -def hex_color(color: int) -> str: - """Convert a color value to a hex color string. +def load_json(json_path: Union[str, Path], **kwargs: dict[str, Any]) -> Any: + """Load a JSON data file from a file or URL. Parameters ---------- - color: int - any color value + json_path: Union[str, Path] + url or file path for JSON data file + + kwargs: dict[str, Any] + keyword arguments Notes ----- - Convert a color value to a hex color string. Processing and py5 store color - values in 32 bit integers that are inconvenient for a human to parse. To - interpret these values, one can use methods like ``red()``, ``green()``, and - ``blue()`` to extract color channel values from the 32 bit integers. This method - provides an alternative approach, converting the 32 bit integer into a string - such as ``'#0F3FF0FF'``. The hex string has 8 hexadecimal values following a - ``#`` character. The first two values represent the red value, the next two - green, the next two blue, and the last two alpha. This is consistent with CSS 8 - digit hex colors. + Load a JSON data file from a file or URL. When loading a file, the path can be + in the data directory, relative to the current working directory + (`sketch_path()`), or an absolute path. When loading from a URL, the `json_path` + parameter must start with `http://` or `https://`. - Conveniently, the hex color string returned by this method can also be used as - parameter for other methods that accept color values. Observe how this is done - in the example code. + When loading JSON data from a URL, the data is retrieved using the Python + requests library with the `get` method, and any extra keyword arguments (the + `kwargs` parameter) are passed along to that method. When loading JSON data from + a file, the data is loaded using the Python json library with the `load` method, + and again any extra keyword arguments are passed along to that method. """ - return Sketch.hex_color(color) + return _py5sketch.load_json(json_path, **kwargs) -def sin(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Calculates the sine of an angle. +def save_json(json_data: Any, + filename: Union[str, + Path], + **kwargs: dict[str, + Any]) -> None: + """Save JSON data to a file. Parameters ---------- - angle: Union[float, npt.ArrayLike] - angle in radians + filename: Union[str, Path] + filename to save JSON data object to + + json_data: Any + json data object + + kwargs: dict[str, Any] + keyword arguments Notes ----- - Calculates the sine of an angle. This function expects the values of the angle - parameter to be provided in radians (values from ``0`` to ``TWO_PI``). Values - are returned in the range -1 to 1. + Save JSON data to a file. If `filename` is not an absolute path, it will be + saved relative to the current working directory (`sketch_path()`). The saved + file can be reloaded with `load_json()`. - This function makes a call to the numpy ``sin()`` function. + The JSON data is saved using the Python json library with the `dump` method, and + the `kwargs` parameter is passed along to that method. """ - return Sketch.sin(angle) + return _py5sketch.save_json(json_data, filename, **kwargs) -def cos(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Calculates the cosine of an angle. +def parse_json(serialized_json: Any, **kwargs: dict[str, Any]) -> Any: + """Parse serialized JSON data from a string. Parameters ---------- - angle: Union[float, npt.ArrayLike] - angle in radians + kwargs: dict[str, Any] + keyword arguments + + serialized_json: Any + JSON data object that has been serialized as a string Notes ----- - Calculates the cosine of an angle. This function expects the values of the angle - parameter to be provided in radians (values from ``0`` to ``TWO_PI``). Values - are returned in the range -1 to 1. + Parse serialized JSON data from a string. When reading JSON data from a file, + `load_json()` is the better choice. - This function makes a call to the numpy ``cos()`` function. + The JSON data is parsed using the Python json library with the `loads` method, + and the `kwargs` parameter is passed along to that method. """ - return Sketch.cos(angle) + return Sketch.parse_json(serialized_json, **kwargs) -def tan(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Calculates the ratio of the sine and cosine of an angle. +def load_strings(string_path: Union[str, Path], + **kwargs: dict[str, Any]) -> list[str]: + """Load a list of strings from a file or URL. + + Underlying Processing method: Sketch.loadStrings Parameters ---------- - angle: Union[float, npt.ArrayLike] - angle in radians + kwargs: dict[str, Any] + keyword arguments + + string_path: Union[str, Path] + url or file path for string data file Notes ----- - Calculates the ratio of the sine and cosine of an angle. This function expects - the values of the angle parameter to be provided in radians (values from ``0`` - to ``TWO_PI``). Values are returned in the range infinity to -infinity. + Load a list of strings from a file or URL. When loading a file, the path can be + in the data directory, relative to the current working directory + (`sketch_path()`), or an absolute path. When loading from a URL, the + `string_path` parameter must start with `http://` or `https://`. - This function makes a call to the numpy ``tan()`` function. + When loading string data from a URL, the data is retrieved using the Python + requests library with the `get` method, and any extra keyword arguments (the + `kwargs` parameter) are passed along to that method. When loading string data + from a file, the `kwargs` parameter is not used. """ - return Sketch.tan(angle) + return _py5sketch.load_strings(string_path, **kwargs) -def asin(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """The inverse of ``sin()``, returns the arc sine of a value. +def save_strings(string_data: list[str], + filename: Union[str, + Path], + *, + end: str = '\n') -> None: + """Save a list of strings to a file. + + Underlying Processing method: Sketch.saveStrings Parameters ---------- - value: Union[float, npt.ArrayLike] - value in the range of -1 to 1 whose arc sine is to be returned + end: str = '\\n' + line terminator for each string + + filename: Union[str, Path] + filename to save string data to + + string_data: list[str] + string data to save in a file Notes ----- - The inverse of ``sin()``, returns the arc sine of a value. This function expects - the values in the range of -1 to 1 and values are returned in the range - ``-HALF_PI`` to ``HALF_PI``. + Save a list of strings to a file. If `filename` is not an absolute path, it will + be saved relative to the current working directory (`sketch_path()`). If the + contents of the list are not already strings, it will be converted to strings + with the Python builtin `str`. The saved file can be reloaded with + `load_strings()`. - This function makes a call to the numpy ``asin()`` function. + Use the `end` parameter to set the line terminator for each string in the list. + If items in the list of strings already have line terminators, set the `end` + parameter to `''` to keep the output file from being saved with a blank line + after each item. """ - return Sketch.asin(value) + return _py5sketch.save_strings(string_data, filename, end=end) -def acos(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """The inverse of ``cos()``, returns the arc cosine of a value. +def load_bytes(bytes_path: Union[str, Path], ** + kwargs: dict[str, Any]) -> bytearray: + """Load byte data from a file or URL. + + Underlying Processing method: Sketch.loadBytes Parameters ---------- - value: Union[float, npt.ArrayLike] - value in the range of -1 to 1 whose arc cosine is to be returned + bytes_path: Union[str, Path] + url or file path for bytes data file + + kwargs: dict[str, Any] + keyword arguments Notes ----- - The inverse of ``cos()``, returns the arc cosine of a value. This function - expects the values in the range of -1 to 1 and values are returned in the range - ``0`` to ``PI``. + Load byte data from a file or URL. When loading a file, the path can be in the + data directory, relative to the current working directory (`sketch_path()`), or + an absolute path. When loading from a URL, the `bytes_path` parameter must start + with `http://` or `https://`. - This function makes a call to the numpy ``acos()`` function. + When loading byte data from a URL, the data is retrieved using the Python + requests library with the `get` method, and any extra keyword arguments (the + `kwargs` parameter) are passed along to that method. When loading byte data from + a file, the `kwargs` parameter is not used. """ - return Sketch.acos(value) + return _py5sketch.load_bytes(bytes_path, **kwargs) -def atan(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """The inverse of ``tan()``, returns the arc tangent of a value. +def save_bytes(bytes_data: Union[bytes, bytearray], + filename: Union[str, Path]) -> None: + """Save byte data to a file. + + Underlying Processing method: Sketch.saveBytes Parameters ---------- - value: Union[float, npt.ArrayLike] - value whose arc tangent is to be returned + bytes_data: Union[bytes, bytearray] + byte data to save in a file + + filename: Union[str, Path] + filename to save byte data to Notes ----- - The inverse of ``tan()``, returns the arc tangent of a value. This function - expects the values in the range of -Infinity to Infinity and values are returned - in the range ``-HALF_PI`` to ``HALF_PI``. - - This function makes a call to the numpy ``atan()`` function. + Save byte data to a file. If `filename` is not an absolute path, it will be + saved relative to the current working directory (`sketch_path()`). The saved + file can be reloaded with `load_bytes()`. """ - return Sketch.atan(value) + return _py5sketch.save_bytes(bytes_data, filename) -def atan2(y: Union[float, npt.ArrayLike], x: Union[float, - npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Calculates the angle (in radians) from a specified point to the coordinate - origin as measured from the positive x-axis. +def load_pickle(pickle_path: Union[str, Path]) -> Any: + """Load a pickled Python object from a file. + + Underlying Processing method: Sketch.loadPickle Parameters ---------- - x: Union[float, npt.ArrayLike] - x-coordinate of the point - - y: Union[float, npt.ArrayLike] - y-coordinate of the point + pickle_path: Union[str, Path] + file path for pickle object file Notes ----- - Calculates the angle (in radians) from a specified point to the coordinate - origin as measured from the positive x-axis. Values are returned as a float in - the range from ``PI`` to ``-PI``. The ``atan2()`` function is most often used - for orienting geometry to the position of the cursor. Note: The y-coordinate of - the point is the first parameter, and the x-coordinate is the second parameter, - due the the structure of calculating the tangent. + Load a pickled Python object from a file. The path can be in the data directory, + relative to the current working directory (`sketch_path()`), or an absolute + path. - This function makes a call to the numpy ``atan2()`` function. + There are security risks associated with Python pickle files. A pickle file can + contain malicious code, so never load a pickle file from an untrusted source. """ - return Sketch.atan2(y, x) + return _py5sketch.load_pickle(pickle_path) -def degrees(radians: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Converts a radian measurement to its corresponding value in degrees. +def save_pickle(obj: Any, filename: Union[str, Path]) -> None: + """Pickle a Python object to a file. + + Underlying Processing method: Sketch.savePickle Parameters ---------- - radians: Union[float, npt.ArrayLike] - radian value to convert to degrees + filename: Union[str, Path] + filename to save pickled object to + + obj: Any + any non-py5 Python object Notes ----- - Converts a radian measurement to its corresponding value in degrees. Radians and - degrees are two ways of measuring the same thing. There are 360 degrees in a - circle and ``2*PI`` radians in a circle. For example, ``90° = PI/2 = - 1.5707964``. All trigonometric functions in py5 require their parameters to be - specified in radians. + Pickle a Python object to a file. If `filename` is not an absolute path, it will + be saved relative to the current working directory (`sketch_path()`). The saved + file can be reloaded with `load_pickle()`. - This function makes a call to the numpy ``degrees()`` function. + Object "pickling" is a method for serializing objects and saving them to a file + for later retrieval. The recreated objects will be clones of the original + objects. Not all Python objects can be saved to a Python pickle file. This + limitation prevents any py5 object from being pickled. """ - return Sketch.degrees(radians) + return _py5sketch.save_pickle(obj, filename) + +############################################################################## +# module functions from print_tools.py +############################################################################## -def radians(degrees: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Converts a degree measurement to its corresponding value in radians. +def set_println_stream(println_stream: Any) -> None: + """Customize where the output of `println()` goes. Parameters ---------- - degrees: Union[float, npt.ArrayLike] - degree value to convert to radians + println_stream: Any + println stream object to be used by println method Notes ----- - Converts a degree measurement to its corresponding value in radians. Radians and - degrees are two ways of measuring the same thing. There are 360 degrees in a - circle and ``2*PI`` radians in a circle. For example, ``90° = PI/2 = - 1.5707964``. All trigonometric functions in py5 require their parameters to be - specified in radians. + Customize where the output of `println()` goes. - This function makes a call to the numpy ``radians()`` function. + When running a Sketch asynchronously through Jupyter Notebook, any `print` + statements using Python's builtin function will always appear in the output of + the currently active cell. This will rarely be desirable, as the active cell + will keep changing as the user executes code elsewhere in the notebook. The + `println()` method was created to provide users with print functionality in a + Sketch without having to cope with output moving from one cell to the next. Use + `set_println_stream` to change how the output is handled. The `println_stream` + object must provide `init()` and `print()` methods, as shown in the example. The + example demonstrates how to configure py5 to output text to an IPython Widget. """ - return Sketch.radians(degrees) + return _py5sketch.set_println_stream(println_stream) -def constrain(amt: Union[float, - npt.NDArray], - low: Union[float, - npt.NDArray], - high: Union[float, - npt.NDArray]) -> Union[float, - npt.NDArray]: - """Constrains a value to not exceed a maximum and minimum value. +def println( + *args, + sep: str = ' ', + end: str = '\n', + stderr: bool = False) -> None: + """Print text or other values to the screen. Parameters ---------- - amt: Union[float, npt.NDArray] - the value to constrain + args + values to be printed - high: Union[float, npt.NDArray] - minimum limit + end: str = '\\n' + string appended after the last value, defaults to newline character - low: Union[float, npt.NDArray] - maximum limit + sep: str = ' ' + string inserted between values, defaults to a space + + stderr: bool = False + use stderr instead of stdout Notes ----- - Constrains a value to not exceed a maximum and minimum value. + Print text or other values to the screen. For a Sketch running outside of a + Jupyter Notebook, this method will behave the same as the Python's builtin + `print` method. For Sketches running in a Jupyter Notebook, this will place text + in the output of the cell that made the `run_sketch()` call. + + When running a Sketch asynchronously through Jupyter Notebook, any `print` + statements using Python's builtin function will always appear in the output of + the currently active cell. This will rarely be desirable, as the active cell + will keep changing as the user executes code elsewhere in the notebook. This + method was created to provide users with print functionality in a Sketch without + having to cope with output moving from one cell to the next. + + Use `set_println_stream()` to customize the behavior of `println()`. """ - return Sketch.constrain(amt, low, high) + return _py5sketch.println(*args, sep=sep, end=end, stderr=stderr) +############################################################################## +# module functions from threads.py +############################################################################## -def remap(value: Union[float, - npt.NDArray], - start1: Union[float, - npt.NDArray], - stop1: Union[float, - npt.NDArray], - start2: Union[float, - npt.NDArray], - stop2: Union[float, - npt.NDArray]) -> Union[float, - npt.NDArray]: - """Re-maps a number from one range to another. + +def launch_thread( + f: Callable, + name: str = None, + *, + daemon: bool = True, + args: tuple = None, + kwargs: dict = None) -> str: + """Launch a new thread to execute a function in parallel with your Sketch code. Parameters ---------- - start1: Union[float, npt.NDArray] - lower bound of the value's current range + args: tuple = None + positional arguments to pass to the given function - start2: Union[float, npt.NDArray] - lower bound of the value's target range + daemon: bool = True + if the thread should be a daemon thread - stop1: Union[float, npt.NDArray] - upper bound of the value's current range + f: Callable + function to call in the launched thread - stop2: Union[float, npt.NDArray] - upper bound of the value's target range + kwargs: dict = None + keyword arguments to pass to the given function - value: Union[float, npt.NDArray] - the incoming value to be converted + name: str = None + name of thread to be created Notes ----- - Re-maps a number from one range to another. - - In the first example, the number 0.5 is converted from a value in the range of 0 - to 1 into a value that ranges from the left edge of the window (0) to the right - edge (``width``). - - As shown in the second example, numbers outside of the range are not clamped to - the minimum and maximum parameters values, because out-of-range values are often - intentional and useful. If that isn't what you want, try pairing this function - with ``constrain()``. + Launch a new thread to execute a function in parallel with your Sketch code. + This can be useful for executing non-py5 code that would otherwise slow down the + animation thread and reduce the Sketch's frame rate. - In Processing this functionality is provided by ``map()`` but was renamed in py5 - because of a name conflict with a builtin Python function. - """ - return Sketch.remap(value, start1, stop1, start2, stop2) + The `name` parameter is optional but useful if you want to monitor the thread + with other methods such as `has_thread()`. If the provided `name` is identical + to an already running thread, the running thread will first be stopped with a + call to `stop_thread()` with the `wait` parameter equal to `True`. + Use the `args` and `kwargs` parameters to pass positional and keyword arguments + to the function. -@overload -def dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, - npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: - """Calculates the distance between two points. + Use the `daemon` parameter to make the launched thread a daemon that will run + without blocking Python from exiting. This parameter defaults to `True`, meaning + that function execution can be interupted if the Python process exits. Note that + if the Python process continues running after the Sketch exits, which is + typically the case when using a Jupyter Notebook, this parameter won't have any + effect unless if you try to restart the Notebook kernel. Generally speaking, + setting this parameter to `False` causes problems but it is available for those + who really need it. See `stop_all_threads()` for a better approach to exit + threads. - Methods - ------- + The new thread is a Python thread, so all the usual caveats about the Global + Interpreter Lock (GIL) apply here. + """ + return _py5sketch.launch_thread( + f, name=name, daemon=daemon, args=args, kwargs=kwargs) - You can use any of the following signatures: - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] +def launch_promise_thread( + f: Callable, + name: str = None, + *, + daemon: bool = True, + args: tuple = None, + kwargs: dict = None) -> Py5Promise: + """Create a `Py5Promise` object that will store the returned result of a function + when that function completes. Parameters ---------- - x1: Union[float, npt.NDArray] - x-coordinate of the first point - - x2: Union[float, npt.NDArray] - x-coordinate of the second point + args: tuple = None + positional arguments to pass to the given function - y1: Union[float, npt.NDArray] - y-coordinate of the first point + daemon: bool = True + if the thread should be a daemon thread - y2: Union[float, npt.NDArray] - y-coordinate of the second point + f: Callable + function to call in the launched thread - z1: Union[float, npt.NDArray] - z-coordinate of the first point + kwargs: dict = None + keyword arguments to pass to the given function - z2: Union[float, npt.NDArray] - z-coordinate of the second point + name: str = None + name of thread to be created Notes ----- - Calculates the distance between two points. - """ - pass + Create a `Py5Promise` object that will store the returned result of a function + when that function completes. This can be useful for executing non-py5 code that + would otherwise slow down the animation thread and reduce the Sketch's frame + rate. + The `Py5Promise` object has an `is_ready` property that will be `True` when the + `result` property contains the value function `f` returned. Before then, the + `result` property will be `None`. -@overload -def dist(x1: Union[float, - npt.NDArray], - y1: Union[float, - npt.NDArray], - z1: Union[float, - npt.NDArray], - x2: Union[float, - npt.NDArray], - y2: Union[float, - npt.NDArray], - z2: Union[float, - npt.NDArray], - /) -> Union[float, - npt.NDArray]: - """Calculates the distance between two points. + The `name` parameter is optional but useful if you want to monitor the thread + with other methods such as `has_thread()`. If the provided `name` is identical + to an already running thread, the running thread will first be stopped with a + call to `stop_thread()` with the `wait` parameter equal to `True`. - Methods - ------- + Use the `args` and `kwargs` parameters to pass positional and keyword arguments + to the function. - You can use any of the following signatures: + Use the `daemon` parameter to make the launched thread a daemon that will run + without blocking Python from exiting. This parameter defaults to `True`, meaning + that function execution can be interupted if the Python process exits. Note that + if the Python process continues running after the Sketch exits, which is + typically the case when using a Jupyter Notebook, this parameter won't have any + effect unless if you try to restart the Notebook kernel. Generally speaking, + setting this parameter to `False` causes problems but it is available for those + who really need it. See `stop_all_threads()` for a better approach to exit + threads. - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + The new thread is a Python thread, so all the usual caveats about the Global + Interpreter Lock (GIL) apply here. + """ + return _py5sketch.launch_promise_thread( + f, name=name, daemon=daemon, args=args, kwargs=kwargs) + + +def launch_repeating_thread(f: Callable, name: str = None, *, + time_delay: float = 0, daemon: bool = True, + args: tuple = None, kwargs: dict = None) -> str: + """Launch a new thread that will repeatedly execute a function in parallel with + your Sketch code. Parameters ---------- - x1: Union[float, npt.NDArray] - x-coordinate of the first point + args: tuple = None + positional arguments to pass to the given function - x2: Union[float, npt.NDArray] - x-coordinate of the second point + daemon: bool = True + if the thread should be a daemon thread - y1: Union[float, npt.NDArray] - y-coordinate of the first point + f: Callable + function to call in the launched thread - y2: Union[float, npt.NDArray] - y-coordinate of the second point + kwargs: dict = None + keyword arguments to pass to the given function - z1: Union[float, npt.NDArray] - z-coordinate of the first point + name: str = None + name of thread to be created - z2: Union[float, npt.NDArray] - z-coordinate of the second point + time_delay: float = 0 + time delay in seconds between calls to the given function Notes ----- - Calculates the distance between two points. - """ - pass - + Launch a new thread that will repeatedly execute a function in parallel with + your Sketch code. This can be useful for executing non-py5 code that would + otherwise slow down the animation thread and reduce the Sketch's frame rate. -def dist(*args: Union[float, npt.NDArray]) -> float: - """Calculates the distance between two points. + Use the `time_delay` parameter to set the time in seconds between one call to + function `f` and the next call. Set this parameter to `0` if you want each call + to happen immediately after the previous call finishes. If the function `f` + takes longer than expected to finish, py5 will wait for it to finish before + making the next call. There will not be overlapping calls to function `f`. + + The `name` parameter is optional but useful if you want to monitor the thread + with other methods such as `has_thread()`. If the provided `name` is identical + to an already running thread, the running thread will first be stopped with a + call to `stop_thread()` with the `wait` parameter equal to `True`. + + Use the `args` and `kwargs` parameters to pass positional and keyword arguments + to the function. + + Use the `daemon` parameter to make the launched thread a daemon that will run + without blocking Python from exiting. This parameter defaults to `True`, meaning + that function execution can be interupted if the Python process exits. Note that + if the Python process continues running after the Sketch exits, which is + typically the case when using a Jupyter Notebook, this parameter won't have any + effect unless if you try to restart the Notebook kernel. Generally speaking, + setting this parameter to `False` causes problems but it is available for those + who really need it. See `stop_all_threads()` for a better approach to exit + threads. - Methods - ------- + The new thread is a Python thread, so all the usual caveats about the Global + Interpreter Lock (GIL) apply here. + """ + return _py5sketch.launch_repeating_thread( + f, + name=name, + time_delay=time_delay, + daemon=daemon, + args=args, + kwargs=kwargs) - You can use any of the following signatures: - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] +def has_thread(name: str) -> None: + """Determine if a thread of a given name exists and is currently running. Parameters ---------- - x1: Union[float, npt.NDArray] - x-coordinate of the first point + name: str + name of thread - x2: Union[float, npt.NDArray] - x-coordinate of the second point + Notes + ----- - y1: Union[float, npt.NDArray] - y-coordinate of the first point + Determine if a thread of a given name exists and is currently running. You can + get the list of all currently running threads with `list_threads()`. + """ + return _py5sketch.has_thread(name) - y2: Union[float, npt.NDArray] - y-coordinate of the second point - z1: Union[float, npt.NDArray] - z-coordinate of the first point +def join_thread(name: str, *, timeout: float = None) -> bool: + """Join the Python thread associated with the given thread name. - z2: Union[float, npt.NDArray] - z-coordinate of the second point + Parameters + ---------- + + name: str + name of thread + + timeout: float = None + maximum time in seconds to wait for the thread to join Notes ----- - Calculates the distance between two points. + Join the Python thread associated with the given thread name. The + `join_thread()` method will wait until the named thread has finished executing + before returning. Use the `timeout` parameter to set an upper limit for the + number of seconds to wait. This method will return right away if the named + thread does not exist or the thread has already finished executing. You can get + the list of all currently running threads with `list_threads()`. + + This method will return `True` if the named thread has completed execution and + `False` if the named thread is still executing. It will only return `False` if + you use the `timeout` parameter and the method is not able to join with the + thread within that time limit. """ - return Sketch.dist(*args) + return _py5sketch.join_thread(name, timeout=timeout) -def lerp(start: Union[float, - npt.NDArray], - stop: Union[float, - npt.NDArray], - amt: Union[float, - npt.NDArray]) -> Union[float, - npt.NDArray]: - """Calculates a number between two numbers at a specific increment. +def stop_thread(name: str, wait: bool = False) -> None: + """Stop a thread of a given name. Parameters ---------- - amt: Union[float, npt.NDArray] - float between 0.0 and 1.0 - - start: Union[float, npt.NDArray] - first value + name: str + name of thread - stop: Union[float, npt.NDArray] - second value + wait: bool = False + wait for thread to exit before returning Notes ----- - Calculates a number between two numbers at a specific increment. The ``amt`` - parameter is the amount to interpolate between the two values where 0.0 equal to - the first point, 0.1 is very near the first point, 0.5 is half-way in between, - etc. The lerp function is convenient for creating motion along a straight path - and for drawing dotted lines. If the ``amt`` parameter is greater than 1.0 or - less than 0.0, the interpolated value will be outside of the range specified by - the ``start`` and ``stop`` parameter values. - """ - return Sketch.lerp(start, stop, amt) - + Stop a thread of a given name. The `wait` parameter determines if the method + call will return right away or wait for the thread to exit. -@overload -def mag(a: Union[float, npt.NDArray], - b: Union[float, npt.NDArray], /) -> float: - """Calculates the magnitude (or length) of a vector. + This won't do anything useful if the thread was launched with either + `launch_thread()` or `launch_promise_thread()` and the `wait` parameter is + `False`. Non-repeating threads are executed once and will stop when they + complete execution. Setting the `wait` parameter to `True` will merely block + until the thread exits on its own. Killing off a running thread in Python is + complicated and py5 cannot do that for you. If you want a thread to perform some + action repeatedly and be interuptable, use `launch_repeating_thread()` instead. - Methods - ------- + Use `has_thread()` to determine if a thread of a given name exists and + `list_threads()` to get a list of all thread names. Use `stop_all_threads()` to + stop all threads. + """ + return _py5sketch.stop_thread(name, wait=wait) - You can use any of the following signatures: - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float +def stop_all_threads(wait: bool = False) -> None: + """Stop all running threads. Parameters ---------- - a: Union[float, npt.NDArray] - first value + wait: bool = False + wait for thread to exit before returning - b: Union[float, npt.NDArray] - second value + Notes + ----- - c: Union[float, npt.NDArray] - third value + Stop all running threads. The `wait` parameter determines if the method call + will return right away or wait for the threads to exit. + + When the Sketch shuts down, `stop_all_threads(wait=False)` is called for you. If + you would rather the Sketch waited for threads to exit, create an `exiting` + method and make a call to `stop_all_threads(wait=True)`. + """ + return _py5sketch.stop_all_threads(wait=wait) + + +def list_threads() -> None: + """List the names of all of the currently running threads. Notes ----- - Calculates the magnitude (or length) of a vector. A vector is a direction in - space commonly used in computer graphics and linear algebra. Because it has no - "start" position, the magnitude of a vector can be thought of as the distance - from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is - a shortcut for writing ``dist(0, 0, x, y)``. + List the names of all of the currently running threads. The names of previously + launched threads that have exited will be removed from the list. """ - pass + return _py5sketch.list_threads() +############################################################################## +# module functions from pixels.py +############################################################################## -@overload -def mag(a: Union[float, npt.NDArray], b: Union[float, - npt.NDArray], c: Union[float, npt.NDArray], /) -> float: - """Calculates the magnitude (or length) of a vector. - Methods - ------- +def load_np_pixels() -> None: + """Loads the pixel data of the current display window into the `np_pixels[]` array. - You can use any of the following signatures: + Notes + ----- - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float + Loads the pixel data of the current display window into the `np_pixels[]` array. + This method must always be called before reading from or writing to + `np_pixels[]`. Subsequent changes to the display window will not be reflected in + `np_pixels[]` until `load_np_pixels()` is called again. - Parameters - ---------- + The `load_np_pixels()` method is similar to `load_pixels()` in that + `load_np_pixels()` must be called before reading from or writing to + `np_pixels[]` just as `load_pixels()` must be called before reading from or + writing to `pixels[]`. - a: Union[float, npt.NDArray] - first value + Note that `load_np_pixels()` will as a side effect call `load_pixels()`, so if + your code needs to read `np_pixels[]` and `pixels[]` simultaneously, there is no + need for a separate call to `load_pixels()`. However, be aware that modifying + both `np_pixels[]` and `pixels[]` simultaneously will likely result in the + updates to `pixels[]` being discarded. + """ + return _py5sketch.load_np_pixels() - b: Union[float, npt.NDArray] - second value - c: Union[float, npt.NDArray] - third value +def update_np_pixels() -> None: + """Updates the display window with the data in the `np_pixels[]` array. Notes ----- - Calculates the magnitude (or length) of a vector. A vector is a direction in - space commonly used in computer graphics and linear algebra. Because it has no - "start" position, the magnitude of a vector can be thought of as the distance - from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is - a shortcut for writing ``dist(0, 0, x, y)``. - """ - pass + Updates the display window with the data in the `np_pixels[]` array. Use in + conjunction with `load_np_pixels()`. If you're only reading pixels from the + array, there's no need to call `update_np_pixels()` — updating is only necessary + to apply changes. + The `update_np_pixels()` method is similar to `update_pixels()` in that + `update_np_pixels()` must be called after modifying `np_pixels[]` just as + `update_pixels()` must be called after modifying `pixels[]`. + """ + return _py5sketch.update_np_pixels() -def mag(*args: Union[float, npt.NDArray]) -> float: - """Calculates the magnitude (or length) of a vector. - Methods - ------- +np_pixels: npt.NDArray[np.uint8] = None - You can use any of the following signatures: - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float +def set_np_pixels(array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None: + """Set the entire contents of `np_pixels[]` to the contents of another properly + sized and typed numpy array. Parameters ---------- - a: Union[float, npt.NDArray] - first value + array: npt.NDArray[np.uint8] + properly sized numpy array to be copied to np_pixels[] - b: Union[float, npt.NDArray] - second value - - c: Union[float, npt.NDArray] - third value + bands: str = 'ARGB' + color channels in the array's third dimension Notes ----- - Calculates the magnitude (or length) of a vector. A vector is a direction in - space commonly used in computer graphics and linear algebra. Because it has no - "start" position, the magnitude of a vector can be thought of as the distance - from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is - a shortcut for writing ``dist(0, 0, x, y)``. + Set the entire contents of `np_pixels[]` to the contents of another properly + sized and typed numpy array. The size of `array`'s first and second dimensions + must match the height and width of the Sketch window, respectively. The array's + `dtype` must be `np.uint8`. + + The `bands` parameter is used to interpret the `array`'s color channel dimension + (the array's third dimension). It can be one of `'L'` (single-channel + grayscale), `'ARGB'`, `'RGB'`, or `'RGBA'`. If there is no alpha channel, + `array` is assumed to have no transparency, but recall that the display window's + pixels can never be transparent so any transparency in `array` will have no + effect. If the `bands` parameter is `'L'`, `array`'s third dimension is + optional. + + This method makes its own calls to `load_np_pixels()` and `update_np_pixels()` + so there is no need to call either explicitly. + + This method exists because setting the array contents with the code + `py5.np_pixels = array` will cause an error, while the correct syntax, + `py5.np_pixels[:] = array`, might also be unintuitive for beginners. """ - return Sketch.mag(*args) + return _py5sketch.set_np_pixels(array, bands=bands) -def norm(value: Union[float, - npt.NDArray], - start: Union[float, - npt.NDArray], - stop: Union[float, - npt.NDArray]) -> Union[float, - npt.NDArray]: - """Normalizes a number from another range into a value between 0 and 1. +def save(filename: Union[str, + Path, + BytesIO], + *, + format: str = None, + drop_alpha: bool = True, + use_thread: bool = False, + **params) -> None: + """Save the drawing surface to an image file. Parameters ---------- - start: Union[float, npt.NDArray] - lower bound of the value's current range + drop_alpha: bool = True + remove the alpha channel when saving the image - stop: Union[float, npt.NDArray] - upper bound of the value's current range + filename: Union[str, Path, BytesIO] + output filename - value: Union[float, npt.NDArray] - the incoming value to be converted + format: str = None + image format, if not determined from filename extension + + params + keyword arguments to pass to the PIL.Image save method + + use_thread: bool = False + write file in separate thread Notes ----- - Normalizes a number from another range into a value between 0 and 1. Identical - to ``remap(value, low, high, 0, 1)``. + Save the drawing surface to an image file. This method uses the Python library + Pillow to write the image, so it can save images in any format that that library + supports. - Numbers outside of the range are not clamped to 0 and 1, because out-of-range - values are often intentional and useful. (See the second example.) If that isn't - what you want, try pairing this function with ``constrain()``. + Use the `drop_alpha` parameter to drop the alpha channel from the image. This + defaults to `True`. Some image formats such as JPG do not support alpha + channels, and Pillow will throw an error if you try to save an image with the + alpha channel in that format. + + The `use_thread` parameter will save the image in a separate Python thread. This + improves performance by returning before the image has actually been written to + the file. """ - return Sketch.norm(value, start, stop) + return _py5sketch.save( + filename, + format=format, + drop_alpha=drop_alpha, + use_thread=use_thread, + **params) + +############################################################################## +# module functions from math.py +############################################################################## -def sq(value: Union[float, npt.NDArray]) -> Union[float, npt.NDArray]: - """Squares a number (multiplies a number by itself). +def hex_color(color: int) -> str: + """Convert a color value to a hex color string. Parameters ---------- - value: Union[float, npt.NDArray] - number to square + color: int + any color value Notes ----- - Squares a number (multiplies a number by itself). The result is always a - positive number, as multiplying two negative numbers always yields a positive - result. For example, ``-1 * -1 = 1``. + Convert a color value to a hex color string. Processing and py5 store color + values in 32 bit integers that are inconvenient for a human to parse. To + interpret these values, one can use methods like `red()`, `green()`, and + `blue()` to extract color channel values from the 32 bit integers. This method + provides an alternative approach, converting the 32 bit integer into a string + such as `'#0F3FF0FF'`. The hex string has 8 hexadecimal values following a `#` + character. The first two values represent the red value, the next two green, the + next two blue, and the last two alpha. This is consistent with CSS 8 digit hex + colors. + + Conveniently, the hex color string returned by this method can also be used as + parameter for other methods that accept color values. Observe how this is done + in the example code. """ - return Sketch.sq(value) + return Sketch.hex_color(color) -def sqrt(value: Union[float, npt.NDArray] - ) -> Union[float, complex, npt.NDArray]: - """Calculates the square root of a number. +def sin(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Calculates the sine of an angle. Parameters ---------- - value: Union[float, npt.NDArray] - value to calculate the square root of + angle: Union[float, npt.ArrayLike] + angle in radians Notes ----- - Calculates the square root of a number. The square root of a positive number is - always positive, even though there may be a valid negative root. The square root - of a negative number is a complex number. In either case, the square root ``s`` - of number ``a`` is such that ``s*s = a``. It is the opposite of squaring. + Calculates the sine of an angle. This function expects the values of the angle + parameter to be provided in radians (values from `0` to `TWO_PI`). Values are + returned in the range -1 to 1. - Python supports complex numbers, but such values cannot be passed to py5 drawing - functions. When using the ``sqrt()`` function, you should check if the result is - complex before using the value. You can also extract the real and imaginary - components of the complex value with ``.real`` and ``.imag``. See the second - example to learn how to do both of these things. + This function makes a call to the numpy `sin()` function. """ - return Sketch.sqrt(value) + return Sketch.sin(angle) -def floor(value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]: - """Calculates the closest int value that is less than or equal to the value of the - parameter. +def cos(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Calculates the cosine of an angle. Parameters ---------- - value: Union[float, npt.ArrayLike] - number to round down + angle: Union[float, npt.ArrayLike] + angle in radians Notes ----- - Calculates the closest int value that is less than or equal to the value of the - parameter. + Calculates the cosine of an angle. This function expects the values of the angle + parameter to be provided in radians (values from `0` to `TWO_PI`). Values are + returned in the range -1 to 1. - This function makes a call to the numpy ``floor()`` function. + This function makes a call to the numpy `cos()` function. """ - return Sketch.floor(value) + return Sketch.cos(angle) -def ceil(value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]: - """Calculates the closest int value that is greater than or equal to the value of - the parameter. +def tan(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Calculates the ratio of the sine and cosine of an angle. Parameters ---------- - value: Union[float, npt.ArrayLike] - number to round up + angle: Union[float, npt.ArrayLike] + angle in radians Notes ----- - Calculates the closest int value that is greater than or equal to the value of - the parameter. + Calculates the ratio of the sine and cosine of an angle. This function expects + the values of the angle parameter to be provided in radians (values from `0` to + `TWO_PI`). Values are returned in the range infinity to -infinity. - This function makes a call to the numpy ``ceil()`` function. + This function makes a call to the numpy `tan()` function. """ - return Sketch.ceil(value) + return Sketch.tan(angle) -def exp(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Returns Euler's number e (2.71828...) raised to the power of the ``n`` - parameter. +def asin(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """The inverse of `sin()`, returns the arc sine of a value. Parameters ---------- value: Union[float, npt.ArrayLike] - exponent to raise + value in the range of -1 to 1 whose arc sine is to be returned Notes ----- - Returns Euler's number e (2.71828...) raised to the power of the ``n`` - parameter. This function is the compliment to ``log()``. + The inverse of `sin()`, returns the arc sine of a value. This function expects + the values in the range of -1 to 1 and values are returned in the range + `-HALF_PI` to `HALF_PI`. - This function makes a call to the numpy ``exp()`` function. + This function makes a call to the numpy `asin()` function. """ - return Sketch.exp(value) + return Sketch.asin(value) -def log(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Calculates the natural logarithm (the base-e logarithm) of a number. +def acos(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """The inverse of `cos()`, returns the arc cosine of a value. Parameters ---------- value: Union[float, npt.ArrayLike] - number greater than 0.0 + value in the range of -1 to 1 whose arc cosine is to be returned Notes ----- - Calculates the natural logarithm (the base-e logarithm) of a number. This - function expects the ``n`` parameter to be a value greater than 0.0. This - function is the compliment to ``exp()``. + The inverse of `cos()`, returns the arc cosine of a value. This function expects + the values in the range of -1 to 1 and values are returned in the range `0` to + `PI`. - This function makes a call to the numpy ``log()`` function. If the ``n`` - parameter is less than or equal to 0.0, you will see a ``RuntimeWarning`` and - the returned result will be numpy's Not-a-Number value, ``np.nan``. + This function makes a call to the numpy `acos()` function. """ - return Sketch.log(value) - - -np_random: np.random.Generator = None + return Sketch.acos(value) -def random_seed(seed: int) -> None: - """Sets the seed value for py5's random functions. +def atan(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """The inverse of `tan()`, returns the arc tangent of a value. Parameters ---------- - seed: int - seed value + value: Union[float, npt.ArrayLike] + value whose arc tangent is to be returned Notes ----- - Sets the seed value for py5's random functions. This includes ``random()``, - ``random_int()``, ``random_choice()``, and ``random_gaussian()``. By default, - all of these functions would produce different results each time a program is - run. Set the seed parameter to a constant value to return the same pseudo-random - numbers each time the software is run. - """ - return _py5sketch.random_seed(seed) - - -@overload -def random() -> float: - """Generates random numbers. + The inverse of `tan()`, returns the arc tangent of a value. This function + expects the values in the range of -Infinity to Infinity and values are returned + in the range `-HALF_PI` to `HALF_PI`. - Methods - ------- + This function makes a call to the numpy `atan()` function. + """ + return Sketch.atan(value) - You can use any of the following signatures: - * random() -> float - * random(high: float, /) -> float - * random(low: float, high: float, /) -> float +def atan2(y: Union[float, npt.ArrayLike], x: Union[float, + npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Calculates the angle (in radians) from a specified point to the coordinate + origin as measured from the positive x-axis. Parameters ---------- - high: float - upper limit + x: Union[float, npt.ArrayLike] + x-coordinate of the point - low: float - lower limit + y: Union[float, npt.ArrayLike] + y-coordinate of the point Notes ----- - Generates random numbers. Each time the ``random()`` function is called, it - returns an unexpected value within the specified range. This function's - randomness can be influenced by ``random_seed()``. - - If no parameters are passed to the function, it will return a float between zero - and one. - - If only one parameter is passed to the function, it will return a float between - zero and the value of the ``high`` parameter. For example, ``random(5)`` returns - values between 0 and 5 (starting at zero, and up to, but not including, 5). - - If two parameters are specified, the function will return a float with a value - between the two values. For example, ``random(-5, 10.2)`` returns values - starting at -5 and up to (but not including) 10.2. To convert a floating-point - random number to an integer, use the ``int()`` function, or alternatively, - consider using ``random_int()``. + Calculates the angle (in radians) from a specified point to the coordinate + origin as measured from the positive x-axis. Values are returned as a float in + the range from `PI` to `-PI`. The `atan2()` function is most often used for + orienting geometry to the position of the cursor. Note: The y-coordinate of the + point is the first parameter, and the x-coordinate is the second parameter, due + the the structure of calculating the tangent. - This function makes calls to numpy to generate the random values. + This function makes a call to the numpy `atan2()` function. """ - pass - - -@overload -def random(high: float, /) -> float: - """Generates random numbers. - - Methods - ------- + return Sketch.atan2(y, x) - You can use any of the following signatures: - * random() -> float - * random(high: float, /) -> float - * random(low: float, high: float, /) -> float +def degrees(radians: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Converts a radian measurement to its corresponding value in degrees. Parameters ---------- - high: float - upper limit - - low: float - lower limit + radians: Union[float, npt.ArrayLike] + radian value to convert to degrees Notes ----- - Generates random numbers. Each time the ``random()`` function is called, it - returns an unexpected value within the specified range. This function's - randomness can be influenced by ``random_seed()``. - - If no parameters are passed to the function, it will return a float between zero - and one. - - If only one parameter is passed to the function, it will return a float between - zero and the value of the ``high`` parameter. For example, ``random(5)`` returns - values between 0 and 5 (starting at zero, and up to, but not including, 5). - - If two parameters are specified, the function will return a float with a value - between the two values. For example, ``random(-5, 10.2)`` returns values - starting at -5 and up to (but not including) 10.2. To convert a floating-point - random number to an integer, use the ``int()`` function, or alternatively, - consider using ``random_int()``. + Converts a radian measurement to its corresponding value in degrees. Radians and + degrees are two ways of measuring the same thing. There are 360 degrees in a + circle and `2*PI` radians in a circle. For example, `90° = PI/2 = 1.5707964`. + All trigonometric functions in py5 require their parameters to be specified in + radians. - This function makes calls to numpy to generate the random values. + This function makes a call to the numpy `degrees()` function. """ - pass - - -@overload -def random(low: float, high: float, /) -> float: - """Generates random numbers. - - Methods - ------- + return Sketch.degrees(radians) - You can use any of the following signatures: - * random() -> float - * random(high: float, /) -> float - * random(low: float, high: float, /) -> float +def radians(degrees: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Converts a degree measurement to its corresponding value in radians. Parameters ---------- - high: float - upper limit - - low: float - lower limit + degrees: Union[float, npt.ArrayLike] + degree value to convert to radians Notes ----- - Generates random numbers. Each time the ``random()`` function is called, it - returns an unexpected value within the specified range. This function's - randomness can be influenced by ``random_seed()``. - - If no parameters are passed to the function, it will return a float between zero - and one. - - If only one parameter is passed to the function, it will return a float between - zero and the value of the ``high`` parameter. For example, ``random(5)`` returns - values between 0 and 5 (starting at zero, and up to, but not including, 5). - - If two parameters are specified, the function will return a float with a value - between the two values. For example, ``random(-5, 10.2)`` returns values - starting at -5 and up to (but not including) 10.2. To convert a floating-point - random number to an integer, use the ``int()`` function, or alternatively, - consider using ``random_int()``. + Converts a degree measurement to its corresponding value in radians. Radians and + degrees are two ways of measuring the same thing. There are 360 degrees in a + circle and `2*PI` radians in a circle. For example, `90° = PI/2 = 1.5707964`. + All trigonometric functions in py5 require their parameters to be specified in + radians. - This function makes calls to numpy to generate the random values. + This function makes a call to the numpy `radians()` function. """ - pass - - -def random(*args: float) -> float: - """Generates random numbers. - - Methods - ------- + return Sketch.radians(degrees) - You can use any of the following signatures: - * random() -> float - * random(high: float, /) -> float - * random(low: float, high: float, /) -> float +def constrain(amt: Union[float, + npt.NDArray], + low: Union[float, + npt.NDArray], + high: Union[float, + npt.NDArray]) -> Union[float, + npt.NDArray]: + """Constrains a value to not exceed a maximum and minimum value. Parameters ---------- - high: float - upper limit + amt: Union[float, npt.NDArray] + the value to constrain - low: float - lower limit + high: Union[float, npt.NDArray] + minimum limit + + low: Union[float, npt.NDArray] + maximum limit Notes ----- - Generates random numbers. Each time the ``random()`` function is called, it - returns an unexpected value within the specified range. This function's - randomness can be influenced by ``random_seed()``. - - If no parameters are passed to the function, it will return a float between zero - and one. - - If only one parameter is passed to the function, it will return a float between - zero and the value of the ``high`` parameter. For example, ``random(5)`` returns - values between 0 and 5 (starting at zero, and up to, but not including, 5). - - If two parameters are specified, the function will return a float with a value - between the two values. For example, ``random(-5, 10.2)`` returns values - starting at -5 and up to (but not including) 10.2. To convert a floating-point - random number to an integer, use the ``int()`` function, or alternatively, - consider using ``random_int()``. - - This function makes calls to numpy to generate the random values. + Constrains a value to not exceed a maximum and minimum value. """ - return _py5sketch.random(*args) + return Sketch.constrain(amt, low, high) -@overload -def random_int() -> int: - """Generates random integers. +def remap(value: Union[float, + npt.NDArray], + start1: Union[float, + npt.NDArray], + stop1: Union[float, + npt.NDArray], + start2: Union[float, + npt.NDArray], + stop2: Union[float, + npt.NDArray]) -> Union[float, + npt.NDArray]: + """Re-maps a number from one range to another. - Methods - ------- + Parameters + ---------- - You can use any of the following signatures: + start1: Union[float, npt.NDArray] + lower bound of the value's current range - * random_int() -> int - * random_int(high: int, /) -> int - * random_int(low: int, high: int, /) -> int + start2: Union[float, npt.NDArray] + lower bound of the value's target range - Parameters - ---------- + stop1: Union[float, npt.NDArray] + upper bound of the value's current range - high: int - upper limit + stop2: Union[float, npt.NDArray] + upper bound of the value's target range - low: int - lower limit + value: Union[float, npt.NDArray] + the incoming value to be converted Notes ----- - Generates random integers. Each time the ``random_int()`` function is called, it - returns an unexpected integer within the specified range. This function's - randomness can be influenced by ``random_seed()``. - - If no parameters are passed to the function, it will return either 0 or 1. - Recall that in a Python boolean expression, 0 evaluates to ``False`` and 1 - evaluates to ``True``. This is equivalent to a coin toss. - - If only one parameter is passed to the function, it will return an integer - between zero and the value of the ``high`` parameter, inclusive. For example, - ``random(5)`` returns one of 0, 1, 2, 3, 4, or 5. + Re-maps a number from one range to another. - If two parameters are specified, the function will return an integer with a - value between the two values, inclusive. For example, ``random(2, 5)`` returns - one of 2, 3, 4, or 5. + In the first example, the number 0.5 is converted from a value in the range of 0 + to 1 into a value that ranges from the left edge of the window (0) to the right + edge (`width`). - If you want to pick a random object from a list, recall that Python uses zero- - indexing, so the first index value is 0 and the final index value is one less - than the list length. Therefore, to pick a random index to use in the list - ``words``, your code should be ``random_int(len(words)-1)``. Omitting the ``-1`` - will (occasionally) result in an index out of range error. Alternatively, you - can also use ``random_choice()`` to pick a random object from a list. + As shown in the second example, numbers outside of the range are not clamped to + the minimum and maximum parameters values, because out-of-range values are often + intentional and useful. If that isn't what you want, try pairing this function + with `constrain()`. - This function makes calls to numpy to generate the random integers. + In Processing this functionality is provided by `map()` but was renamed in py5 + because of a name conflict with a builtin Python function. """ - pass + return Sketch.remap(value, start1, stop1, start2, stop2) @overload -def random_int(high: int, /) -> int: - """Generates random integers. +def dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, + npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: + """Calculates the distance between two points. Methods ------- You can use any of the following signatures: - * random_int() -> int - * random_int(high: int, /) -> int - * random_int(low: int, high: int, /) -> int + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] Parameters ---------- - high: int - upper limit - - low: int - lower limit + x1: Union[float, npt.NDArray] + x-coordinate of the first point - Notes - ----- + x2: Union[float, npt.NDArray] + x-coordinate of the second point - Generates random integers. Each time the ``random_int()`` function is called, it - returns an unexpected integer within the specified range. This function's - randomness can be influenced by ``random_seed()``. + y1: Union[float, npt.NDArray] + y-coordinate of the first point - If no parameters are passed to the function, it will return either 0 or 1. - Recall that in a Python boolean expression, 0 evaluates to ``False`` and 1 - evaluates to ``True``. This is equivalent to a coin toss. + y2: Union[float, npt.NDArray] + y-coordinate of the second point - If only one parameter is passed to the function, it will return an integer - between zero and the value of the ``high`` parameter, inclusive. For example, - ``random(5)`` returns one of 0, 1, 2, 3, 4, or 5. + z1: Union[float, npt.NDArray] + z-coordinate of the first point - If two parameters are specified, the function will return an integer with a - value between the two values, inclusive. For example, ``random(2, 5)`` returns - one of 2, 3, 4, or 5. + z2: Union[float, npt.NDArray] + z-coordinate of the second point - If you want to pick a random object from a list, recall that Python uses zero- - indexing, so the first index value is 0 and the final index value is one less - than the list length. Therefore, to pick a random index to use in the list - ``words``, your code should be ``random_int(len(words)-1)``. Omitting the ``-1`` - will (occasionally) result in an index out of range error. Alternatively, you - can also use ``random_choice()`` to pick a random object from a list. + Notes + ----- - This function makes calls to numpy to generate the random integers. + Calculates the distance between two points. """ pass @overload -def random_int(low: int, high: int, /) -> int: - """Generates random integers. +def dist(x1: Union[float, + npt.NDArray], + y1: Union[float, + npt.NDArray], + z1: Union[float, + npt.NDArray], + x2: Union[float, + npt.NDArray], + y2: Union[float, + npt.NDArray], + z2: Union[float, + npt.NDArray], + /) -> Union[float, + npt.NDArray]: + """Calculates the distance between two points. Methods ------- You can use any of the following signatures: - * random_int() -> int - * random_int(high: int, /) -> int - * random_int(low: int, high: int, /) -> int + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] Parameters ---------- - high: int - upper limit - - low: int - lower limit + x1: Union[float, npt.NDArray] + x-coordinate of the first point - Notes - ----- + x2: Union[float, npt.NDArray] + x-coordinate of the second point - Generates random integers. Each time the ``random_int()`` function is called, it - returns an unexpected integer within the specified range. This function's - randomness can be influenced by ``random_seed()``. + y1: Union[float, npt.NDArray] + y-coordinate of the first point - If no parameters are passed to the function, it will return either 0 or 1. - Recall that in a Python boolean expression, 0 evaluates to ``False`` and 1 - evaluates to ``True``. This is equivalent to a coin toss. + y2: Union[float, npt.NDArray] + y-coordinate of the second point - If only one parameter is passed to the function, it will return an integer - between zero and the value of the ``high`` parameter, inclusive. For example, - ``random(5)`` returns one of 0, 1, 2, 3, 4, or 5. + z1: Union[float, npt.NDArray] + z-coordinate of the first point - If two parameters are specified, the function will return an integer with a - value between the two values, inclusive. For example, ``random(2, 5)`` returns - one of 2, 3, 4, or 5. + z2: Union[float, npt.NDArray] + z-coordinate of the second point - If you want to pick a random object from a list, recall that Python uses zero- - indexing, so the first index value is 0 and the final index value is one less - than the list length. Therefore, to pick a random index to use in the list - ``words``, your code should be ``random_int(len(words)-1)``. Omitting the ``-1`` - will (occasionally) result in an index out of range error. Alternatively, you - can also use ``random_choice()`` to pick a random object from a list. + Notes + ----- - This function makes calls to numpy to generate the random integers. + Calculates the distance between two points. """ pass -def random_int(*args: int) -> int: - """Generates random integers. +def dist(*args: Union[float, npt.NDArray]) -> float: + """Calculates the distance between two points. Methods ------- You can use any of the following signatures: - * random_int() -> int - * random_int(high: int, /) -> int - * random_int(low: int, high: int, /) -> int + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] Parameters ---------- - high: int - upper limit - - low: int - lower limit + x1: Union[float, npt.NDArray] + x-coordinate of the first point - Notes - ----- + x2: Union[float, npt.NDArray] + x-coordinate of the second point - Generates random integers. Each time the ``random_int()`` function is called, it - returns an unexpected integer within the specified range. This function's - randomness can be influenced by ``random_seed()``. + y1: Union[float, npt.NDArray] + y-coordinate of the first point - If no parameters are passed to the function, it will return either 0 or 1. - Recall that in a Python boolean expression, 0 evaluates to ``False`` and 1 - evaluates to ``True``. This is equivalent to a coin toss. + y2: Union[float, npt.NDArray] + y-coordinate of the second point - If only one parameter is passed to the function, it will return an integer - between zero and the value of the ``high`` parameter, inclusive. For example, - ``random(5)`` returns one of 0, 1, 2, 3, 4, or 5. + z1: Union[float, npt.NDArray] + z-coordinate of the first point - If two parameters are specified, the function will return an integer with a - value between the two values, inclusive. For example, ``random(2, 5)`` returns - one of 2, 3, 4, or 5. + z2: Union[float, npt.NDArray] + z-coordinate of the second point - If you want to pick a random object from a list, recall that Python uses zero- - indexing, so the first index value is 0 and the final index value is one less - than the list length. Therefore, to pick a random index to use in the list - ``words``, your code should be ``random_int(len(words)-1)``. Omitting the ``-1`` - will (occasionally) result in an index out of range error. Alternatively, you - can also use ``random_choice()`` to pick a random object from a list. + Notes + ----- - This function makes calls to numpy to generate the random integers. + Calculates the distance between two points. """ - return _py5sketch.random_int(*args) - - -def random_choice( - objects: list[Any], - size: int = 1, - replace: bool = True) -> Any: - """Select random items from a list. + return Sketch.dist(*args) - Parameters - ---------- - objects: list[Any] - list of objects to choose from +def lerp(start: Union[float, + npt.NDArray], + stop: Union[float, + npt.NDArray], + amt: Union[float, + npt.NDArray]) -> Union[float, + npt.NDArray]: + """Calculates a number between two numbers at a specific increment. - replace: bool=True - whether to select random items with or without replacement + Parameters + ---------- - size: int=1 - number of random items to select + amt: Union[float, npt.NDArray] + float between 0.0 and 1.0 + + start: Union[float, npt.NDArray] + first value + + stop: Union[float, npt.NDArray] + second value Notes ----- - Select random items from a list. The list items can be of any type. If multiple - items are selected, this function will by default allow the same item to be - selected multiple times. Set the ``replace`` parameter to ``False`` to prevent - the same item from being selected multiple times. - - This function's randomness can be influenced by ``random_seed()``, and makes - calls to numpy to select the random items. + Calculates a number between two numbers at a specific increment. The `amt` + parameter is the amount to interpolate between the two values where 0.0 equal to + the first point, 0.1 is very near the first point, 0.5 is half-way in between, + etc. The lerp function is convenient for creating motion along a straight path + and for drawing dotted lines. If the `amt` parameter is greater than 1.0 or less + than 0.0, the interpolated value will be outside of the range specified by the + `start` and `stop` parameter values. """ - return _py5sketch.random_choice(objects, size=size, replace=replace) + return Sketch.lerp(start, stop, amt) @overload -def random_gaussian() -> float: - """Generates random gaussian values. +def mag(a: Union[float, npt.NDArray], + b: Union[float, npt.NDArray], /) -> float: + """Calculates the magnitude (or length) of a vector. Methods ------- You can use any of the following signatures: - * random_gaussian() -> float - * random_gaussian(loc: float, /) -> float - * random_gaussian(loc: float, scale: float, /) -> float + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float Parameters ---------- - loc: float - average of randomly selected numbers + a: Union[float, npt.NDArray] + first value - scale: float - standard deviation of randomly selected numbers + b: Union[float, npt.NDArray] + second value + + c: Union[float, npt.NDArray] + third value Notes ----- - Generates random gaussian values. Each time the ``random_gaussian()`` function - is called, it returns an unexpected float with a probability distribution set by - the parameters. This function's randomness can be influenced by - ``random_seed()``. - - If no parameters are passed to the function, returned values will have an - average of 0 and a standard deviation of 1. Although there is theoretically no - minimum or maximum value that this function might return, in practice returned - values will be within plus or minus one standard deviation of the mean 68% of - the time and within two standard devations 95% of the time. Values farther and - farther from the mean become increasingly less likely. - - If only one parameter is passed to the function, that parameter will be used as - the average instead of 0. If two parameters are called, those values will be - used as the average and standard deviation. - - This function makes calls to numpy to generate the random values. + Calculates the magnitude (or length) of a vector. A vector is a direction in + space commonly used in computer graphics and linear algebra. Because it has no + "start" position, the magnitude of a vector can be thought of as the distance + from the coordinate `(0, 0)` to its `(x, y)` value. Therefore, `mag()` is a + shortcut for writing `dist(0, 0, x, y)`. """ pass @overload -def random_gaussian(loc: float, /) -> float: - """Generates random gaussian values. +def mag(a: Union[float, npt.NDArray], b: Union[float, + npt.NDArray], c: Union[float, npt.NDArray], /) -> float: + """Calculates the magnitude (or length) of a vector. Methods ------- You can use any of the following signatures: - * random_gaussian() -> float - * random_gaussian(loc: float, /) -> float - * random_gaussian(loc: float, scale: float, /) -> float + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float Parameters ---------- - loc: float - average of randomly selected numbers + a: Union[float, npt.NDArray] + first value - scale: float - standard deviation of randomly selected numbers + b: Union[float, npt.NDArray] + second value + + c: Union[float, npt.NDArray] + third value Notes ----- - Generates random gaussian values. Each time the ``random_gaussian()`` function - is called, it returns an unexpected float with a probability distribution set by - the parameters. This function's randomness can be influenced by - ``random_seed()``. - - If no parameters are passed to the function, returned values will have an - average of 0 and a standard deviation of 1. Although there is theoretically no - minimum or maximum value that this function might return, in practice returned - values will be within plus or minus one standard deviation of the mean 68% of - the time and within two standard devations 95% of the time. Values farther and - farther from the mean become increasingly less likely. - - If only one parameter is passed to the function, that parameter will be used as - the average instead of 0. If two parameters are called, those values will be - used as the average and standard deviation. - - This function makes calls to numpy to generate the random values. + Calculates the magnitude (or length) of a vector. A vector is a direction in + space commonly used in computer graphics and linear algebra. Because it has no + "start" position, the magnitude of a vector can be thought of as the distance + from the coordinate `(0, 0)` to its `(x, y)` value. Therefore, `mag()` is a + shortcut for writing `dist(0, 0, x, y)`. """ pass -@overload -def random_gaussian(loc: float, scale: float, /) -> float: - """Generates random gaussian values. +def mag(*args: Union[float, npt.NDArray]) -> float: + """Calculates the magnitude (or length) of a vector. Methods ------- You can use any of the following signatures: - * random_gaussian() -> float - * random_gaussian(loc: float, /) -> float - * random_gaussian(loc: float, scale: float, /) -> float + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float Parameters ---------- - loc: float - average of randomly selected numbers + a: Union[float, npt.NDArray] + first value - scale: float - standard deviation of randomly selected numbers + b: Union[float, npt.NDArray] + second value + + c: Union[float, npt.NDArray] + third value Notes ----- - Generates random gaussian values. Each time the ``random_gaussian()`` function - is called, it returns an unexpected float with a probability distribution set by - the parameters. This function's randomness can be influenced by - ``random_seed()``. + Calculates the magnitude (or length) of a vector. A vector is a direction in + space commonly used in computer graphics and linear algebra. Because it has no + "start" position, the magnitude of a vector can be thought of as the distance + from the coordinate `(0, 0)` to its `(x, y)` value. Therefore, `mag()` is a + shortcut for writing `dist(0, 0, x, y)`. + """ + return Sketch.mag(*args) - If no parameters are passed to the function, returned values will have an - average of 0 and a standard deviation of 1. Although there is theoretically no - minimum or maximum value that this function might return, in practice returned - values will be within plus or minus one standard deviation of the mean 68% of - the time and within two standard devations 95% of the time. Values farther and - farther from the mean become increasingly less likely. - If only one parameter is passed to the function, that parameter will be used as - the average instead of 0. If two parameters are called, those values will be - used as the average and standard deviation. +def norm(value: Union[float, + npt.NDArray], + start: Union[float, + npt.NDArray], + stop: Union[float, + npt.NDArray]) -> Union[float, + npt.NDArray]: + """Normalizes a number from another range into a value between 0 and 1. - This function makes calls to numpy to generate the random values. - """ - pass + Parameters + ---------- + start: Union[float, npt.NDArray] + lower bound of the value's current range -def random_gaussian(*args: float) -> float: - """Generates random gaussian values. + stop: Union[float, npt.NDArray] + upper bound of the value's current range - Methods - ------- + value: Union[float, npt.NDArray] + the incoming value to be converted - You can use any of the following signatures: + Notes + ----- - * random_gaussian() -> float - * random_gaussian(loc: float, /) -> float - * random_gaussian(loc: float, scale: float, /) -> float + Normalizes a number from another range into a value between 0 and 1. Identical + to `remap(value, low, high, 0, 1)`. + + Numbers outside of the range are not clamped to 0 and 1, because out-of-range + values are often intentional and useful. (See the second example.) If that isn't + what you want, try pairing this function with `constrain()`. + """ + return Sketch.norm(value, start, stop) + + +def sq(value: Union[float, npt.NDArray]) -> Union[float, npt.NDArray]: + """Squares a number (multiplies a number by itself). Parameters ---------- - loc: float - average of randomly selected numbers - - scale: float - standard deviation of randomly selected numbers + value: Union[float, npt.NDArray] + number to square Notes ----- - Generates random gaussian values. Each time the ``random_gaussian()`` function - is called, it returns an unexpected float with a probability distribution set by - the parameters. This function's randomness can be influenced by - ``random_seed()``. + Squares a number (multiplies a number by itself). The result is always a + positive number, as multiplying two negative numbers always yields a positive + result. For example, `-1 * -1 = 1`. + """ + return Sketch.sq(value) - If no parameters are passed to the function, returned values will have an - average of 0 and a standard deviation of 1. Although there is theoretically no - minimum or maximum value that this function might return, in practice returned - values will be within plus or minus one standard deviation of the mean 68% of - the time and within two standard devations 95% of the time. Values farther and - farther from the mean become increasingly less likely. - If only one parameter is passed to the function, that parameter will be used as - the average instead of 0. If two parameters are called, those values will be - used as the average and standard deviation. +def sqrt(value: Union[float, npt.NDArray] + ) -> Union[float, complex, npt.NDArray]: + """Calculates the square root of a number. - This function makes calls to numpy to generate the random values. - """ - return _py5sketch.random_gaussian(*args) + Parameters + ---------- + value: Union[float, npt.NDArray] + value to calculate the square root of -@overload -def noise(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: - """Generate pseudo-random noise values for specific coodinates using Processing's - noise algorithm. + Notes + ----- - Underlying Processing method: PApplet.noise + Calculates the square root of a number. The square root of a positive number is + always positive, even though there may be a valid negative root. The square root + of a negative number is a complex number. In either case, the square root `s` of + number `a` is such that `s*s = a`. It is the opposite of squaring. - Methods - ------- + Python supports complex numbers, but such values cannot be passed to py5 drawing + functions. When using the `sqrt()` function, you should check if the result is + complex before using the value. You can also extract the real and imaginary + components of the complex value with `.real` and `.imag`. See the second example + to learn how to do both of these things. + """ + return Sketch.sqrt(value) - You can use any of the following signatures: - * noise(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] +def floor(value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]: + """Calculates the closest int value that is less than or equal to the value of the + parameter. Parameters ---------- - x: Union[float, npt.NDArray] - x-coordinate in noise space - - y: Union[float, npt.NDArray] - y-coordinate in noise space - - z: Union[float, npt.NDArray] - z-coordinate in noise space + value: Union[float, npt.ArrayLike] + number to round down Notes ----- - Generate pseudo-random noise values for specific coodinates using Processing's - noise algorithm. Noise functions are random sequence generators that produce a - more natural, harmonic succession of numbers compared to the ``random()`` - method. + Calculates the closest int value that is less than or equal to the value of the + parameter. - In contrast to the ``random()`` method, noise is defined in an n-dimensional - space, in which each coordinate corresponds to a fixed pseudo-random value - (fixed only for the lifespan of the program). The noise value can be animated by - moving through the noise space, as demonstrated in the examples. Any dimension - can also be interpreted as time. An easy way to animate the noise value is to - pass the ``noise()`` method the ``frame_count`` divided by a scaling factor, as - is done in a few of the examples. + This function makes a call to the numpy `floor()` function. + """ + return Sketch.floor(value) - The generated noise values for this method will typically be between 0 and 1, - and can be generated in 1, 2, or 3 dimensions. Py5 also provides the - ``os_noise()`` method, which generates noise using the OpenSimplex 2 algorithm - (smooth version / SuperSimplex). That algorithm generates noise values between - -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of - these differences when modifying your code to switch from one to the other. - There are other differences in the character of the noise values generated by - both methods, so you'll need to do some experimentation to get the results you - want. - The actual noise structure is similar to that of an audio signal, in respect to - the method's use of frequencies. Similar to the concept of harmonics in physics, - both noise algorithms are computed over several octaves which are added together - for the final result. +def ceil(value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]: + """Calculates the closest int value that is greater than or equal to the value of + the parameter. - The nature of the noise values returned can be adjusted with ``noise_seed()`` - and ``noise_detail()``. + Parameters + ---------- - Another way to adjust the character of the resulting sequence is the scale of - the input coordinates. As the method works within an infinite space, the value - of the coordinates doesn't matter as such; only the distance between successive - coordinates is important. As a general rule, the smaller the difference between - coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work - best for most applications, but this will differ depending on the use case and - the noise settings. + value: Union[float, npt.ArrayLike] + number to round up - Py5's ``noise()`` method can also accept numpy arrays as parameters. It will use - broadcasting when needed and calculate the values efficiently. Using numpy array - parameters will be much faster and efficient than calling the ``noise()`` method - repeatedly in a loop. See the examples to see how this can be done. + Notes + ----- - Noise generation is a rich and complex topic, and there are many noise - algorithms and libraries available that are worth learning about. Early versions - of py5 used the Python "noise" library, which can generate noise using the - "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH - paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That - Python library was removed from py5 because it has some bugs and hasn't had a - release in years. Nevertheless, it might be useful to you, and can be installed - separately like any other Python package. You can also try the Python library - "vnoise", which is a pure Python implementation of the Improved Perlin Noise - algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise - Lite" to experiment with a large selection of noise algorithms with efficient - implementations. + Calculates the closest int value that is greater than or equal to the value of + the parameter. + + This function makes a call to the numpy `ceil()` function. """ - pass + return Sketch.ceil(value) -@overload -def noise(x: Union[float, npt.NDArray], y: Union[float, - npt.NDArray], /) -> Union[float, npt.NDArray]: - """Generate pseudo-random noise values for specific coodinates using Processing's - noise algorithm. +def exp(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Returns Euler's number e (2.71828...) raised to the power of the `n` parameter. - Underlying Processing method: PApplet.noise + Parameters + ---------- - Methods - ------- + value: Union[float, npt.ArrayLike] + exponent to raise - You can use any of the following signatures: + Notes + ----- - * noise(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + Returns Euler's number e (2.71828...) raised to the power of the `n` parameter. + This function is the compliment to `log()`. - Parameters - ---------- + This function makes a call to the numpy `exp()` function. + """ + return Sketch.exp(value) - x: Union[float, npt.NDArray] - x-coordinate in noise space - y: Union[float, npt.NDArray] - y-coordinate in noise space +def log(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Calculates the natural logarithm (the base-e logarithm) of a number. - z: Union[float, npt.NDArray] - z-coordinate in noise space + Parameters + ---------- + + value: Union[float, npt.ArrayLike] + number greater than 0.0 Notes ----- - Generate pseudo-random noise values for specific coodinates using Processing's - noise algorithm. Noise functions are random sequence generators that produce a - more natural, harmonic succession of numbers compared to the ``random()`` - method. + Calculates the natural logarithm (the base-e logarithm) of a number. This + function expects the `n` parameter to be a value greater than 0.0. This function + is the compliment to `exp()`. - In contrast to the ``random()`` method, noise is defined in an n-dimensional - space, in which each coordinate corresponds to a fixed pseudo-random value - (fixed only for the lifespan of the program). The noise value can be animated by - moving through the noise space, as demonstrated in the examples. Any dimension - can also be interpreted as time. An easy way to animate the noise value is to - pass the ``noise()`` method the ``frame_count`` divided by a scaling factor, as - is done in a few of the examples. + This function makes a call to the numpy `log()` function. If the `n` parameter + is less than or equal to 0.0, you will see a `RuntimeWarning` and the returned + result will be numpy's Not-a-Number value, `np.nan`. + """ + return Sketch.log(value) - The generated noise values for this method will typically be between 0 and 1, - and can be generated in 1, 2, or 3 dimensions. Py5 also provides the - ``os_noise()`` method, which generates noise using the OpenSimplex 2 algorithm - (smooth version / SuperSimplex). That algorithm generates noise values between - -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of - these differences when modifying your code to switch from one to the other. - There are other differences in the character of the noise values generated by - both methods, so you'll need to do some experimentation to get the results you - want. - The actual noise structure is similar to that of an audio signal, in respect to - the method's use of frequencies. Similar to the concept of harmonics in physics, - both noise algorithms are computed over several octaves which are added together - for the final result. +np_random: np.random.Generator = None - The nature of the noise values returned can be adjusted with ``noise_seed()`` - and ``noise_detail()``. - Another way to adjust the character of the resulting sequence is the scale of - the input coordinates. As the method works within an infinite space, the value - of the coordinates doesn't matter as such; only the distance between successive - coordinates is important. As a general rule, the smaller the difference between - coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work - best for most applications, but this will differ depending on the use case and - the noise settings. +def random_seed(seed: int) -> None: + """Sets the seed value for py5's random functions. - Py5's ``noise()`` method can also accept numpy arrays as parameters. It will use - broadcasting when needed and calculate the values efficiently. Using numpy array - parameters will be much faster and efficient than calling the ``noise()`` method - repeatedly in a loop. See the examples to see how this can be done. + Parameters + ---------- - Noise generation is a rich and complex topic, and there are many noise - algorithms and libraries available that are worth learning about. Early versions - of py5 used the Python "noise" library, which can generate noise using the - "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH - paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That - Python library was removed from py5 because it has some bugs and hasn't had a - release in years. Nevertheless, it might be useful to you, and can be installed - separately like any other Python package. You can also try the Python library - "vnoise", which is a pure Python implementation of the Improved Perlin Noise - algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise - Lite" to experiment with a large selection of noise algorithms with efficient - implementations. + seed: int + seed value + + Notes + ----- + + Sets the seed value for py5's random functions. This includes `random()`, + `random_int()`, `random_choice()`, and `random_gaussian()`. By default, all of + these functions would produce different results each time a program is run. Set + the seed parameter to a constant value to return the same pseudo-random numbers + each time the software is run. """ - pass + return _py5sketch.random_seed(seed) @overload -def noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], - z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: - """Generate pseudo-random noise values for specific coodinates using Processing's - noise algorithm. - - Underlying Processing method: PApplet.noise +def random() -> float: + """Generates random numbers. Methods ------- You can use any of the following signatures: - * noise(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * random() -> float + * random(high: float, /) -> float + * random(low: float, high: float, /) -> float Parameters ---------- - x: Union[float, npt.NDArray] - x-coordinate in noise space - - y: Union[float, npt.NDArray] - y-coordinate in noise space + high: float + upper limit - z: Union[float, npt.NDArray] - z-coordinate in noise space + low: float + lower limit Notes ----- - Generate pseudo-random noise values for specific coodinates using Processing's - noise algorithm. Noise functions are random sequence generators that produce a - more natural, harmonic succession of numbers compared to the ``random()`` - method. - - In contrast to the ``random()`` method, noise is defined in an n-dimensional - space, in which each coordinate corresponds to a fixed pseudo-random value - (fixed only for the lifespan of the program). The noise value can be animated by - moving through the noise space, as demonstrated in the examples. Any dimension - can also be interpreted as time. An easy way to animate the noise value is to - pass the ``noise()`` method the ``frame_count`` divided by a scaling factor, as - is done in a few of the examples. - - The generated noise values for this method will typically be between 0 and 1, - and can be generated in 1, 2, or 3 dimensions. Py5 also provides the - ``os_noise()`` method, which generates noise using the OpenSimplex 2 algorithm - (smooth version / SuperSimplex). That algorithm generates noise values between - -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of - these differences when modifying your code to switch from one to the other. - There are other differences in the character of the noise values generated by - both methods, so you'll need to do some experimentation to get the results you - want. - - The actual noise structure is similar to that of an audio signal, in respect to - the method's use of frequencies. Similar to the concept of harmonics in physics, - both noise algorithms are computed over several octaves which are added together - for the final result. + Generates random numbers. Each time the `random()` function is called, it + returns an unexpected value within the specified range. This function's + randomness can be influenced by `random_seed()`. - The nature of the noise values returned can be adjusted with ``noise_seed()`` - and ``noise_detail()``. + If no parameters are passed to the function, it will return a float between zero + and one. - Another way to adjust the character of the resulting sequence is the scale of - the input coordinates. As the method works within an infinite space, the value - of the coordinates doesn't matter as such; only the distance between successive - coordinates is important. As a general rule, the smaller the difference between - coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work - best for most applications, but this will differ depending on the use case and - the noise settings. + If only one parameter is passed to the function, it will return a float between + zero and the value of the `high` parameter. For example, `random(5)` returns + values between 0 and 5 (starting at zero, and up to, but not including, 5). - Py5's ``noise()`` method can also accept numpy arrays as parameters. It will use - broadcasting when needed and calculate the values efficiently. Using numpy array - parameters will be much faster and efficient than calling the ``noise()`` method - repeatedly in a loop. See the examples to see how this can be done. + If two parameters are specified, the function will return a float with a value + between the two values. For example, `random(-5, 10.2)` returns values starting + at -5 and up to (but not including) 10.2. To convert a floating-point random + number to an integer, use the `int()` function, or alternatively, consider using + `random_int()`. - Noise generation is a rich and complex topic, and there are many noise - algorithms and libraries available that are worth learning about. Early versions - of py5 used the Python "noise" library, which can generate noise using the - "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH - paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That - Python library was removed from py5 because it has some bugs and hasn't had a - release in years. Nevertheless, it might be useful to you, and can be installed - separately like any other Python package. You can also try the Python library - "vnoise", which is a pure Python implementation of the Improved Perlin Noise - algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise - Lite" to experiment with a large selection of noise algorithms with efficient - implementations. + This function makes calls to numpy to generate the random values. """ pass -def noise(*args) -> Union[float, npt.NDArray]: - """Generate pseudo-random noise values for specific coodinates using Processing's - noise algorithm. - - Underlying Processing method: PApplet.noise +@overload +def random(high: float, /) -> float: + """Generates random numbers. Methods ------- You can use any of the following signatures: - * noise(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * random() -> float + * random(high: float, /) -> float + * random(low: float, high: float, /) -> float Parameters ---------- - x: Union[float, npt.NDArray] - x-coordinate in noise space - - y: Union[float, npt.NDArray] - y-coordinate in noise space + high: float + upper limit - z: Union[float, npt.NDArray] - z-coordinate in noise space + low: float + lower limit Notes ----- - Generate pseudo-random noise values for specific coodinates using Processing's - noise algorithm. Noise functions are random sequence generators that produce a - more natural, harmonic succession of numbers compared to the ``random()`` - method. + Generates random numbers. Each time the `random()` function is called, it + returns an unexpected value within the specified range. This function's + randomness can be influenced by `random_seed()`. - In contrast to the ``random()`` method, noise is defined in an n-dimensional - space, in which each coordinate corresponds to a fixed pseudo-random value - (fixed only for the lifespan of the program). The noise value can be animated by - moving through the noise space, as demonstrated in the examples. Any dimension - can also be interpreted as time. An easy way to animate the noise value is to - pass the ``noise()`` method the ``frame_count`` divided by a scaling factor, as - is done in a few of the examples. + If no parameters are passed to the function, it will return a float between zero + and one. - The generated noise values for this method will typically be between 0 and 1, - and can be generated in 1, 2, or 3 dimensions. Py5 also provides the - ``os_noise()`` method, which generates noise using the OpenSimplex 2 algorithm - (smooth version / SuperSimplex). That algorithm generates noise values between - -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of - these differences when modifying your code to switch from one to the other. - There are other differences in the character of the noise values generated by - both methods, so you'll need to do some experimentation to get the results you - want. - - The actual noise structure is similar to that of an audio signal, in respect to - the method's use of frequencies. Similar to the concept of harmonics in physics, - both noise algorithms are computed over several octaves which are added together - for the final result. - - The nature of the noise values returned can be adjusted with ``noise_seed()`` - and ``noise_detail()``. - - Another way to adjust the character of the resulting sequence is the scale of - the input coordinates. As the method works within an infinite space, the value - of the coordinates doesn't matter as such; only the distance between successive - coordinates is important. As a general rule, the smaller the difference between - coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work - best for most applications, but this will differ depending on the use case and - the noise settings. + If only one parameter is passed to the function, it will return a float between + zero and the value of the `high` parameter. For example, `random(5)` returns + values between 0 and 5 (starting at zero, and up to, but not including, 5). - Py5's ``noise()`` method can also accept numpy arrays as parameters. It will use - broadcasting when needed and calculate the values efficiently. Using numpy array - parameters will be much faster and efficient than calling the ``noise()`` method - repeatedly in a loop. See the examples to see how this can be done. + If two parameters are specified, the function will return a float with a value + between the two values. For example, `random(-5, 10.2)` returns values starting + at -5 and up to (but not including) 10.2. To convert a floating-point random + number to an integer, use the `int()` function, or alternatively, consider using + `random_int()`. - Noise generation is a rich and complex topic, and there are many noise - algorithms and libraries available that are worth learning about. Early versions - of py5 used the Python "noise" library, which can generate noise using the - "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH - paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That - Python library was removed from py5 because it has some bugs and hasn't had a - release in years. Nevertheless, it might be useful to you, and can be installed - separately like any other Python package. You can also try the Python library - "vnoise", which is a pure Python implementation of the Improved Perlin Noise - algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise - Lite" to experiment with a large selection of noise algorithms with efficient - implementations. + This function makes calls to numpy to generate the random values. """ - return _py5sketch.noise(*args) + pass @overload -def os_noise(x: Union[float, npt.NDArray], y: Union[float, - npt.NDArray], /) -> Union[float, npt.NDArray]: - """Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). +def random(low: float, high: float, /) -> float: + """Generates random numbers. Methods ------- You can use any of the following signatures: - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * random() -> float + * random(high: float, /) -> float + * random(low: float, high: float, /) -> float Parameters ---------- - w: Union[float, npt.NDArray] - w-coordinate in noise space - - x: Union[float, npt.NDArray] - x-coordinate in noise space - - y: Union[float, npt.NDArray] - y-coordinate in noise space + high: float + upper limit - z: Union[float, npt.NDArray] - z-coordinate in noise space + low: float + lower limit Notes ----- - Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are - random sequence generators that produce a more natural, harmonic succession of - numbers compared to the ``random()`` method. - - In contrast to the ``random()`` method, noise is defined in an n-dimensional - space, in which each coordinate corresponds to a fixed pseudo-random value - (fixed only for the lifespan of the program). The noise value can be animated by - moving through the noise space, as demonstrated in the examples. Any dimension - can also be interpreted as time. An easy way to animate the noise value is to - pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, - as is done in a few of the examples. - - The generated noise values for this method will be between -1 and 1, and can be - generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a - constant value as an extra parameter, as shown in a few examples. Py5 also - provides the ``noise()`` method, which generates noise using Processing's noise - algorithm. That algorithm typically generates noise values between 0 and 1, and - can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences - when modifying your code to switch from one to the other. There are other - differences in the character of the noise values generated by both methods, so - you'll need to do some experimentation to get the results you want. + Generates random numbers. Each time the `random()` function is called, it + returns an unexpected value within the specified range. This function's + randomness can be influenced by `random_seed()`. - The nature of the noise values returned can be adjusted with - ``os_noise_seed()``. + If no parameters are passed to the function, it will return a float between zero + and one. - Another way to adjust the character of the resulting sequence is the scale of - the input coordinates. As the method works within an infinite space, the value - of the coordinates doesn't matter as such; only the distance between successive - coordinates is important. As a general rule, the smaller the difference between - coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work - best for most applications, but this will differ depending on the use case and - the noise settings. + If only one parameter is passed to the function, it will return a float between + zero and the value of the `high` parameter. For example, `random(5)` returns + values between 0 and 5 (starting at zero, and up to, but not including, 5). - Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will - use broadcasting when needed and calculate the values efficiently. Using numpy - array parameters will be much faster and efficient than calling the - ``os_noise()`` method repeatedly in a loop. See the examples to see how this can - be done. The noise algorithm for this method is implemented in Java. + If two parameters are specified, the function will return a float with a value + between the two values. For example, `random(-5, 10.2)` returns values starting + at -5 and up to (but not including) 10.2. To convert a floating-point random + number to an integer, use the `int()` function, or alternatively, consider using + `random_int()`. - Noise generation is a rich and complex topic, and there are many noise - algorithms and libraries available that are worth learning about. Early versions - of py5 used the Python "noise" library, which can generate noise using the - "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH - paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That - Python library was removed from py5 because it has some bugs and hasn't had a - release in years. Nevertheless, it might be useful to you, and can be installed - separately like any other Python package. You can also try the Python library - "vnoise", which is a pure Python implementation of the Improved Perlin Noise - algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise - Lite" to experiment with a large selection of noise algorithms with efficient - implementations. + This function makes calls to numpy to generate the random values. """ pass -@overload -def os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], - z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: - """Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). +def random(*args: float) -> float: + """Generates random numbers. Methods ------- You can use any of the following signatures: - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * random() -> float + * random(high: float, /) -> float + * random(low: float, high: float, /) -> float Parameters ---------- - w: Union[float, npt.NDArray] - w-coordinate in noise space - - x: Union[float, npt.NDArray] - x-coordinate in noise space - - y: Union[float, npt.NDArray] - y-coordinate in noise space + high: float + upper limit - z: Union[float, npt.NDArray] - z-coordinate in noise space + low: float + lower limit Notes ----- - Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are - random sequence generators that produce a more natural, harmonic succession of - numbers compared to the ``random()`` method. - - In contrast to the ``random()`` method, noise is defined in an n-dimensional - space, in which each coordinate corresponds to a fixed pseudo-random value - (fixed only for the lifespan of the program). The noise value can be animated by - moving through the noise space, as demonstrated in the examples. Any dimension - can also be interpreted as time. An easy way to animate the noise value is to - pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, - as is done in a few of the examples. - - The generated noise values for this method will be between -1 and 1, and can be - generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a - constant value as an extra parameter, as shown in a few examples. Py5 also - provides the ``noise()`` method, which generates noise using Processing's noise - algorithm. That algorithm typically generates noise values between 0 and 1, and - can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences - when modifying your code to switch from one to the other. There are other - differences in the character of the noise values generated by both methods, so - you'll need to do some experimentation to get the results you want. + Generates random numbers. Each time the `random()` function is called, it + returns an unexpected value within the specified range. This function's + randomness can be influenced by `random_seed()`. - The nature of the noise values returned can be adjusted with - ``os_noise_seed()``. + If no parameters are passed to the function, it will return a float between zero + and one. - Another way to adjust the character of the resulting sequence is the scale of - the input coordinates. As the method works within an infinite space, the value - of the coordinates doesn't matter as such; only the distance between successive - coordinates is important. As a general rule, the smaller the difference between - coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work - best for most applications, but this will differ depending on the use case and - the noise settings. + If only one parameter is passed to the function, it will return a float between + zero and the value of the `high` parameter. For example, `random(5)` returns + values between 0 and 5 (starting at zero, and up to, but not including, 5). - Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will - use broadcasting when needed and calculate the values efficiently. Using numpy - array parameters will be much faster and efficient than calling the - ``os_noise()`` method repeatedly in a loop. See the examples to see how this can - be done. The noise algorithm for this method is implemented in Java. + If two parameters are specified, the function will return a float with a value + between the two values. For example, `random(-5, 10.2)` returns values starting + at -5 and up to (but not including) 10.2. To convert a floating-point random + number to an integer, use the `int()` function, or alternatively, consider using + `random_int()`. - Noise generation is a rich and complex topic, and there are many noise - algorithms and libraries available that are worth learning about. Early versions - of py5 used the Python "noise" library, which can generate noise using the - "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH - paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That - Python library was removed from py5 because it has some bugs and hasn't had a - release in years. Nevertheless, it might be useful to you, and can be installed - separately like any other Python package. You can also try the Python library - "vnoise", which is a pure Python implementation of the Improved Perlin Noise - algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise - Lite" to experiment with a large selection of noise algorithms with efficient - implementations. + This function makes calls to numpy to generate the random values. """ - pass + return _py5sketch.random(*args) @overload -def os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, - npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: - """Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). +def random_int() -> int: + """Generates random integers. Methods ------- You can use any of the following signatures: - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * random_int() -> int + * random_int(high: int, /) -> int + * random_int(low: int, high: int, /) -> int Parameters ---------- - w: Union[float, npt.NDArray] - w-coordinate in noise space - - x: Union[float, npt.NDArray] - x-coordinate in noise space - - y: Union[float, npt.NDArray] - y-coordinate in noise space + high: int + upper limit - z: Union[float, npt.NDArray] - z-coordinate in noise space + low: int + lower limit Notes ----- - Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are - random sequence generators that produce a more natural, harmonic succession of - numbers compared to the ``random()`` method. - - In contrast to the ``random()`` method, noise is defined in an n-dimensional - space, in which each coordinate corresponds to a fixed pseudo-random value - (fixed only for the lifespan of the program). The noise value can be animated by - moving through the noise space, as demonstrated in the examples. Any dimension - can also be interpreted as time. An easy way to animate the noise value is to - pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, - as is done in a few of the examples. + Generates random integers. Each time the `random_int()` function is called, it + returns an unexpected integer within the specified range. This function's + randomness can be influenced by `random_seed()`. - The generated noise values for this method will be between -1 and 1, and can be - generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a - constant value as an extra parameter, as shown in a few examples. Py5 also - provides the ``noise()`` method, which generates noise using Processing's noise - algorithm. That algorithm typically generates noise values between 0 and 1, and - can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences - when modifying your code to switch from one to the other. There are other - differences in the character of the noise values generated by both methods, so - you'll need to do some experimentation to get the results you want. + If no parameters are passed to the function, it will return either 0 or 1. + Recall that in a Python boolean expression, 0 evaluates to `False` and 1 + evaluates to `True`. This is equivalent to a coin toss. - The nature of the noise values returned can be adjusted with - ``os_noise_seed()``. + If only one parameter is passed to the function, it will return an integer + between zero and the value of the `high` parameter, inclusive. For example, + `random(5)` returns one of 0, 1, 2, 3, 4, or 5. - Another way to adjust the character of the resulting sequence is the scale of - the input coordinates. As the method works within an infinite space, the value - of the coordinates doesn't matter as such; only the distance between successive - coordinates is important. As a general rule, the smaller the difference between - coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work - best for most applications, but this will differ depending on the use case and - the noise settings. + If two parameters are specified, the function will return an integer with a + value between the two values, inclusive. For example, `random(2, 5)` returns one + of 2, 3, 4, or 5. - Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will - use broadcasting when needed and calculate the values efficiently. Using numpy - array parameters will be much faster and efficient than calling the - ``os_noise()`` method repeatedly in a loop. See the examples to see how this can - be done. The noise algorithm for this method is implemented in Java. + If you want to pick a random object from a list, recall that Python uses zero- + indexing, so the first index value is 0 and the final index value is one less + than the list length. Therefore, to pick a random index to use in the list + `words`, your code should be `random_int(len(words)-1)`. Omitting the `-1` will + (occasionally) result in an index out of range error. Alternatively, you can + also use `random_choice()` to pick a random object from a list. - Noise generation is a rich and complex topic, and there are many noise - algorithms and libraries available that are worth learning about. Early versions - of py5 used the Python "noise" library, which can generate noise using the - "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH - paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That - Python library was removed from py5 because it has some bugs and hasn't had a - release in years. Nevertheless, it might be useful to you, and can be installed - separately like any other Python package. You can also try the Python library - "vnoise", which is a pure Python implementation of the Improved Perlin Noise - algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise - Lite" to experiment with a large selection of noise algorithms with efficient - implementations. + This function makes calls to numpy to generate the random integers. """ pass -def os_noise(*args) -> Union[float, npt.NDArray]: - """Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). +@overload +def random_int(high: int, /) -> int: + """Generates random integers. Methods ------- You can use any of the following signatures: - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * random_int() -> int + * random_int(high: int, /) -> int + * random_int(low: int, high: int, /) -> int Parameters ---------- - w: Union[float, npt.NDArray] - w-coordinate in noise space - - x: Union[float, npt.NDArray] - x-coordinate in noise space - - y: Union[float, npt.NDArray] - y-coordinate in noise space + high: int + upper limit - z: Union[float, npt.NDArray] - z-coordinate in noise space + low: int + lower limit Notes ----- - Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are - random sequence generators that produce a more natural, harmonic succession of - numbers compared to the ``random()`` method. - - In contrast to the ``random()`` method, noise is defined in an n-dimensional - space, in which each coordinate corresponds to a fixed pseudo-random value - (fixed only for the lifespan of the program). The noise value can be animated by - moving through the noise space, as demonstrated in the examples. Any dimension - can also be interpreted as time. An easy way to animate the noise value is to - pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, - as is done in a few of the examples. + Generates random integers. Each time the `random_int()` function is called, it + returns an unexpected integer within the specified range. This function's + randomness can be influenced by `random_seed()`. - The generated noise values for this method will be between -1 and 1, and can be - generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a - constant value as an extra parameter, as shown in a few examples. Py5 also - provides the ``noise()`` method, which generates noise using Processing's noise - algorithm. That algorithm typically generates noise values between 0 and 1, and - can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences - when modifying your code to switch from one to the other. There are other - differences in the character of the noise values generated by both methods, so - you'll need to do some experimentation to get the results you want. + If no parameters are passed to the function, it will return either 0 or 1. + Recall that in a Python boolean expression, 0 evaluates to `False` and 1 + evaluates to `True`. This is equivalent to a coin toss. - The nature of the noise values returned can be adjusted with - ``os_noise_seed()``. + If only one parameter is passed to the function, it will return an integer + between zero and the value of the `high` parameter, inclusive. For example, + `random(5)` returns one of 0, 1, 2, 3, 4, or 5. - Another way to adjust the character of the resulting sequence is the scale of - the input coordinates. As the method works within an infinite space, the value - of the coordinates doesn't matter as such; only the distance between successive - coordinates is important. As a general rule, the smaller the difference between - coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work - best for most applications, but this will differ depending on the use case and - the noise settings. + If two parameters are specified, the function will return an integer with a + value between the two values, inclusive. For example, `random(2, 5)` returns one + of 2, 3, 4, or 5. - Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will - use broadcasting when needed and calculate the values efficiently. Using numpy - array parameters will be much faster and efficient than calling the - ``os_noise()`` method repeatedly in a loop. See the examples to see how this can - be done. The noise algorithm for this method is implemented in Java. + If you want to pick a random object from a list, recall that Python uses zero- + indexing, so the first index value is 0 and the final index value is one less + than the list length. Therefore, to pick a random index to use in the list + `words`, your code should be `random_int(len(words)-1)`. Omitting the `-1` will + (occasionally) result in an index out of range error. Alternatively, you can + also use `random_choice()` to pick a random object from a list. - Noise generation is a rich and complex topic, and there are many noise - algorithms and libraries available that are worth learning about. Early versions - of py5 used the Python "noise" library, which can generate noise using the - "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH - paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That - Python library was removed from py5 because it has some bugs and hasn't had a - release in years. Nevertheless, it might be useful to you, and can be installed - separately like any other Python package. You can also try the Python library - "vnoise", which is a pure Python implementation of the Improved Perlin Noise - algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise - Lite" to experiment with a large selection of noise algorithms with efficient - implementations. + This function makes calls to numpy to generate the random integers. """ - return _py5sketch.os_noise(*args) - -############################################################################## -# module functions from pixels.py -############################################################################## + pass -def load_np_pixels() -> None: - """Loads the pixel data of the current display window into the ``np_pixels[]`` - array. +@overload +def random_int(low: int, high: int, /) -> int: + """Generates random integers. - Notes - ----- + Methods + ------- - Loads the pixel data of the current display window into the ``np_pixels[]`` - array. This method must always be called before reading from or writing to - ``np_pixels[]``. Subsequent changes to the display window will not be reflected - in ``np_pixels[]`` until ``load_np_pixels()`` is called again. + You can use any of the following signatures: - The ``load_np_pixels()`` method is similar to ``load_pixels()`` in that - ``load_np_pixels()`` must be called before reading from or writing to - ``np_pixels[]`` just as ``load_pixels()`` must be called before reading from or - writing to ``pixels[]``. + * random_int() -> int + * random_int(high: int, /) -> int + * random_int(low: int, high: int, /) -> int - Note that ``load_np_pixels()`` will as a side effect call ``load_pixels()``, so - if your code needs to read ``np_pixels[]`` and ``pixels[]`` simultaneously, - there is no need for a separate call to ``load_pixels()``. However, be aware - that modifying both ``np_pixels[]`` and ``pixels[]`` simultaneously will likely - result in the updates to ``pixels[]`` being discarded. - """ - return _py5sketch.load_np_pixels() + Parameters + ---------- + high: int + upper limit -def update_np_pixels() -> None: - """Updates the display window with the data in the ``np_pixels[]`` array. + low: int + lower limit Notes ----- - Updates the display window with the data in the ``np_pixels[]`` array. Use in - conjunction with ``load_np_pixels()``. If you're only reading pixels from the - array, there's no need to call ``update_np_pixels()`` — updating is only - necessary to apply changes. - - The ``update_np_pixels()`` method is similar to ``update_pixels()`` in that - ``update_np_pixels()`` must be called after modifying ``np_pixels[]`` just as - ``update_pixels()`` must be called after modifying ``pixels[]``. - """ - return _py5sketch.update_np_pixels() - - -np_pixels: npt.NDArray[np.uint8] = None - - -def set_np_pixels(array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None: - """Set the entire contents of ``np_pixels[]`` to the contents of another properly - sized and typed numpy array. + Generates random integers. Each time the `random_int()` function is called, it + returns an unexpected integer within the specified range. This function's + randomness can be influenced by `random_seed()`. - Parameters - ---------- + If no parameters are passed to the function, it will return either 0 or 1. + Recall that in a Python boolean expression, 0 evaluates to `False` and 1 + evaluates to `True`. This is equivalent to a coin toss. - array: npt.NDArray[np.uint8] - properly sized numpy array to be copied to np_pixels[] + If only one parameter is passed to the function, it will return an integer + between zero and the value of the `high` parameter, inclusive. For example, + `random(5)` returns one of 0, 1, 2, 3, 4, or 5. - bands: str = 'ARGB' - color channels in the array's third dimension + If two parameters are specified, the function will return an integer with a + value between the two values, inclusive. For example, `random(2, 5)` returns one + of 2, 3, 4, or 5. - Notes - ----- + If you want to pick a random object from a list, recall that Python uses zero- + indexing, so the first index value is 0 and the final index value is one less + than the list length. Therefore, to pick a random index to use in the list + `words`, your code should be `random_int(len(words)-1)`. Omitting the `-1` will + (occasionally) result in an index out of range error. Alternatively, you can + also use `random_choice()` to pick a random object from a list. - Set the entire contents of ``np_pixels[]`` to the contents of another properly - sized and typed numpy array. The size of ``array``'s first and second dimensions - must match the height and width of the Sketch window, respectively. The array's - ``dtype`` must be ``np.uint8``. + This function makes calls to numpy to generate the random integers. + """ + pass - The ``bands`` parameter is used to interpret the ``array``'s color channel - dimension (the array's third dimension). It can be one of ``'L'`` (single- - channel grayscale), ``'ARGB'``, ``'RGB'``, or ``'RGBA'``. If there is no alpha - channel, ``array`` is assumed to have no transparency, but recall that the - display window's pixels can never be transparent so any transparency in - ``array`` will have no effect. If the ``bands`` parameter is ``'L'``, - ``array``'s third dimension is optional. - This method makes its own calls to ``load_np_pixels()`` and - ``update_np_pixels()`` so there is no need to call either explicitly. +def random_int(*args: int) -> int: + """Generates random integers. - This method exists because setting the array contents with the code - ``py5.np_pixels = array`` will cause an error, while the correct syntax, - ``py5.np_pixels[:] = array``, might also be unintuitive for beginners. - """ - return _py5sketch.set_np_pixels(array, bands=bands) + Methods + ------- + You can use any of the following signatures: -def save(filename: Union[str, - Path, - BytesIO], - *, - format: str = None, - drop_alpha: bool = True, - use_thread: bool = False, - **params) -> None: - """Save the drawing surface to an image file. + * random_int() -> int + * random_int(high: int, /) -> int + * random_int(low: int, high: int, /) -> int Parameters ---------- - drop_alpha: bool = True - remove the alpha channel when saving the image + high: int + upper limit - filename: Union[str, Path, BytesIO] - output filename + low: int + lower limit - format: str = None - image format, if not determined from filename extension + Notes + ----- - params - keyword arguments to pass to the PIL.Image save method + Generates random integers. Each time the `random_int()` function is called, it + returns an unexpected integer within the specified range. This function's + randomness can be influenced by `random_seed()`. - use_thread: bool = False - write file in separate thread + If no parameters are passed to the function, it will return either 0 or 1. + Recall that in a Python boolean expression, 0 evaluates to `False` and 1 + evaluates to `True`. This is equivalent to a coin toss. - Notes - ----- + If only one parameter is passed to the function, it will return an integer + between zero and the value of the `high` parameter, inclusive. For example, + `random(5)` returns one of 0, 1, 2, 3, 4, or 5. - Save the drawing surface to an image file. This method uses the Python library - Pillow to write the image, so it can save images in any format that that library - supports. + If two parameters are specified, the function will return an integer with a + value between the two values, inclusive. For example, `random(2, 5)` returns one + of 2, 3, 4, or 5. - Use the ``drop_alpha`` parameter to drop the alpha channel from the image. This - defaults to ``True``. Some image formats such as JPG do not support alpha - channels, and Pillow will throw an error if you try to save an image with the - alpha channel in that format. + If you want to pick a random object from a list, recall that Python uses zero- + indexing, so the first index value is 0 and the final index value is one less + than the list length. Therefore, to pick a random index to use in the list + `words`, your code should be `random_int(len(words)-1)`. Omitting the `-1` will + (occasionally) result in an index out of range error. Alternatively, you can + also use `random_choice()` to pick a random object from a list. - The ``use_thread`` parameter will save the image in a separate Python thread. - This improves performance by returning before the image has actually been - written to the file. + This function makes calls to numpy to generate the random integers. """ - return _py5sketch.save( - filename, - format=format, - drop_alpha=drop_alpha, - use_thread=use_thread, - **params) - -############################################################################## -# module functions from print_tools.py -############################################################################## + return _py5sketch.random_int(*args) -def set_println_stream(println_stream: Any) -> None: - """Customize where the output of ``println()`` goes. +def random_choice(objects: list[Any]) -> Any: + """Select a random item from a list. Parameters ---------- - println_stream: Any - println stream object to be used by println method + objects: list[Any] + list of objects to choose from Notes ----- - Customize where the output of ``println()`` goes. + Select a random item from a list. The list items can be of any type. If the list + of objects is empty, `None` will be returned. - When running a Sketch asynchronously through Jupyter Notebook, any ``print`` - statements using Python's builtin function will always appear in the output of - the currently active cell. This will rarely be desirable, as the active cell - will keep changing as the user executes code elsewhere in the notebook. The - ``println()`` method was created to provide users with print functionality in a - Sketch without having to cope with output moving from one cell to the next. Use - ``set_println_stream`` to change how the output is handled. The - ``println_stream`` object must provide ``init()`` and ``print()`` methods, as - shown in the example. The example demonstrates how to configure py5 to output - text to an IPython Widget. + This function's randomness can be influenced by `random_seed()`, and makes calls + to numpy to select the random items. """ - return _py5sketch.set_println_stream(println_stream) + return _py5sketch.random_choice(objects) -def println( - *args, - sep: str = ' ', - end: str = '\n', - stderr: bool = False) -> None: - """Print text or other values to the screen. +def random_sample( + objects: list[Any], + size: int = 1, + replace: bool = True) -> list[Any]: + """Select random items from a list. Parameters ---------- - args - values to be printed - - end: str = '\\n' - string appended after the last value, defaults to newline character + objects: list[Any] + list of objects to choose from - sep: str = ' ' - string inserted between values, defaults to a space + replace: bool=True + whether to select random items with or without replacement - stderr: bool = False - use stderr instead of stdout + size: int=1 + number of random items to select Notes ----- - Print text or other values to the screen. For a Sketch running outside of a - Jupyter Notebook, this method will behave the same as the Python's builtin - ``print`` method. For Sketches running in a Jupyter Notebook, this will place - text in the output of the cell that made the ``run_sketch()`` call. + Select random items from a list. The list items can be of any type. If multiple + items are selected, this function will by default allow the same item to be + selected multiple times. Set the `replace` parameter to `False` to prevent the + same item from being selected multiple times. - When running a Sketch asynchronously through Jupyter Notebook, any ``print`` - statements using Python's builtin function will always appear in the output of - the currently active cell. This will rarely be desirable, as the active cell - will keep changing as the user executes code elsewhere in the notebook. This - method was created to provide users with print functionality in a Sketch without - having to cope with output moving from one cell to the next. + The returned value will always be a sequence such as a list or numpy array, even + if only one item is sampled. If you only want to sample one item, consider using + `random_choice()` instead. If the list of objects is empty, an empty list will + be returned. - Use ``set_println_stream()`` to customize the behavior of ``println()``. + This function's randomness can be influenced by `random_seed()`, and makes calls + to numpy to select the random items. """ - return _py5sketch.println(*args, sep=sep, end=end, stderr=stderr) + return _py5sketch.random_sample(objects, size=size, replace=replace) -############################################################################## -# module functions from data.py -############################################################################## +@overload +def random_gaussian() -> float: + """Generates random gaussian values. + + Methods + ------- -def load_json(json_path: Union[str, Path], **kwargs: dict[str, Any]) -> Any: - """Load a JSON data file from a file or URL. + You can use any of the following signatures: + + * random_gaussian() -> float + * random_gaussian(loc: float, /) -> float + * random_gaussian(loc: float, scale: float, /) -> float Parameters ---------- - json_path: Union[str, Path] - url or file path for JSON data file + loc: float + average of randomly selected numbers - kwargs: dict[str, Any] - keyword arguments + scale: float + standard deviation of randomly selected numbers Notes ----- - Load a JSON data file from a file or URL. When loading a file, the path can be - in the data directory, relative to the current working directory - (``sketch_path()``), or an absolute path. When loading from a URL, the - ``json_path`` parameter must start with ``http://`` or ``https://``. + Generates random gaussian values. Each time the `random_gaussian()` function is + called, it returns an unexpected float with a probability distribution set by + the parameters. This function's randomness can be influenced by + `random_seed()`. - When loading JSON data from a URL, the data is retrieved using the Python - requests library with the ``get`` method, and any extra keyword arguments (the - ``kwargs`` parameter) are passed along to that method. When loading JSON data - from a file, the data is loaded using the Python json library with the ``load`` - method, and again any extra keyword arguments are passed along to that method. - """ - return _py5sketch.load_json(json_path, **kwargs) + If no parameters are passed to the function, returned values will have an + average of 0 and a standard deviation of 1. Although there is theoretically no + minimum or maximum value that this function might return, in practice returned + values will be within plus or minus one standard deviation of the mean 68% of + the time and within two standard devations 95% of the time. Values farther and + farther from the mean become increasingly less likely. + If only one parameter is passed to the function, that parameter will be used as + the average instead of 0. If two parameters are called, those values will be + used as the average and standard deviation. -def save_json(json_data: Any, - filename: Union[str, - Path], - **kwargs: dict[str, - Any]) -> None: - """Save JSON data to a file. + This function makes calls to numpy to generate the random values. + """ + pass + + +@overload +def random_gaussian(loc: float, /) -> float: + """Generates random gaussian values. + + Methods + ------- + + You can use any of the following signatures: + + * random_gaussian() -> float + * random_gaussian(loc: float, /) -> float + * random_gaussian(loc: float, scale: float, /) -> float Parameters ---------- - filename: Union[str, Path] - filename to save JSON data object to - - json_data: Any - json data object + loc: float + average of randomly selected numbers - kwargs: dict[str, Any] - keyword arguments + scale: float + standard deviation of randomly selected numbers Notes ----- - Save JSON data to a file. If ``filename`` is not an absolute path, it will be - saved relative to the current working directory (``sketch_path()``). The saved - file can be reloaded with ``load_json()``. + Generates random gaussian values. Each time the `random_gaussian()` function is + called, it returns an unexpected float with a probability distribution set by + the parameters. This function's randomness can be influenced by + `random_seed()`. + + If no parameters are passed to the function, returned values will have an + average of 0 and a standard deviation of 1. Although there is theoretically no + minimum or maximum value that this function might return, in practice returned + values will be within plus or minus one standard deviation of the mean 68% of + the time and within two standard devations 95% of the time. Values farther and + farther from the mean become increasingly less likely. + + If only one parameter is passed to the function, that parameter will be used as + the average instead of 0. If two parameters are called, those values will be + used as the average and standard deviation. - The JSON data is saved using the Python json library with the ``dump`` method, - and the ``kwargs`` parameter is passed along to that method. + This function makes calls to numpy to generate the random values. """ - return _py5sketch.save_json(json_data, filename, **kwargs) + pass -def parse_json(serialized_json: Any, **kwargs: dict[str, Any]) -> Any: - """Parse serialized JSON data from a string. +@overload +def random_gaussian(loc: float, scale: float, /) -> float: + """Generates random gaussian values. + + Methods + ------- + + You can use any of the following signatures: + + * random_gaussian() -> float + * random_gaussian(loc: float, /) -> float + * random_gaussian(loc: float, scale: float, /) -> float Parameters ---------- - kwargs: dict[str, Any] - keyword arguments + loc: float + average of randomly selected numbers - serialized_json: Any - JSON data object that has been serialized as a string + scale: float + standard deviation of randomly selected numbers Notes ----- - Parse serialized JSON data from a string. When reading JSON data from a file, - ``load_json()`` is the better choice. + Generates random gaussian values. Each time the `random_gaussian()` function is + called, it returns an unexpected float with a probability distribution set by + the parameters. This function's randomness can be influenced by + `random_seed()`. + + If no parameters are passed to the function, returned values will have an + average of 0 and a standard deviation of 1. Although there is theoretically no + minimum or maximum value that this function might return, in practice returned + values will be within plus or minus one standard deviation of the mean 68% of + the time and within two standard devations 95% of the time. Values farther and + farther from the mean become increasingly less likely. + + If only one parameter is passed to the function, that parameter will be used as + the average instead of 0. If two parameters are called, those values will be + used as the average and standard deviation. - The JSON data is parsed using the Python json library with the ``loads`` method, - and the ``kwargs`` parameter is passed along to that method. + This function makes calls to numpy to generate the random values. """ - return Sketch.parse_json(serialized_json, **kwargs) + pass -def load_strings(string_path: Union[str, Path], - **kwargs: dict[str, Any]) -> list[str]: - """Load a list of strings from a file or URL. +def random_gaussian(*args: float) -> float: + """Generates random gaussian values. - Underlying Processing method: Sketch.loadStrings + Methods + ------- + + You can use any of the following signatures: + + * random_gaussian() -> float + * random_gaussian(loc: float, /) -> float + * random_gaussian(loc: float, scale: float, /) -> float Parameters ---------- - kwargs: dict[str, Any] - keyword arguments + loc: float + average of randomly selected numbers - string_path: Union[str, Path] - url or file path for string data file + scale: float + standard deviation of randomly selected numbers Notes ----- - Load a list of strings from a file or URL. When loading a file, the path can be - in the data directory, relative to the current working directory - (``sketch_path()``), or an absolute path. When loading from a URL, the - ``string_path`` parameter must start with ``http://`` or ``https://``. + Generates random gaussian values. Each time the `random_gaussian()` function is + called, it returns an unexpected float with a probability distribution set by + the parameters. This function's randomness can be influenced by + `random_seed()`. - When loading string data from a URL, the data is retrieved using the Python - requests library with the ``get`` method, and any extra keyword arguments (the - ``kwargs`` parameter) are passed along to that method. When loading string data - from a file, the ``kwargs`` parameter is not used. + If no parameters are passed to the function, returned values will have an + average of 0 and a standard deviation of 1. Although there is theoretically no + minimum or maximum value that this function might return, in practice returned + values will be within plus or minus one standard deviation of the mean 68% of + the time and within two standard devations 95% of the time. Values farther and + farther from the mean become increasingly less likely. + + If only one parameter is passed to the function, that parameter will be used as + the average instead of 0. If two parameters are called, those values will be + used as the average and standard deviation. + + This function makes calls to numpy to generate the random values. """ - return _py5sketch.load_strings(string_path, **kwargs) + return _py5sketch.random_gaussian(*args) -def save_strings(string_data: list[str], - filename: Union[str, - Path], - *, - end: str = '\n') -> None: - """Save a list of strings to a file. +@overload +def noise(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: + """Generate pseudo-random noise values for specific coodinates using Processing's + noise algorithm. - Underlying Processing method: Sketch.saveStrings + Underlying Processing method: PApplet.noise + + Methods + ------- + + You can use any of the following signatures: + + * noise(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] Parameters ---------- - end: str = '\\n' - line terminator for each string + x: Union[float, npt.NDArray] + x-coordinate in noise space - filename: Union[str, Path] - filename to save string data to + y: Union[float, npt.NDArray] + y-coordinate in noise space - string_data: list[str] - string data to save in a file + z: Union[float, npt.NDArray] + z-coordinate in noise space Notes ----- - Save a list of strings to a file. If ``filename`` is not an absolute path, it - will be saved relative to the current working directory (``sketch_path()``). If - the contents of the list are not already strings, it will be converted to - strings with the Python builtin ``str``. The saved file can be reloaded with - ``load_strings()``. + Generate pseudo-random noise values for specific coodinates using Processing's + noise algorithm. Noise functions are random sequence generators that produce a + more natural, harmonic succession of numbers compared to the `random()` method. - Use the ``end`` parameter to set the line terminator for each string in the - list. If items in the list of strings already have line terminators, set the - ``end`` parameter to ``''`` to keep the output file from being saved with a - blank line after each item. - """ - return _py5sketch.save_strings(string_data, filename, end=end) + In contrast to the `random()` method, noise is defined in an n-dimensional + space, in which each coordinate corresponds to a fixed pseudo-random value + (fixed only for the lifespan of the program). The noise value can be animated by + moving through the noise space, as demonstrated in the examples. Any dimension + can also be interpreted as time. An easy way to animate the noise value is to + pass the `noise()` method the `frame_count` divided by a scaling factor, as is + done in a few of the examples. + The generated noise values for this method will typically be between 0 and 1, + and can be generated in 1, 2, or 3 dimensions. Py5 also provides the + `os_noise()` method, which generates noise using the OpenSimplex 2 algorithm + (smooth version / SuperSimplex). That algorithm generates noise values between + -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of + these differences when modifying your code to switch from one to the other. + There are other differences in the character of the noise values generated by + both methods, so you'll need to do some experimentation to get the results you + want. -def load_bytes(bytes_path: Union[str, Path], ** - kwargs: dict[str, Any]) -> bytearray: - """Load byte data from a file or URL. + The actual noise structure is similar to that of an audio signal, in respect to + the method's use of frequencies. Similar to the concept of harmonics in physics, + both noise algorithms are computed over several octaves which are added together + for the final result. - Underlying Processing method: Sketch.loadBytes + The nature of the noise values returned can be adjusted with `noise_seed()` and + `noise_detail()`. - Parameters - ---------- + Another way to adjust the character of the resulting sequence is the scale of + the input coordinates. As the method works within an infinite space, the value + of the coordinates doesn't matter as such; only the distance between successive + coordinates is important. As a general rule, the smaller the difference between + coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work + best for most applications, but this will differ depending on the use case and + the noise settings. - bytes_path: Union[str, Path] - url or file path for bytes data file + Py5's `noise()` method can also accept numpy arrays as parameters. It will use + broadcasting when needed and calculate the values efficiently. Using numpy array + parameters will be much faster and efficient than calling the `noise()` method + repeatedly in a loop. See the examples to see how this can be done. - kwargs: dict[str, Any] - keyword arguments + Noise generation is a rich and complex topic, and there are many noise + algorithms and libraries available that are worth learning about. Early versions + of py5 used the Python "noise" library, which can generate noise using the + "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH + paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That + Python library was removed from py5 because it has some bugs and hasn't had a + release in years. Nevertheless, it might be useful to you, and can be installed + separately like any other Python package. You can also try the Python library + "vnoise", which is a pure Python implementation of the Improved Perlin Noise + algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise + Lite" to experiment with a large selection of noise algorithms with efficient + implementations. + """ + pass - Notes - ----- - Load byte data from a file or URL. When loading a file, the path can be in the - data directory, relative to the current working directory (``sketch_path()``), - or an absolute path. When loading from a URL, the ``bytes_path`` parameter must - start with ``http://`` or ``https://``. +@overload +def noise(x: Union[float, npt.NDArray], y: Union[float, + npt.NDArray], /) -> Union[float, npt.NDArray]: + """Generate pseudo-random noise values for specific coodinates using Processing's + noise algorithm. - When loading byte data from a URL, the data is retrieved using the Python - requests library with the ``get`` method, and any extra keyword arguments (the - ``kwargs`` parameter) are passed along to that method. When loading byte data - from a file, the ``kwargs`` parameter is not used. - """ - return _py5sketch.load_bytes(bytes_path, **kwargs) + Underlying Processing method: PApplet.noise + Methods + ------- -def save_bytes(bytes_data: Union[bytes, bytearray], - filename: Union[str, Path]) -> None: - """Save byte data to a file. + You can use any of the following signatures: - Underlying Processing method: Sketch.saveBytes + * noise(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] Parameters ---------- - bytes_data: Union[bytes, bytearray] - byte data to save in a file + x: Union[float, npt.NDArray] + x-coordinate in noise space - filename: Union[str, Path] - filename to save byte data to + y: Union[float, npt.NDArray] + y-coordinate in noise space + + z: Union[float, npt.NDArray] + z-coordinate in noise space Notes ----- - Save byte data to a file. If ``filename`` is not an absolute path, it will be - saved relative to the current working directory (``sketch_path()``). The saved - file can be reloaded with ``load_bytes()``. - """ - return _py5sketch.save_bytes(bytes_data, filename) - + Generate pseudo-random noise values for specific coodinates using Processing's + noise algorithm. Noise functions are random sequence generators that produce a + more natural, harmonic succession of numbers compared to the `random()` method. -def load_pickle(pickle_path: Union[str, Path]) -> Any: - """Load a pickled Python object from a file. + In contrast to the `random()` method, noise is defined in an n-dimensional + space, in which each coordinate corresponds to a fixed pseudo-random value + (fixed only for the lifespan of the program). The noise value can be animated by + moving through the noise space, as demonstrated in the examples. Any dimension + can also be interpreted as time. An easy way to animate the noise value is to + pass the `noise()` method the `frame_count` divided by a scaling factor, as is + done in a few of the examples. - Underlying Processing method: Sketch.loadPickle + The generated noise values for this method will typically be between 0 and 1, + and can be generated in 1, 2, or 3 dimensions. Py5 also provides the + `os_noise()` method, which generates noise using the OpenSimplex 2 algorithm + (smooth version / SuperSimplex). That algorithm generates noise values between + -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of + these differences when modifying your code to switch from one to the other. + There are other differences in the character of the noise values generated by + both methods, so you'll need to do some experimentation to get the results you + want. - Parameters - ---------- + The actual noise structure is similar to that of an audio signal, in respect to + the method's use of frequencies. Similar to the concept of harmonics in physics, + both noise algorithms are computed over several octaves which are added together + for the final result. - pickle_path: Union[str, Path] - file path for pickle object file + The nature of the noise values returned can be adjusted with `noise_seed()` and + `noise_detail()`. - Notes - ----- + Another way to adjust the character of the resulting sequence is the scale of + the input coordinates. As the method works within an infinite space, the value + of the coordinates doesn't matter as such; only the distance between successive + coordinates is important. As a general rule, the smaller the difference between + coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work + best for most applications, but this will differ depending on the use case and + the noise settings. - Load a pickled Python object from a file. The path can be in the data directory, - relative to the current working directory (``sketch_path()``), or an absolute - path. + Py5's `noise()` method can also accept numpy arrays as parameters. It will use + broadcasting when needed and calculate the values efficiently. Using numpy array + parameters will be much faster and efficient than calling the `noise()` method + repeatedly in a loop. See the examples to see how this can be done. - There are security risks associated with Python pickle files. A pickle file can - contain malicious code, so never load a pickle file from an untrusted source. + Noise generation is a rich and complex topic, and there are many noise + algorithms and libraries available that are worth learning about. Early versions + of py5 used the Python "noise" library, which can generate noise using the + "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH + paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That + Python library was removed from py5 because it has some bugs and hasn't had a + release in years. Nevertheless, it might be useful to you, and can be installed + separately like any other Python package. You can also try the Python library + "vnoise", which is a pure Python implementation of the Improved Perlin Noise + algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise + Lite" to experiment with a large selection of noise algorithms with efficient + implementations. """ - return _py5sketch.load_pickle(pickle_path) + pass -def save_pickle(obj: Any, filename: Union[str, Path]) -> None: - """Pickle a Python object to a file. +@overload +def noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], + z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: + """Generate pseudo-random noise values for specific coodinates using Processing's + noise algorithm. - Underlying Processing method: Sketch.savePickle + Underlying Processing method: PApplet.noise + + Methods + ------- + + You can use any of the following signatures: + + * noise(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] Parameters ---------- - filename: Union[str, Path] - filename to save pickled object to + x: Union[float, npt.NDArray] + x-coordinate in noise space - obj: Any - any non-py5 Python object + y: Union[float, npt.NDArray] + y-coordinate in noise space + + z: Union[float, npt.NDArray] + z-coordinate in noise space Notes ----- - Pickle a Python object to a file. If ``filename`` is not an absolute path, it - will be saved relative to the current working directory (``sketch_path()``). The - saved file can be reloaded with ``load_pickle()``. + Generate pseudo-random noise values for specific coodinates using Processing's + noise algorithm. Noise functions are random sequence generators that produce a + more natural, harmonic succession of numbers compared to the `random()` method. - Object "pickling" is a method for serializing objects and saving them to a file - for later retrieval. The recreated objects will be clones of the original - objects. Not all Python objects can be saved to a Python pickle file. This - limitation prevents any py5 object from being pickled. + In contrast to the `random()` method, noise is defined in an n-dimensional + space, in which each coordinate corresponds to a fixed pseudo-random value + (fixed only for the lifespan of the program). The noise value can be animated by + moving through the noise space, as demonstrated in the examples. Any dimension + can also be interpreted as time. An easy way to animate the noise value is to + pass the `noise()` method the `frame_count` divided by a scaling factor, as is + done in a few of the examples. + + The generated noise values for this method will typically be between 0 and 1, + and can be generated in 1, 2, or 3 dimensions. Py5 also provides the + `os_noise()` method, which generates noise using the OpenSimplex 2 algorithm + (smooth version / SuperSimplex). That algorithm generates noise values between + -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of + these differences when modifying your code to switch from one to the other. + There are other differences in the character of the noise values generated by + both methods, so you'll need to do some experimentation to get the results you + want. + + The actual noise structure is similar to that of an audio signal, in respect to + the method's use of frequencies. Similar to the concept of harmonics in physics, + both noise algorithms are computed over several octaves which are added together + for the final result. + + The nature of the noise values returned can be adjusted with `noise_seed()` and + `noise_detail()`. + + Another way to adjust the character of the resulting sequence is the scale of + the input coordinates. As the method works within an infinite space, the value + of the coordinates doesn't matter as such; only the distance between successive + coordinates is important. As a general rule, the smaller the difference between + coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work + best for most applications, but this will differ depending on the use case and + the noise settings. + + Py5's `noise()` method can also accept numpy arrays as parameters. It will use + broadcasting when needed and calculate the values efficiently. Using numpy array + parameters will be much faster and efficient than calling the `noise()` method + repeatedly in a loop. See the examples to see how this can be done. + + Noise generation is a rich and complex topic, and there are many noise + algorithms and libraries available that are worth learning about. Early versions + of py5 used the Python "noise" library, which can generate noise using the + "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH + paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That + Python library was removed from py5 because it has some bugs and hasn't had a + release in years. Nevertheless, it might be useful to you, and can be installed + separately like any other Python package. You can also try the Python library + "vnoise", which is a pure Python implementation of the Improved Perlin Noise + algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise + Lite" to experiment with a large selection of noise algorithms with efficient + implementations. """ - return _py5sketch.save_pickle(obj, filename) + pass -############################################################################## -# module functions from threads.py -############################################################################## +def noise(*args) -> Union[float, npt.NDArray]: + """Generate pseudo-random noise values for specific coodinates using Processing's + noise algorithm. -def launch_thread( - f: Callable, - name: str = None, - *, - daemon: bool = True, - args: tuple = None, - kwargs: dict = None) -> str: - """Launch a new thread to execute a function in parallel with your Sketch code. + Underlying Processing method: PApplet.noise - Parameters - ---------- + Methods + ------- - args: tuple = None - positional arguments to pass to the given function + You can use any of the following signatures: - daemon: bool = True - if the thread should be a daemon thread + * noise(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - f: Callable - function to call in the launched thread + Parameters + ---------- - kwargs: dict = None - keyword arguments to pass to the given function + x: Union[float, npt.NDArray] + x-coordinate in noise space - name: str = None - name of thread to be created + y: Union[float, npt.NDArray] + y-coordinate in noise space + + z: Union[float, npt.NDArray] + z-coordinate in noise space Notes ----- - Launch a new thread to execute a function in parallel with your Sketch code. - This can be useful for executing non-py5 code that would otherwise slow down the - animation thread and reduce the Sketch's frame rate. + Generate pseudo-random noise values for specific coodinates using Processing's + noise algorithm. Noise functions are random sequence generators that produce a + more natural, harmonic succession of numbers compared to the `random()` method. + + In contrast to the `random()` method, noise is defined in an n-dimensional + space, in which each coordinate corresponds to a fixed pseudo-random value + (fixed only for the lifespan of the program). The noise value can be animated by + moving through the noise space, as demonstrated in the examples. Any dimension + can also be interpreted as time. An easy way to animate the noise value is to + pass the `noise()` method the `frame_count` divided by a scaling factor, as is + done in a few of the examples. - The ``name`` parameter is optional but useful if you want to monitor the thread - with other methods such as ``has_thread()``. If the provided ``name`` is - identical to an already running thread, the running thread will first be stopped - with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. + The generated noise values for this method will typically be between 0 and 1, + and can be generated in 1, 2, or 3 dimensions. Py5 also provides the + `os_noise()` method, which generates noise using the OpenSimplex 2 algorithm + (smooth version / SuperSimplex). That algorithm generates noise values between + -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of + these differences when modifying your code to switch from one to the other. + There are other differences in the character of the noise values generated by + both methods, so you'll need to do some experimentation to get the results you + want. - Use the ``args`` and ``kwargs`` parameters to pass positional and keyword - arguments to the function. + The actual noise structure is similar to that of an audio signal, in respect to + the method's use of frequencies. Similar to the concept of harmonics in physics, + both noise algorithms are computed over several octaves which are added together + for the final result. - Use the ``daemon`` parameter to make the launched thread a daemon that will run - without blocking Python from exiting. This parameter defaults to ``True``, - meaning that function execution can be interupted if the Python process exits. - Note that if the Python process continues running after the Sketch exits, which - is typically the case when using a Jupyter Notebook, this parameter won't have - any effect unless if you try to restart the Notebook kernel. Generally speaking, - setting this parameter to ``False`` causes problems but it is available for - those who really need it. See ``stop_all_threads()`` for a better approach to - exit threads. + The nature of the noise values returned can be adjusted with `noise_seed()` and + `noise_detail()`. - The new thread is a Python thread, so all the usual caveats about the Global - Interpreter Lock (GIL) apply here. + Another way to adjust the character of the resulting sequence is the scale of + the input coordinates. As the method works within an infinite space, the value + of the coordinates doesn't matter as such; only the distance between successive + coordinates is important. As a general rule, the smaller the difference between + coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work + best for most applications, but this will differ depending on the use case and + the noise settings. + + Py5's `noise()` method can also accept numpy arrays as parameters. It will use + broadcasting when needed and calculate the values efficiently. Using numpy array + parameters will be much faster and efficient than calling the `noise()` method + repeatedly in a loop. See the examples to see how this can be done. + + Noise generation is a rich and complex topic, and there are many noise + algorithms and libraries available that are worth learning about. Early versions + of py5 used the Python "noise" library, which can generate noise using the + "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH + paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That + Python library was removed from py5 because it has some bugs and hasn't had a + release in years. Nevertheless, it might be useful to you, and can be installed + separately like any other Python package. You can also try the Python library + "vnoise", which is a pure Python implementation of the Improved Perlin Noise + algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise + Lite" to experiment with a large selection of noise algorithms with efficient + implementations. """ - return _py5sketch.launch_thread( - f, name=name, daemon=daemon, args=args, kwargs=kwargs) + return _py5sketch.noise(*args) -def launch_promise_thread( - f: Callable, - name: str = None, - *, - daemon: bool = True, - args: tuple = None, - kwargs: dict = None) -> Py5Promise: - """Create a ``Py5Promise`` object that will store the returned result of a function - when that function completes. +@overload +def os_noise(x: Union[float, npt.NDArray], y: Union[float, + npt.NDArray], /) -> Union[float, npt.NDArray]: + """Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). + + Methods + ------- + + You can use any of the following signatures: + + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] Parameters ---------- - args: tuple = None - positional arguments to pass to the given function - - daemon: bool = True - if the thread should be a daemon thread + w: Union[float, npt.NDArray] + w-coordinate in noise space - f: Callable - function to call in the launched thread + x: Union[float, npt.NDArray] + x-coordinate in noise space - kwargs: dict = None - keyword arguments to pass to the given function + y: Union[float, npt.NDArray] + y-coordinate in noise space - name: str = None - name of thread to be created + z: Union[float, npt.NDArray] + z-coordinate in noise space Notes ----- - Create a ``Py5Promise`` object that will store the returned result of a function - when that function completes. This can be useful for executing non-py5 code that - would otherwise slow down the animation thread and reduce the Sketch's frame - rate. + Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are + random sequence generators that produce a more natural, harmonic succession of + numbers compared to the `random()` method. + + In contrast to the `random()` method, noise is defined in an n-dimensional + space, in which each coordinate corresponds to a fixed pseudo-random value + (fixed only for the lifespan of the program). The noise value can be animated by + moving through the noise space, as demonstrated in the examples. Any dimension + can also be interpreted as time. An easy way to animate the noise value is to + pass the `os_noise()` method the `frame_count` divided by a scaling factor, as + is done in a few of the examples. - The ``Py5Promise`` object has an ``is_ready`` property that will be ``True`` - when the ``result`` property contains the value function ``f`` returned. Before - then, the ``result`` property will be ``None``. + The generated noise values for this method will be between -1 and 1, and can be + generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a + constant value as an extra parameter, as shown in a few examples. Py5 also + provides the `noise()` method, which generates noise using Processing's noise + algorithm. That algorithm typically generates noise values between 0 and 1, and + can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences + when modifying your code to switch from one to the other. There are other + differences in the character of the noise values generated by both methods, so + you'll need to do some experimentation to get the results you want. - The ``name`` parameter is optional but useful if you want to monitor the thread - with other methods such as ``has_thread()``. If the provided ``name`` is - identical to an already running thread, the running thread will first be stopped - with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. + The nature of the noise values returned can be adjusted with `os_noise_seed()`. - Use the ``args`` and ``kwargs`` parameters to pass positional and keyword - arguments to the function. + Another way to adjust the character of the resulting sequence is the scale of + the input coordinates. As the method works within an infinite space, the value + of the coordinates doesn't matter as such; only the distance between successive + coordinates is important. As a general rule, the smaller the difference between + coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work + best for most applications, but this will differ depending on the use case and + the noise settings. - Use the ``daemon`` parameter to make the launched thread a daemon that will run - without blocking Python from exiting. This parameter defaults to ``True``, - meaning that function execution can be interupted if the Python process exits. - Note that if the Python process continues running after the Sketch exits, which - is typically the case when using a Jupyter Notebook, this parameter won't have - any effect unless if you try to restart the Notebook kernel. Generally speaking, - setting this parameter to ``False`` causes problems but it is available for - those who really need it. See ``stop_all_threads()`` for a better approach to - exit threads. + Py5's `os_noise()` method can also accept numpy arrays as parameters. It will + use broadcasting when needed and calculate the values efficiently. Using numpy + array parameters will be much faster and efficient than calling the `os_noise()` + method repeatedly in a loop. See the examples to see how this can be done. The + noise algorithm for this method is implemented in Java. - The new thread is a Python thread, so all the usual caveats about the Global - Interpreter Lock (GIL) apply here. + Noise generation is a rich and complex topic, and there are many noise + algorithms and libraries available that are worth learning about. Early versions + of py5 used the Python "noise" library, which can generate noise using the + "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH + paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That + Python library was removed from py5 because it has some bugs and hasn't had a + release in years. Nevertheless, it might be useful to you, and can be installed + separately like any other Python package. You can also try the Python library + "vnoise", which is a pure Python implementation of the Improved Perlin Noise + algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise + Lite" to experiment with a large selection of noise algorithms with efficient + implementations. """ - return _py5sketch.launch_promise_thread( - f, name=name, daemon=daemon, args=args, kwargs=kwargs) + pass -def launch_repeating_thread(f: Callable, name: str = None, *, - time_delay: float = 0, daemon: bool = True, - args: tuple = None, kwargs: dict = None) -> str: - """Launch a new thread that will repeatedly execute a function in parallel with - your Sketch code. +@overload +def os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], + z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: + """Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). + + Methods + ------- + + You can use any of the following signatures: + + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] Parameters ---------- - args: tuple = None - positional arguments to pass to the given function - - daemon: bool = True - if the thread should be a daemon thread - - f: Callable - function to call in the launched thread + w: Union[float, npt.NDArray] + w-coordinate in noise space - kwargs: dict = None - keyword arguments to pass to the given function + x: Union[float, npt.NDArray] + x-coordinate in noise space - name: str = None - name of thread to be created + y: Union[float, npt.NDArray] + y-coordinate in noise space - time_delay: float = 0 - time delay in seconds between calls to the given function + z: Union[float, npt.NDArray] + z-coordinate in noise space Notes ----- - Launch a new thread that will repeatedly execute a function in parallel with - your Sketch code. This can be useful for executing non-py5 code that would - otherwise slow down the animation thread and reduce the Sketch's frame rate. + Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are + random sequence generators that produce a more natural, harmonic succession of + numbers compared to the `random()` method. - Use the ``time_delay`` parameter to set the time in seconds between one call to - function ``f`` and the next call. Set this parameter to ``0`` if you want each - call to happen immediately after the previous call finishes. If the function - ``f`` takes longer than expected to finish, py5 will wait for it to finish - before making the next call. There will not be overlapping calls to function - ``f``. - - The ``name`` parameter is optional but useful if you want to monitor the thread - with other methods such as ``has_thread()``. If the provided ``name`` is - identical to an already running thread, the running thread will first be stopped - with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. - - Use the ``args`` and ``kwargs`` parameters to pass positional and keyword - arguments to the function. - - Use the ``daemon`` parameter to make the launched thread a daemon that will run - without blocking Python from exiting. This parameter defaults to ``True``, - meaning that function execution can be interupted if the Python process exits. - Note that if the Python process continues running after the Sketch exits, which - is typically the case when using a Jupyter Notebook, this parameter won't have - any effect unless if you try to restart the Notebook kernel. Generally speaking, - setting this parameter to ``False`` causes problems but it is available for - those who really need it. See ``stop_all_threads()`` for a better approach to - exit threads. + In contrast to the `random()` method, noise is defined in an n-dimensional + space, in which each coordinate corresponds to a fixed pseudo-random value + (fixed only for the lifespan of the program). The noise value can be animated by + moving through the noise space, as demonstrated in the examples. Any dimension + can also be interpreted as time. An easy way to animate the noise value is to + pass the `os_noise()` method the `frame_count` divided by a scaling factor, as + is done in a few of the examples. - The new thread is a Python thread, so all the usual caveats about the Global - Interpreter Lock (GIL) apply here. - """ - return _py5sketch.launch_repeating_thread( - f, - name=name, - time_delay=time_delay, - daemon=daemon, - args=args, - kwargs=kwargs) + The generated noise values for this method will be between -1 and 1, and can be + generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a + constant value as an extra parameter, as shown in a few examples. Py5 also + provides the `noise()` method, which generates noise using Processing's noise + algorithm. That algorithm typically generates noise values between 0 and 1, and + can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences + when modifying your code to switch from one to the other. There are other + differences in the character of the noise values generated by both methods, so + you'll need to do some experimentation to get the results you want. + The nature of the noise values returned can be adjusted with `os_noise_seed()`. -def has_thread(name: str) -> None: - """Determine if a thread of a given name exists and is currently running. + Another way to adjust the character of the resulting sequence is the scale of + the input coordinates. As the method works within an infinite space, the value + of the coordinates doesn't matter as such; only the distance between successive + coordinates is important. As a general rule, the smaller the difference between + coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work + best for most applications, but this will differ depending on the use case and + the noise settings. - Parameters - ---------- + Py5's `os_noise()` method can also accept numpy arrays as parameters. It will + use broadcasting when needed and calculate the values efficiently. Using numpy + array parameters will be much faster and efficient than calling the `os_noise()` + method repeatedly in a loop. See the examples to see how this can be done. The + noise algorithm for this method is implemented in Java. - name: str - name of thread + Noise generation is a rich and complex topic, and there are many noise + algorithms and libraries available that are worth learning about. Early versions + of py5 used the Python "noise" library, which can generate noise using the + "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH + paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That + Python library was removed from py5 because it has some bugs and hasn't had a + release in years. Nevertheless, it might be useful to you, and can be installed + separately like any other Python package. You can also try the Python library + "vnoise", which is a pure Python implementation of the Improved Perlin Noise + algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise + Lite" to experiment with a large selection of noise algorithms with efficient + implementations. + """ + pass - Notes - ----- - Determine if a thread of a given name exists and is currently running. You can - get the list of all currently running threads with ``list_threads()``. - """ - return _py5sketch.has_thread(name) +@overload +def os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, + npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: + """Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). + Methods + ------- -def join_thread(name: str, *, timeout: float = None) -> bool: - """Join the Python thread associated with the given thread name. + You can use any of the following signatures: + + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] Parameters ---------- - name: str - name of thread + w: Union[float, npt.NDArray] + w-coordinate in noise space - timeout: float = None - maximum time in seconds to wait for the thread to join + x: Union[float, npt.NDArray] + x-coordinate in noise space + + y: Union[float, npt.NDArray] + y-coordinate in noise space + + z: Union[float, npt.NDArray] + z-coordinate in noise space Notes ----- - Join the Python thread associated with the given thread name. The - ``join_thread()`` method will wait until the named thread has finished executing - before returning. Use the ``timeout`` parameter to set an upper limit for the - number of seconds to wait. This method will return right away if the named - thread does not exist or the thread has already finished executing. You can get - the list of all currently running threads with ``list_threads()``. - - This method will return ``True`` if the named thread has completed execution and - ``False`` if the named thread is still executing. It will only return ``False`` - if you use the ``timeout`` parameter and the method is not able to join with the - thread within that time limit. - """ - return _py5sketch.join_thread(name, timeout=timeout) + Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are + random sequence generators that produce a more natural, harmonic succession of + numbers compared to the `random()` method. + In contrast to the `random()` method, noise is defined in an n-dimensional + space, in which each coordinate corresponds to a fixed pseudo-random value + (fixed only for the lifespan of the program). The noise value can be animated by + moving through the noise space, as demonstrated in the examples. Any dimension + can also be interpreted as time. An easy way to animate the noise value is to + pass the `os_noise()` method the `frame_count` divided by a scaling factor, as + is done in a few of the examples. -def stop_thread(name: str, wait: bool = False) -> None: - """Stop a thread of a given name. + The generated noise values for this method will be between -1 and 1, and can be + generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a + constant value as an extra parameter, as shown in a few examples. Py5 also + provides the `noise()` method, which generates noise using Processing's noise + algorithm. That algorithm typically generates noise values between 0 and 1, and + can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences + when modifying your code to switch from one to the other. There are other + differences in the character of the noise values generated by both methods, so + you'll need to do some experimentation to get the results you want. - Parameters - ---------- + The nature of the noise values returned can be adjusted with `os_noise_seed()`. - name: str - name of thread + Another way to adjust the character of the resulting sequence is the scale of + the input coordinates. As the method works within an infinite space, the value + of the coordinates doesn't matter as such; only the distance between successive + coordinates is important. As a general rule, the smaller the difference between + coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work + best for most applications, but this will differ depending on the use case and + the noise settings. - wait: bool = False - wait for thread to exit before returning + Py5's `os_noise()` method can also accept numpy arrays as parameters. It will + use broadcasting when needed and calculate the values efficiently. Using numpy + array parameters will be much faster and efficient than calling the `os_noise()` + method repeatedly in a loop. See the examples to see how this can be done. The + noise algorithm for this method is implemented in Java. - Notes - ----- + Noise generation is a rich and complex topic, and there are many noise + algorithms and libraries available that are worth learning about. Early versions + of py5 used the Python "noise" library, which can generate noise using the + "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH + paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That + Python library was removed from py5 because it has some bugs and hasn't had a + release in years. Nevertheless, it might be useful to you, and can be installed + separately like any other Python package. You can also try the Python library + "vnoise", which is a pure Python implementation of the Improved Perlin Noise + algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise + Lite" to experiment with a large selection of noise algorithms with efficient + implementations. + """ + pass - Stop a thread of a given name. The ``wait`` parameter determines if the method - call will return right away or wait for the thread to exit. - This won't do anything useful if the thread was launched with either - ``launch_thread()`` or ``launch_promise_thread()`` and the ``wait`` parameter is - ``False``. Non-repeating threads are executed once and will stop when they - complete execution. Setting the ``wait`` parameter to ``True`` will merely block - until the thread exits on its own. Killing off a running thread in Python is - complicated and py5 cannot do that for you. If you want a thread to perform some - action repeatedly and be interuptable, use ``launch_repeating_thread()`` - instead. +def os_noise(*args) -> Union[float, npt.NDArray]: + """Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). - Use ``has_thread()`` to determine if a thread of a given name exists and - ``list_threads()`` to get a list of all thread names. Use ``stop_all_threads()`` - to stop all threads. - """ - return _py5sketch.stop_thread(name, wait=wait) + Methods + ------- + You can use any of the following signatures: -def stop_all_threads(wait: bool = False) -> None: - """Stop all running threads. + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] Parameters ---------- - wait: bool = False - wait for thread to exit before returning + w: Union[float, npt.NDArray] + w-coordinate in noise space + + x: Union[float, npt.NDArray] + x-coordinate in noise space + + y: Union[float, npt.NDArray] + y-coordinate in noise space + + z: Union[float, npt.NDArray] + z-coordinate in noise space Notes ----- - Stop all running threads. The ``wait`` parameter determines if the method call - will return right away or wait for the threads to exit. + Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are + random sequence generators that produce a more natural, harmonic succession of + numbers compared to the `random()` method. - When the Sketch shuts down, ``stop_all_threads(wait=False)`` is called for you. - If you would rather the Sketch waited for threads to exit, create an ``exiting`` - method and make a call to ``stop_all_threads(wait=True)``. - """ - return _py5sketch.stop_all_threads(wait=wait) + In contrast to the `random()` method, noise is defined in an n-dimensional + space, in which each coordinate corresponds to a fixed pseudo-random value + (fixed only for the lifespan of the program). The noise value can be animated by + moving through the noise space, as demonstrated in the examples. Any dimension + can also be interpreted as time. An easy way to animate the noise value is to + pass the `os_noise()` method the `frame_count` divided by a scaling factor, as + is done in a few of the examples. + The generated noise values for this method will be between -1 and 1, and can be + generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a + constant value as an extra parameter, as shown in a few examples. Py5 also + provides the `noise()` method, which generates noise using Processing's noise + algorithm. That algorithm typically generates noise values between 0 and 1, and + can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences + when modifying your code to switch from one to the other. There are other + differences in the character of the noise values generated by both methods, so + you'll need to do some experimentation to get the results you want. -def list_threads() -> None: - """List the names of all of the currently running threads. + The nature of the noise values returned can be adjusted with `os_noise_seed()`. - Notes - ----- + Another way to adjust the character of the resulting sequence is the scale of + the input coordinates. As the method works within an infinite space, the value + of the coordinates doesn't matter as such; only the distance between successive + coordinates is important. As a general rule, the smaller the difference between + coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work + best for most applications, but this will differ depending on the use case and + the noise settings. - List the names of all of the currently running threads. The names of previously - launched threads that have exited will be removed from the list. + Py5's `os_noise()` method can also accept numpy arrays as parameters. It will + use broadcasting when needed and calculate the values efficiently. Using numpy + array parameters will be much faster and efficient than calling the `os_noise()` + method repeatedly in a loop. See the examples to see how this can be done. The + noise algorithm for this method is implemented in Java. + + Noise generation is a rich and complex topic, and there are many noise + algorithms and libraries available that are worth learning about. Early versions + of py5 used the Python "noise" library, which can generate noise using the + "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH + paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That + Python library was removed from py5 because it has some bugs and hasn't had a + release in years. Nevertheless, it might be useful to you, and can be installed + separately like any other Python package. You can also try the Python library + "vnoise", which is a pure Python implementation of the Improved Perlin Noise + algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise + Lite" to experiment with a large selection of noise algorithms with efficient + implementations. """ - return _py5sketch.list_threads() + return _py5sketch.os_noise(*args) PI = np.pi @@ -20403,12 +20481,12 @@ def sketch_path() -> Path: Notes ----- - The Sketch's current path. If the ``where`` parameter is used, the result will - be a subdirectory of the current path. + The Sketch's current path. If the `where` parameter is used, the result will be + a subdirectory of the current path. - Result will be relative to Python's current working directory (``os.getcwd()``) - unless it was specifically set to something else with the ``run_sketch()`` call - by including a ``--sketch-path`` argument in the ``py5_options`` parameters. + Result will be relative to Python's current working directory (`os.getcwd()`) + unless it was specifically set to something else with the `run_sketch()` call by + including a `--sketch-path` argument in the `py5_options` parameters. """ pass @@ -20436,12 +20514,12 @@ def sketch_path(where: str, /) -> Path: Notes ----- - The Sketch's current path. If the ``where`` parameter is used, the result will - be a subdirectory of the current path. + The Sketch's current path. If the `where` parameter is used, the result will be + a subdirectory of the current path. - Result will be relative to Python's current working directory (``os.getcwd()``) - unless it was specifically set to something else with the ``run_sketch()`` call - by including a ``--sketch-path`` argument in the ``py5_options`` parameters. + Result will be relative to Python's current working directory (`os.getcwd()`) + unless it was specifically set to something else with the `run_sketch()` call by + including a `--sketch-path` argument in the `py5_options` parameters. """ pass @@ -20468,12 +20546,12 @@ def sketch_path(*args) -> Path: Notes ----- - The Sketch's current path. If the ``where`` parameter is used, the result will - be a subdirectory of the current path. + The Sketch's current path. If the `where` parameter is used, the result will be + a subdirectory of the current path. - Result will be relative to Python's current working directory (``os.getcwd()``) - unless it was specifically set to something else with the ``run_sketch()`` call - by including a ``--sketch-path`` argument in the ``py5_options`` parameters. + Result will be relative to Python's current working directory (`os.getcwd()`) + unless it was specifically set to something else with the `run_sketch()` call by + including a `--sketch-path` argument in the `py5_options` parameters. """ return _py5sketch.sketch_path(*args) @@ -20523,14 +20601,14 @@ def profile_functions(function_names: list[str]) -> None: information can be used to target the performance tuning efforts for a slow Sketch. - This method can be called before or after ``run_sketch()``. You are welcome to + This method can be called before or after `run_sketch()`. You are welcome to profile multiple functions, but don't initiate profiling on the same function multiple times. To profile functions that do not belong to the Sketch, including - any functions called from ``launch_thread()`` and the like, use lineprofiler + any functions called from `launch_thread()` and the like, use lineprofiler directly and not through py5's performance tools. - To profile just the draw function, you can also use ``profile_draw()``. To see - the results, use ``print_line_profiler_stats()``. + To profile just the draw function, you can also use `profile_draw()`. To see the + results, use `print_line_profiler_stats()`. """ return _py5sketch.profile_functions(function_names) @@ -20547,30 +20625,30 @@ def profile_draw() -> None: (Hits) and the total amount of time spent on each line (Time). This information can be used to target the performance tuning efforts for a slow Sketch. - This method can be called before or after ``run_sketch()``. You are welcome to + This method can be called before or after `run_sketch()`. You are welcome to profile multiple functions, but don't initiate profiling on the same function multiple times. To profile functions that do not belong to the Sketch, including - any functions called from ``launch_thread()`` and the like, use lineprofiler + any functions called from `launch_thread()` and the like, use lineprofiler directly and not through py5's performance tools. - To profile a other functions besides draw, use ``profile_functions()``. To see - the results, use ``print_line_profiler_stats()``. + To profile a other functions besides draw, use `profile_functions()`. To see the + results, use `print_line_profiler_stats()`. """ return _py5sketch.profile_draw() def print_line_profiler_stats() -> None: - """Print the line profiler stats initiated with ``profile_draw()`` or - ``profile_functions()``. + """Print the line profiler stats initiated with `profile_draw()` or + `profile_functions()`. Notes ----- - Print the line profiler stats initiated with ``profile_draw()`` or - ``profile_functions()``. The collected stats will include the number of times - each line of code was executed (Hits) and the total amount of time spent on each - line (Time). This information can be used to target the performance tuning - efforts for a slow Sketch. + Print the line profiler stats initiated with `profile_draw()` or + `profile_functions()`. The collected stats will include the number of times each + line of code was executed (Hits) and the total amount of time spent on each line + (Time). This information can be used to target the performance tuning efforts + for a slow Sketch. This method can be called multiple times on a running Sketch. """ @@ -20612,17 +20690,17 @@ def save_frame(filename: Union[str, to write the image, so it can save images in any format that that library supports. - Use the ``drop_alpha`` parameter to drop the alpha channel from the image. This - defaults to ``True``. Some image formats such as JPG do not support alpha + Use the `drop_alpha` parameter to drop the alpha channel from the image. This + defaults to `True`. Some image formats such as JPG do not support alpha channels, and Pillow will throw an error if you try to save an image with the alpha channel in that format. - The ``use_thread`` parameter will save the image in a separate Python thread. - This improves performance by returning before the image has actually been - written to the file. + The `use_thread` parameter will save the image in a separate Python thread. This + improves performance by returning before the image has actually been written to + the file. - This method is the same as ``save()`` except it will replace a sequence of ``#`` - symbols in the ``filename`` parameter with the frame number. This is useful when + This method is the same as `save()` except it will replace a sequence of `#` + symbols in the `filename` parameter with the frame number. This is useful when saving an image sequence for a running animation. The first frame number will be 1. """ @@ -20658,15 +20736,15 @@ def select_folder( ----- Opens a file chooser dialog to select a folder. After the selection is made, the - selection will be passed to the ``callback`` function. If the dialog is closed - or canceled, ``None`` will be sent to the function, so that the program is not + selection will be passed to the `callback` function. If the dialog is closed or + canceled, `None` will be sent to the function, so that the program is not waiting for additional input. The callback is necessary because of how threading works. This method has some platform specific quirks. On OSX, this does not work when the Sketch is run through a Jupyter notebook. On Windows, Sketches using the - OpenGL renderers (``P2D`` or ``P3D``) will be minimized while the select dialog - box is open. This method only uses native dialog boxes on OSX. + OpenGL renderers (`P2D` or `P3D`) will be minimized while the select dialog box + is open. This method only uses native dialog boxes on OSX. """ return _py5sketch.select_folder( prompt, callback, default_folder=default_folder) @@ -20696,15 +20774,15 @@ def select_input( ----- Open a file chooser dialog to select a file for input. After the selection is - made, the selected File will be passed to the ``callback`` function. If the - dialog is closed or canceled, ``None`` will be sent to the function, so that the - program is not waiting for additional input. The callback is necessary because - of how threading works. + made, the selected File will be passed to the `callback` function. If the dialog + is closed or canceled, `None` will be sent to the function, so that the program + is not waiting for additional input. The callback is necessary because of how + threading works. This method has some platform specific quirks. On OSX, this does not work when the Sketch is run through a Jupyter notebook. On Windows, Sketches using the - OpenGL renderers (``P2D`` or ``P3D``) will be minimized while the select dialog - box is open. This method only uses native dialog boxes on OSX. + OpenGL renderers (`P2D` or `P3D`) will be minimized while the select dialog box + is open. This method only uses native dialog boxes on OSX. """ return _py5sketch.select_input(prompt, callback, default_file=default_file) @@ -20733,15 +20811,15 @@ def select_output( ----- Opens a file chooser dialog to select a file for output. After the selection is - made, the selected File will be passed to the ``callback`` function. If the - dialog is closed or canceled, ``None`` will be sent to the function, so that the - program is not waiting for additional input. The callback is necessary because - of how threading works. + made, the selected File will be passed to the `callback` function. If the dialog + is closed or canceled, `None` will be sent to the function, so that the program + is not waiting for additional input. The callback is necessary because of how + threading works. This method has some platform specific quirks. On OSX, this does not work when the Sketch is run through a Jupyter notebook. On Windows, Sketches using the - OpenGL renderers (``P2D`` or ``P3D``) will be minimized while the select dialog - box is open. This method only uses native dialog boxes on OSX. + OpenGL renderers (`P2D` or `P3D`) will be minimized while the select dialog box + is open. This method only uses native dialog boxes on OSX. """ return _py5sketch.select_output( prompt, callback, default_file=default_file) @@ -20767,20 +20845,20 @@ def create_image_from_numpy( ----- Convert a numpy array into a Py5Image object. The numpy array must have 3 - dimensions and the array's ``dtype`` must be ``np.uint8``. The size of - ``array``'s first and second dimensions will be the image's height and width, - respectively. The third dimension is for the array's color channels. + dimensions and the array's `dtype` must be `np.uint8`. The size of `array`'s + first and second dimensions will be the image's height and width, respectively. + The third dimension is for the array's color channels. - The ``bands`` parameter is used to interpret the ``array``'s color channel - dimension (the array's third dimension). It can be one of ``'L'`` (single- - channel grayscale), ``'ARGB'``, ``'RGB'``, or ``'RGBA'``. If there is no alpha - channel, ``array`` is assumed to have no transparency. If the ``bands`` - parameter is ``'L'``, ``array``'s third dimension is optional. + The `bands` parameter is used to interpret the `array`'s color channel dimension + (the array's third dimension). It can be one of `'L'` (single-channel + grayscale), `'ARGB'`, `'RGB'`, or `'RGBA'`. If there is no alpha channel, + `array` is assumed to have no transparency. If the `bands` parameter is `'L'`, + `array`'s third dimension is optional. The caller can optionally pass an existing Py5Image object to put the image data - into using the ``dst`` parameter. This can have performance benefits in code - that would otherwise continuously create new Py5Image objects. The array's width - and height must match that of the recycled Py5Image object. + into using the `dst` parameter. This can have performance benefits in code that + would otherwise continuously create new Py5Image objects. The array's width and + height must match that of the recycled Py5Image object. """ return _py5sketch.create_image_from_numpy(array, bands=bands, dst=dst) @@ -20803,30 +20881,28 @@ def convert_image(obj: Any, *, dst: Py5Image = None) -> Py5Image: Convert non-py5 image objects into Py5Image objects. This facilitates py5 compatability with other commonly used Python libraries. - This method is comparable to ``load_image()``, except instead of reading image + This method is comparable to `load_image()`, except instead of reading image files from disk, it reads image data from other Python objects. Passed image object types must be known to py5's image conversion tools. New object types and functions to effect conversions can be registered with - ``register_image_conversion()``. + `register_image_conversion()`. - The ``convert_image()`` method has builtin support for conversion of - ``PIL.Image`` objects. This will allow users to use image formats that - ``load_image()`` cannot read. To convert a numpy array into a Py5Image, use - ``create_image_from_numpy()``. + The `convert_image()` method has builtin support for conversion of `PIL.Image` + objects. This will allow users to use image formats that `load_image()` cannot + read. To convert a numpy array into a Py5Image, use `create_image_from_numpy()`. The caller can optionally pass an existing Py5Image object to put the converted - image into using the ``dst`` parameter. This can have performance benefits in - code that would otherwise continuously create new Py5Image objects. The - converted image width and height must match that of the recycled Py5Image - object. + image into using the `dst` parameter. This can have performance benefits in code + that would otherwise continuously create new Py5Image objects. The converted + image width and height must match that of the recycled Py5Image object. """ return _py5sketch.convert_image(obj, dst=dst) def load_image(image_path: Union[str, Path], *, dst: Py5Image = None) -> Py5Image: - """Load an image into a variable of type ``Py5Image``. + """Load an image into a variable of type `Py5Image`. Parameters ---------- @@ -20840,31 +20916,31 @@ def load_image(image_path: Union[str, Path], *, Notes ----- - Load an image into a variable of type ``Py5Image``. Four types of images (GIF, + Load an image into a variable of type `Py5Image`. Four types of images (GIF, JPG, TGA, PNG) can be loaded. To load images in other formats, consider using - ``convert_image()``. + `convert_image()`. - The ``image_path`` parameter can be a file or a URL. When loading a file, the - path can be in the data directory, relative to the current working directory - (``sketch_path()``), or an absolute path. When loading from a URL, the - ``image_path`` parameter must start with ``http://`` or ``https://``. If the - image cannot be loaded, a Python ``RuntimeError`` will be thrown. + The `image_path` parameter can be a file or a URL. When loading a file, the path + can be in the data directory, relative to the current working directory + (`sketch_path()`), or an absolute path. When loading from a URL, the + `image_path` parameter must start with `http://` or `https://`. If the image + cannot be loaded, a Python `RuntimeError` will be thrown. - In most cases, load all images in ``setup()`` to preload them at the start of - the program. Loading images inside ``draw()`` will reduce the speed of a - program. In those situations, consider using ``request_image()`` instead. + In most cases, load all images in `setup()` to preload them at the start of the + program. Loading images inside `draw()` will reduce the speed of a program. In + those situations, consider using `request_image()` instead. - The ``dst`` parameter allows users to store the loaded image into an existing + The `dst` parameter allows users to store the loaded image into an existing Py5Image object instead of creating a new object. The size of the existing Py5Image object must match the size of the loaded image. Most users will not - find the ``dst`` parameter helpful. This feature is needed internally for + find the `dst` parameter helpful. This feature is needed internally for performance reasons. """ return _py5sketch.load_image(image_path, dst=dst) def request_image(image_path: Union[str, Path]) -> Py5Promise: - """Use a Py5Promise object to load an image into a variable of type ``Py5Image``. + """Use a Py5Promise object to load an image into a variable of type `Py5Image`. Parameters ---------- @@ -20875,17 +20951,17 @@ def request_image(image_path: Union[str, Path]) -> Py5Promise: Notes ----- - Use a Py5Promise object to load an image into a variable of type ``Py5Image``. + Use a Py5Promise object to load an image into a variable of type `Py5Image`. This method provides a convenient alternative to combining - ``launch_promise_thread()`` with ``load_image()`` to load image data. + `launch_promise_thread()` with `load_image()` to load image data. - Consider using ``request_image()`` to load image data from within a Sketch's - ``draw()`` function. Using ``load_image()`` in the ``draw()`` function would - slow down the Sketch animation. + Consider using `request_image()` to load image data from within a Sketch's + `draw()` function. Using `load_image()` in the `draw()` function would slow down + the Sketch animation. - The returned Py5Promise object has an ``is_ready`` property that will be - ``True`` when the ``result`` property contains the value function ``f`` - returned. Before then, the ``result`` property will be ``None``. + The returned Py5Promise object has an `is_ready` property that will be `True` + when the `result` property contains the value function `f` returned. Before + then, the `result` property will be `None`. """ return _py5sketch.request_image(image_path) @@ -20894,7 +20970,7 @@ def run_sketch(block: bool = None, *, py5_options: list[str] = None, sketch_args: list[str] = None, sketch_functions: dict[str, Callable] = None, - _jclassname: str = None, + jclassname: str = None, _osx_alt_run_method: bool = True) -> None: """Run the Sketch. @@ -20904,6 +20980,9 @@ def run_sketch(block: bool = None, *, block: bool = None method returns immediately (False) or blocks until Sketch exits (True) + jclassname: str = None + canonical name of class to instantiate when using py5 in processing mode + py5_options: list[str] = None command line arguments to pass to Processing as arguments @@ -20916,56 +20995,58 @@ def run_sketch(block: bool = None, *, Notes ----- - Run the Sketch. Code in the ``settings()``, ``setup()``, and ``draw()`` - functions will be used to actualize your Sketch. + Run the Sketch. Code in the `settings()`, `setup()`, and `draw()` functions will + be used to actualize your Sketch. - Use the ``block`` parameter to specify if the call to ``run_sketch()`` should - return immediately (asynchronous Sketch execution) or block until the Sketch - exits. If the ``block`` parameter is not specified, py5 will first attempt to - determine if the Sketch is running in a Jupyter Notebook or an IPython shell. If - it is, ``block`` will default to ``False``, and ``True`` otherwise. + Use the `block` parameter to specify if the call to `run_sketch()` should return + immediately (asynchronous Sketch execution) or block until the Sketch exits. If + the `block` parameter is not specified, py5 will first attempt to determine if + the Sketch is running in a Jupyter Notebook or an IPython shell. If it is, + `block` will default to `False`, and `True` otherwise. However, on OSX, these + default values are required, as py5 cannot work on OSX without them. - Blocking is not supported on OSX. This is because of the (current) limitations - of py5 on OSX. If the ``block`` parameter is set to ``True``, a warning message - will appear and it will be changed to ``False``. - - A list of strings passed to ``py5_options`` will be passed to the Processing + A list of strings passed to `py5_options` will be passed to the Processing PApplet class as arguments to specify characteristics such as the window's - location on the screen. A list of strings passed to ``sketch_args`` will be - available to a running Sketch using ``pargs``. See the third example for an + location on the screen. A list of strings passed to `sketch_args` will be + available to a running Sketch using `pargs`. See the third example for an example of how this can be used. - When calling ``run_sketch()`` in module mode, py5 will by default search for - functions such as ``setup()``, ``draw()``, etc. in the caller's stack frame and - use those in the Sketch. If for some reason that is not what you want or does - not work because you are hacking py5 to do something unusual, you can use the - ``sketch_functions`` parameter to pass a dictionary of the desired callable - functions. The ``sketch_functions`` parameter is not available when coding py5 - in class mode. Don't forget you can always replace the ``draw()`` function in a - running Sketch using ``hot_reload_draw()``. + When calling `run_sketch()` in module mode, py5 will by default search for + functions such as `setup()`, `draw()`, etc. in the caller's stack frame and use + those in the Sketch. If for some reason that is not what you want or does not + work because you are hacking py5 to do something unusual, you can use the + `sketch_functions` parameter to pass a dictionary of the desired callable + functions. The `sketch_functions` parameter is not available when coding py5 in + class mode. Don't forget you can always replace the `draw()` function in a + running Sketch using `hot_reload_draw()`. When programming in module mode and imported mode, py5 will inspect the - ``setup()`` function and will attempt to split it into synthetic ``settings()`` - and ``setup()`` functions if both were not created by the user and the real - ``setup()`` function contains calls to ``size()``, ``full_screen()``, - ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to those functions - must be at the very beginning of ``setup()``, before any other Python code - (except for comments). This feature allows the user to omit the ``settings()`` - function, much like what can be done while programming in the Processing IDE. - This feature is not available when programming in class mode. - - When running a Sketch asynchronously through Jupyter Notebook, any ``print`` + `setup()` function and will attempt to split it into synthetic `settings()` and + `setup()` functions if both were not created by the user and the real `setup()` + function contains calls to `size()`, `full_screen()`, `smooth()`, `no_smooth()`, + or `pixel_density()`. Calls to those functions must be at the very beginning of + `setup()`, before any other Python code (except for comments). This feature + allows the user to omit the `settings()` function, much like what can be done + while programming in the Processing IDE. This feature is not available when + programming in class mode. + + When running a Sketch asynchronously through Jupyter Notebook, any `print` statements using Python's builtin function will always appear in the output of the currently active cell. This will rarely be desirable, as the active cell will keep changing as the user executes code elsewhere in the notebook. As an - alternative, use py5's ``println()`` method, which will place all text in the - output of the cell that made the ``run_sketch()`` call. This will continue to be + alternative, use py5's `println()` method, which will place all text in the + output of the cell that made the `run_sketch()` call. This will continue to be true if the user moves on to execute code in other Notebook cells. Use - ``set_println_stream()`` to customize this behavior. All py5 error messages and - stack traces are routed through the ``println()`` method. Be aware that some - error messages and warnings generated inside the Processing Jars cannot be - controlled in the same way, and may appear in the output of the active cell or - mixed in with the Jupyter Kernel logs.""" + `set_println_stream()` to customize this behavior. All py5 error messages and + stack traces are routed through the `println()` method. Be aware that some error + messages and warnings generated inside the Processing Jars cannot be controlled + in the same way, and may appear in the output of the active cell or mixed in + with the Jupyter Kernel logs. + + The `jclassname` parameter should only be used when programming in Processing + Mode. This value must be the canonical name of your Processing Sketch class + (i.e. `"org.test.MySketch"`). The class must inherit from `py5.core.SketchBase`. + Read py5's online documentation to learn more about Processing Mode.""" caller_globals = inspect.stack()[1].frame.f_globals caller_locals = inspect.stack()[1].frame.f_locals functions, function_param_counts = bridge._extract_py5_user_function_data( @@ -20978,7 +21059,7 @@ def run_sketch(block: bool = None, *, mode='imported' if _PY5_USE_IMPORTED_MODE else 'module') if not set(functions.keys()) & set( - ['settings', 'setup', 'draw']) and not _jclassname: + ['settings', 'setup', 'draw']) and not jclassname: warnings.warn( ("Unable to find settings, setup, or draw functions. " "Your sketch will be a small gray square. " @@ -20992,8 +21073,8 @@ def run_sketch(block: bool = None, *, 'Sketch is already running. To run a new sketch, exit the running sketch first.', file=sys.stderr) return - if _py5sketch.is_dead or _jclassname: - _py5sketch = Sketch(_jclassname=_jclassname) + if _py5sketch.is_dead or jclassname: + _py5sketch = Sketch(jclassname=jclassname) _prepare_dynamic_variables(caller_locals, caller_globals) @@ -21007,12 +21088,12 @@ def run_sketch(block: bool = None, *, def get_current_sketch() -> Sketch: - """Get the py5 module's current ``Sketch`` instance. + """Get the py5 module's current `Sketch` instance. Notes ----- - Get the py5 module's current ``Sketch`` instance. + Get the py5 module's current `Sketch` instance. When coding py5 in module mode, a Sketch instance is created on your behalf that is referenced within the py5 module itself. That Sketch is called the "current @@ -21020,27 +21101,38 @@ def get_current_sketch() -> Sketch: return _py5sketch -def reset_py5(*, _jclassname: str = None, _force=False) -> bool: - """Reset the py5 module's current ``Sketch`` instance. +def reset_py5(*, jclassname: str = None, _force=False) -> bool: + """Reset the py5 module's current `Sketch` instance. + + Parameters + ---------- + + jclassname: str = None + canonical name of class to instantiate when using py5 in processing mode Notes ----- - Reset the py5 module's current ``Sketch`` instance. + Reset the py5 module's current `Sketch` instance. When coding py5 in module mode, a Sketch instance is created on your behalf that is referenced within the py5 module itself. That Sketch is called the "Current Sketch." If the current Sketch exits, it will be in a dead state and cannot be - re-run. ``reset_py5()`` will discard that exited Sketch instance and replace it + re-run. `reset_py5()` will discard that exited Sketch instance and replace it with a new one in the ready state. - If ``reset_py5()`` is called when the current Sketch is in the ready or running - states, it will do nothing and return ``False``. If ``reset_py5()`` is called - when the current Sketch is in the dead state, ``reset_py5()`` will replace it - and return ``True``.""" + If `reset_py5()` is called when the current Sketch is in the ready or running + states, it will do nothing and return `False`. If `reset_py5()` is called when + the current Sketch is in the dead state, `reset_py5()` will replace it and + return `True`. + + The `jclassname` parameter should only be used when programming in Processing + Mode. This value must be the canonical name of your Processing Sketch class + (i.e. `"org.test.MySketch"`). The class must inherit from `py5.core.SketchBase`. + Read py5's online documentation to learn more about Processing Mode.""" global _py5sketch - if _py5sketch.is_dead or _force or _jclassname: - _py5sketch = Sketch(_jclassname=_jclassname) + if _force or jclassname or _py5sketch.is_dead: + _py5sketch = Sketch(jclassname=jclassname) if _PY5_USE_IMPORTED_MODE: caller_locals = inspect.stack()[1].frame.f_locals caller_globals = inspect.stack()[1].frame.f_globals @@ -21093,9 +21185,9 @@ def set_stackprinter_style(style: str) -> None: Set the formatting style for py5's stack traces. Py5 uses the Python library stackprinter to show exception stack traces. The stackprinter library supports - various color styles. By default py5 will use ``'plaintext'``, which does not - use color. Alternative styles using color are ``'darkbg'``, ``'darkbg2'``, - ``'darkbg3'``, ``'lightbg'``, ``'lightbg2'``, and ``'lightbg3'``.""" + various color styles. By default py5 will use `'plaintext'`, which does not use + color. Alternative styles using color are `'darkbg'`, `'darkbg2'`, `'darkbg3'`, + `'lightbg'`, `'lightbg2'`, and `'lightbg3'`.""" from . import bridge bridge._stackprinter_style = style @@ -21104,7 +21196,12 @@ def __getattr__(name): if hasattr(_py5sketch, name): return getattr(_py5sketch, name) else: - raise AttributeError('py5 has no function or field named ' + name) + raise AttributeError( + _spelling.error_msg( + '', + name, + _py5sketch, + module=True)) def __dir__(): diff --git a/py5/base.py b/py5/base.py index be69cf5..756ef34 100644 --- a/py5/base.py +++ b/py5/base.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by diff --git a/py5/bridge.py b/py5/bridge.py index 3faefcd..5f66c2a 100644 --- a/py5/bridge.py +++ b/py5/bridge.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -33,11 +33,7 @@ import py5_tools from . import reference from . import custom_exceptions -# from . import java_conversion -# *** stacktrace configuration *** -# set stackprinter color style. Default is plaintext. Other choices are darkbg, -# darkbg2, darkbg3, lightbg, lightbg2, lightbg3. _stackprinter_style = 'plaintext' # prune tracebacks to only show only show stack levels in the user's py5 code. _prune_tracebacks = True @@ -95,12 +91,13 @@ def handle_exception(println, exc_type, exc_value, exc_tb): tb = exc_tb.tb_next while hasattr(tb, 'tb_next') and hasattr(tb, 'tb_frame'): f_code = tb.tb_frame.f_code - if f_code.co_filename.startswith(_MODULE_INSTALL_DIR): + if f_code.co_filename.startswith( + _MODULE_INSTALL_DIR) and not f_code.co_name.endswith('py5_no_prune'): py5info.append((Path(f_code.co_filename[(len(_MODULE_INSTALL_DIR) + 1):]).parts, f_code.co_name)) if trim_tb is None: trim_tb = prev_tb - elif f_code.co_filename.startswith(_PY5TOOLS_MODULE_INSTALL_DIR): + elif f_code.co_filename.startswith(_PY5TOOLS_MODULE_INSTALL_DIR) and not f_code.co_name.endswith('py5_no_prune'): py5info.append((Path(f_code.co_filename[( len(_PY5TOOLS_MODULE_INSTALL_DIR) + 1):]).parts, f_code.co_name)) if trim_tb is None: @@ -134,7 +131,7 @@ def handle_exception(println, exc_type, exc_value, exc_tb): while m := _PY5_STATIC_CODE_FILENAME_REGEX.search(errmsg): errmsg = errmsg[m.span()[1]:] else: - errmsg = "py5 encountered an error in your code:" + errmsg + errmsg = "py5 encountered an error in your code:\n\n" + errmsg println(errmsg, stderr=True) @@ -174,8 +171,9 @@ def __init__(self, sketch): self._current_running_method = None self._is_terminated = False - from .java_conversion import convert_to_python_types + from .object_conversion import convert_to_python_types, convert_to_java_type self._convert_to_python_types = convert_to_python_types + self._convert_to_java_type = convert_to_java_type def set_functions(self, functions, function_param_counts): self._function_param_counts = dict() @@ -294,11 +292,11 @@ def call_function(self, key, params): subd = d[s] if isinstance(subd, dict): d = subd - elif hasattr(subd, '__dict__'): - d = subd.__dict__ + elif hasattr(subd, '__dir__') or hasattr(subd, '__dict__'): + d = {k: getattr(subd, k) for k in dir(subd)} else: return _JAVA_RUNTIMEEXCEPTION( - f'{s} in key {key} does map to dict or object with __dict__ attribute') + f'{s} in key {key} does not map to a dict or an object that can be inspected with dir()') else: return _JAVA_RUNTIMEEXCEPTION( f'{s} not found with key {key}') @@ -314,7 +312,7 @@ def call_function(self, key, params): key) if key in py5_tools.config._PY5_PROCESSING_MODE_KEYS: py5_tools.config._PY5_PROCESSING_MODE_KEYS.pop(key) - return retval + return self._convert_to_java_type(retval) except Exception as e: handle_exception(self._sketch.println, *sys.exc_info()) return _JAVA_RUNTIMEEXCEPTION(str(e)) diff --git a/py5/create_font_tool.py b/py5/create_font_tool.py index fd98266..c227302 100644 --- a/py5/create_font_tool.py +++ b/py5/create_font_tool.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -36,6 +36,13 @@ def __init__( self.filename = filename or f'{font_name}-{font_size}.vlw' self.characters = characters + def __str__(self) -> str: + return f"CreateFontTool(font_name='" + self.font_name + \ + "', font_size=" + str(self.font_size) + ")" + + def __repr__(self) -> str: + return self.__str__() + def settings(self): self.size(400, 100, self.P2D) @@ -103,16 +110,16 @@ def create_font_file( By default it will create data files for every character available in the specified font. To reduce execution time and output file size, limit the - characters using the ``characters`` parameter. The default output filename is - ``{font_name}-{font_size}.vlw`` and will be saved to the current directory. + characters using the `characters` parameter. The default output filename is + `{font_name}-{font_size}.vlw` and will be saved to the current directory. This utility function opens a window that displays a short message about the number of glyphs written to the file. To make the window close automatically, - set the ``pause`` parameter to ``False``. + set the `pause` parameter to `False`. Get a list of font names available on your computer with Py5Font's - ``Py5Font.list()`` method. If you request an unavailable font, it will create - the data file anyway but using a default font.""" + `Py5Font.list()` method. If you request an unavailable font, it will create the + data file anyway but using a default font.""" vlw_creator = CreateFontTool(font_name, font_size, filename=filename, characters=characters, pause=pause) diff --git a/py5/custom_exceptions.py b/py5/custom_exceptions.py index 396d9ee..004f2cb 100644 --- a/py5/custom_exceptions.py +++ b/py5/custom_exceptions.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -19,10 +19,14 @@ # ***************************************************************************** import re +import py5_tools + from . import reference +from . import spelling JPYPE_TYPEERROR_REGEX = re.compile( r'No matching overloads found for [\w\.]*(\([^\)]*\))') +IMPORTED_MODE_NAMEERROR_REGEX = re.compile(r"name '(\w+)' is not defined") def handle_typeerror(exc_type_name, exc_msg, py5info): @@ -46,6 +50,21 @@ def handle_typeerror(exc_type_name, exc_msg, py5info): return exc_msg +def handle_nameerror(exc_type_name, exc_msg, py5info): + if py5_tools.imported.get_imported_mode(): + m = IMPORTED_MODE_NAMEERROR_REGEX.match(exc_msg) + if m: + fname = m.group(1) + exc_msg = 'The name "' + fname + '" is not defined.' + suggestion_list = spelling.suggestions( + fname, py5_tools.reference.PY5_DIR_STR) + if suggestion_list: + exc_msg += ' Did you mean ' + suggestion_list + '?' + + return exc_msg + + CUSTOM_EXCEPTION_MSGS = dict( TypeError=handle_typeerror, + NameError=handle_nameerror, ) diff --git a/py5/decorators.py b/py5/decorators.py index bb02f77..723de3d 100644 --- a/py5/decorators.py +++ b/py5/decorators.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by diff --git a/py5/font.py b/py5/font.py index 7008aec..83428d3 100644 --- a/py5/font.py +++ b/py5/font.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -28,6 +28,7 @@ from .shape import Py5Shape, _return_py5shape # noqa from .decorators import _ret_str # noqa +from . import spelling def _return_py5font(f): @@ -72,16 +73,16 @@ class Py5Font: ----- Py5Font is the font class for py5. To create a font to use with py5, use - ``create_font_file()``. This will create a font in the format py5 requires. Py5 + `create_font_file()`. This will create a font in the format py5 requires. Py5 displays fonts using the .vlw font format, which uses images for each letter, - rather than defining them through vector data. The ``load_font()`` function - constructs a new font and ``text_font()`` makes a font active. The - ``Py5Font.list()`` method creates a list of the fonts installed on the computer, - which is useful information to use with the ``create_font()`` function for + rather than defining them through vector data. The `load_font()` function + constructs a new font and `text_font()` makes a font active. The + `Py5Font.list()` method creates a list of the fonts installed on the computer, + which is useful information to use with the `create_font()` function for dynamically converting fonts into a format to use with py5. - To create a new font dynamically, use the ``create_font()`` function. Do not use - the syntax ``Py5Font()``. + To create a new font dynamically, use the `create_font()` function. Do not use + the syntax `Py5Font()`. """ _cls = jpype.JClass('processing.core.PFont') CHARSET = _cls.CHARSET @@ -98,6 +99,16 @@ def __new__(cls, pfont): cls._py5_object_cache.add(o) return o + def __str__(self) -> str: + return "Py5Font(font_name='" + self.get_name() + \ + "', font_size=" + str(self.get_size()) + ")" + + def __repr__(self) -> str: + return self.__str__() + + def __getattr__(self, name): + raise AttributeError(spelling.error_msg('Py5Font', name, self)) + def ascent(self) -> float: """Get the ascent of this font from the baseline. @@ -125,17 +136,17 @@ def descent(self) -> float: return self._instance.descent() def get_default_size(self) -> int: - """Get the font's size that will be used when ``text_font()`` is called. + """Get the font's size that will be used when `text_font()` is called. Underlying Processing method: PFont.getDefaultSize Notes ----- - Get the font's size that will be used when ``text_font()`` is called. When - drawing with 2x pixel density, bitmap fonts in OpenGL need to be created at - double the requested size. This ensures that they're shown at half on displays - (so folks don't have to change their sketch code). + Get the font's size that will be used when `text_font()` is called. When drawing + with 2x pixel density, bitmap fonts in OpenGL need to be created at double the + requested size. This ensures that they're shown at half on displays (so folks + don't have to change their sketch code). """ return self._instance.getDefaultSize() @@ -149,8 +160,8 @@ def get_glyph_count(self) -> int: Get the number of glyphs contained in the font. This will be 0 if the font is a "lazy font" that creates glyphs as they are needed by the Sketch. This will be - the case if the font was created with ``create_font()`` without using the - ``charset`` parameter. + the case if the font was created with `create_font()` without using the + `charset` parameter. """ return self._instance.getGlyphCount() @@ -182,7 +193,7 @@ def get_post_script_name(self) -> str: @overload def get_shape(self, ch: chr, /) -> Py5Shape: - """Get a single character as a ``Py5Shape`` object. + """Get a single character as a `Py5Shape` object. Underlying Processing method: PFont.getShape @@ -206,19 +217,19 @@ def get_shape(self, ch: chr, /) -> Py5Shape: Notes ----- - Get a single character as a ``Py5Shape`` object. Use the ``detail`` parameter to + Get a single character as a `Py5Shape` object. Use the `detail` parameter to draw the shape with only straight line segments. - Calling ``Py5Shape.disable_style()`` on the returned ``Py5Shape`` object seems - to be necessary for these to be drawable. + Calling `Py5Shape.disable_style()` on the returned `Py5Shape` object seems to be + necessary for these to be drawable. - This method only works on fonts loaded with ``create_font()``. + This method only works on fonts loaded with `create_font()`. """ pass @overload def get_shape(self, ch: chr, detail: float, /) -> Py5Shape: - """Get a single character as a ``Py5Shape`` object. + """Get a single character as a `Py5Shape` object. Underlying Processing method: PFont.getShape @@ -242,19 +253,19 @@ def get_shape(self, ch: chr, detail: float, /) -> Py5Shape: Notes ----- - Get a single character as a ``Py5Shape`` object. Use the ``detail`` parameter to + Get a single character as a `Py5Shape` object. Use the `detail` parameter to draw the shape with only straight line segments. - Calling ``Py5Shape.disable_style()`` on the returned ``Py5Shape`` object seems - to be necessary for these to be drawable. + Calling `Py5Shape.disable_style()` on the returned `Py5Shape` object seems to be + necessary for these to be drawable. - This method only works on fonts loaded with ``create_font()``. + This method only works on fonts loaded with `create_font()`. """ pass @_return_py5shape def get_shape(self, *args): - """Get a single character as a ``Py5Shape`` object. + """Get a single character as a `Py5Shape` object. Underlying Processing method: PFont.getShape @@ -278,13 +289,13 @@ def get_shape(self, *args): Notes ----- - Get a single character as a ``Py5Shape`` object. Use the ``detail`` parameter to + Get a single character as a `Py5Shape` object. Use the `detail` parameter to draw the shape with only straight line segments. - Calling ``Py5Shape.disable_style()`` on the returned ``Py5Shape`` object seems - to be necessary for these to be drawable. + Calling `Py5Shape.disable_style()` on the returned `Py5Shape` object seems to be + necessary for these to be drawable. - This method only works on fonts loaded with ``create_font()``. + This method only works on fonts loaded with `create_font()`. """ return self._instance.getShape(*args) @@ -310,7 +321,7 @@ def is_smooth(self) -> bool: ----- Boolean value reflecting if smoothing (anti-aliasing) was used when the font was - created. By default, ``create_font()`` will use smoothing. + created. By default, `create_font()` will use smoothing. """ return self._instance.isSmooth() @@ -326,7 +337,7 @@ def list(cls) -> list[str]: Gets a list of the fonts installed on the system. The data is returned as a list of strings. This list provides the names of each font for input into - ``create_font()``, which allows py5 to dynamically format fonts. + `create_font()`, which allows py5 to dynamically format fonts. This works outside of a running Sketch. """ diff --git a/py5/graphics.py b/py5/graphics.py index eacbbfe..bf9abf0 100644 --- a/py5/graphics.py +++ b/py5/graphics.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -22,6 +22,7 @@ import functools from typing import overload # noqa import weakref +import types import numpy as np # noqa import numpy.typing as npt # noqa @@ -36,6 +37,7 @@ from .image import Py5Image, _return_py5image # noqa from .decorators import _text_fix_str, _convert_hex_color, _context_wrapper # noqa from .pmath import _get_matrix_wrapper # noqa +from . import spelling def _return_py5graphics(f): @@ -64,7 +66,7 @@ def decorated(self_, *args): class Py5Graphics(PixelPy5GraphicsMixin, Py5Base): - """Main graphics and rendering context, as well as the base ``API`` implementation + """Main graphics and rendering context, as well as the base `API` implementation for processing "core". Underlying Processing class: PGraphics.PGraphics @@ -72,20 +74,20 @@ class Py5Graphics(PixelPy5GraphicsMixin, Py5Base): Notes ----- - Main graphics and rendering context, as well as the base ``API`` implementation + Main graphics and rendering context, as well as the base `API` implementation for processing "core". Use this class if you need to draw into an off-screen graphics buffer. A Py5Graphics object can be constructed with the - ``create_graphics()`` function. The ``Py5Graphics.begin_draw()`` and - ``Py5Graphics.end_draw()`` methods (see example) are necessary to set up the + `create_graphics()` function. The `Py5Graphics.begin_draw()` and + `Py5Graphics.end_draw()` methods (see example) are necessary to set up the buffer and to finalize it. The fields and methods for this class are extensive. It is critically important that calls to this object's drawing methods are only - used between ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. - Forgetting to call ``Py5Graphics.begin_draw()`` will likely result in an ugly - and unhelpful Java exception. + used between `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. Forgetting + to call `Py5Graphics.begin_draw()` will likely result in an ugly and unhelpful + Java exception. - To create a new graphics context, use the ``create_graphics()`` function. Do not - use the syntax ``Py5Graphics()``. + To create a new graphics context, use the `create_graphics()` function. Do not + use the syntax `Py5Graphics()`. """ _py5_object_cache = weakref.WeakSet() @@ -115,6 +117,16 @@ def __init__(self, pgraphics): self._instance = pgraphics super().__init__(instance=pgraphics) + def __str__(self) -> str: + return f"Py5Graphics(width=" + str(self._get_width()) + \ + ", height=" + str(self._get_height()) + ")" + + def __repr__(self) -> str: + return self.__str__() + + def __getattr__(self, name): + raise AttributeError(spelling.error_msg('Py5Graphics', name, self)) + def _activate_context_manager(self, exit_function, exit_args): self._context_manager_exit_function = exit_function self._context_manager_exit_args = exit_args @@ -134,21 +146,33 @@ def __exit__(self, *exc): self._context_manager_exit_function(*self._context_manager_exit_args) def points(self, coordinates): + if isinstance(coordinates, types.GeneratorType): + coordinates = list(coordinates) _Py5GraphicsHelper.points(self._instance, coordinates) def lines(self, coordinates): + if isinstance(coordinates, types.GeneratorType): + coordinates = list(coordinates) _Py5GraphicsHelper.lines(self._instance, coordinates) def vertices(self, coordinates): + if isinstance(coordinates, types.GeneratorType): + coordinates = list(coordinates) _Py5GraphicsHelper.vertices(self._instance, coordinates) def bezier_vertices(self, coordinates): + if isinstance(coordinates, types.GeneratorType): + coordinates = list(coordinates) _Py5GraphicsHelper.bezierVertices(self._instance, coordinates) def curve_vertices(self, coordinates): + if isinstance(coordinates, types.GeneratorType): + coordinates = list(coordinates) _Py5GraphicsHelper.curveVertices(self._instance, coordinates) def quadratic_vertices(self, coordinates): + if isinstance(coordinates, types.GeneratorType): + coordinates = list(coordinates) _Py5GraphicsHelper.quadraticVertices(self._instance, coordinates) ADD = 2 @@ -304,12 +328,12 @@ def _get_height(self) -> int: ----- System variable that stores the height of the Py5Graphics drawing surface. This - value is set when creating the ``Py5Graphics`` object with the - ``create_graphics()`` method. For example, ``create_graphics(320, 240)`` sets - the ``height`` variable to the value 240. + value is set when creating the `Py5Graphics` object with the `create_graphics()` + method. For example, `create_graphics(320, 240)` sets the `height` variable to + the value 240. - This field is the same as ``height`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``height``. + This field is the same as `height` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `height`. """ return self._instance.height height: int = property( @@ -322,12 +346,12 @@ def _get_height(self) -> int: ----- System variable that stores the height of the Py5Graphics drawing surface. This - value is set when creating the ``Py5Graphics`` object with the - ``create_graphics()`` method. For example, ``create_graphics(320, 240)`` sets - the ``height`` variable to the value 240. + value is set when creating the `Py5Graphics` object with the `create_graphics()` + method. For example, `create_graphics(320, 240)` sets the `height` variable to + the value 240. - This field is the same as ``height`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``height``.""") + This field is the same as `height` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `height`.""") def _get_pixel_density(self) -> int: """Get the pixel density of the Py5Graphics drawing surface. @@ -338,14 +362,14 @@ def _get_pixel_density(self) -> int: ----- Get the pixel density of the Py5Graphics drawing surface. By default this is 1 - but it can be changed by calling ``pixel_density()`` in ``settings()``. + but it can be changed by calling `pixel_density()` in `settings()`. When the pixel density has been set to more than 1, it changes all of the pixel - operations including the way ``Py5Graphics.get()``, ``Py5Graphics.blend()``, - ``Py5Graphics.copy()``, ``Py5Graphics.update_pixels()``, and - ``Py5Graphics.update_np_pixels()`` all work. See the reference for - ``Py5Graphics.pixel_width`` and ``Py5Graphics.pixel_height`` for more - information. + operations including the way `Py5Graphics.get_pixels()`, + `Py5Graphics.set_pixels()`, `Py5Graphics.blend()`, `Py5Graphics.copy()`, + `Py5Graphics.update_pixels()`, and `Py5Graphics.update_np_pixels()` all work. + See the reference for `Py5Graphics.pixel_width` and `Py5Graphics.pixel_height` + for more information. """ return self._instance.pixelDensity pixel_density: int = property( @@ -358,14 +382,14 @@ def _get_pixel_density(self) -> int: ----- Get the pixel density of the Py5Graphics drawing surface. By default this is 1 - but it can be changed by calling ``pixel_density()`` in ``settings()``. + but it can be changed by calling `pixel_density()` in `settings()`. When the pixel density has been set to more than 1, it changes all of the pixel - operations including the way ``Py5Graphics.get()``, ``Py5Graphics.blend()``, - ``Py5Graphics.copy()``, ``Py5Graphics.update_pixels()``, and - ``Py5Graphics.update_np_pixels()`` all work. See the reference for - ``Py5Graphics.pixel_width`` and ``Py5Graphics.pixel_height`` for more - information.""") + operations including the way `Py5Graphics.get_pixels()`, + `Py5Graphics.set_pixels()`, `Py5Graphics.blend()`, `Py5Graphics.copy()`, + `Py5Graphics.update_pixels()`, and `Py5Graphics.update_np_pixels()` all work. + See the reference for `Py5Graphics.pixel_width` and `Py5Graphics.pixel_height` + for more information.""") def _get_pixel_height(self) -> int: """Height of the Py5Graphics drawing surface in pixels. @@ -375,21 +399,21 @@ def _get_pixel_height(self) -> int: Notes ----- - Height of the Py5Graphics drawing surface in pixels. When ``pixel_density(2)`` - was used in ``settings()`` to make use of a high resolution display (called a - Retina display on OSX or high-dpi on Windows and Linux), the width and height of - the Py5Graphics drawing surface does not change, but the number of pixels is + Height of the Py5Graphics drawing surface in pixels. When `pixel_density(2)` was + used in `settings()` to make use of a high resolution display (called a Retina + display on OSX or high-dpi on Windows and Linux), the width and height of the + Py5Graphics drawing surface does not change, but the number of pixels is doubled. As a result, all operations that use pixels (like - ``Py5Graphics.load_pixels()``, ``Py5Graphics.get()``, etc.) happen in this - doubled space. As a convenience, the variables ``Py5Graphics.pixel_width`` and - ``pixel_height`` hold the actual width and height of the drawing surface in + `Py5Graphics.load_pixels()`, `Py5Graphics.get_pixels()`, etc.) happen in this + doubled space. As a convenience, the variables `Py5Graphics.pixel_width` and + `pixel_height` hold the actual width and height of the drawing surface in pixels. This is useful for any Py5Graphics objects that use the - ``Py5Graphics.pixels[]`` or ``Py5Graphics.np_pixels[]`` arrays, for instance, - because the number of elements in each array will be - ``pixel_width*pixel_height``, not ``width*height``. + `Py5Graphics.pixels[]` or `Py5Graphics.np_pixels[]` arrays, for instance, + because the number of elements in each array will be `pixel_width*pixel_height`, + not `width*height`. - This field is the same as ``pixel_height`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``pixel_height``. + This field is the same as `pixel_height` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `pixel_height`. """ return self._instance.pixelHeight pixel_height: int = property( @@ -401,21 +425,21 @@ def _get_pixel_height(self) -> int: Notes ----- - Height of the Py5Graphics drawing surface in pixels. When ``pixel_density(2)`` - was used in ``settings()`` to make use of a high resolution display (called a - Retina display on OSX or high-dpi on Windows and Linux), the width and height of - the Py5Graphics drawing surface does not change, but the number of pixels is + Height of the Py5Graphics drawing surface in pixels. When `pixel_density(2)` was + used in `settings()` to make use of a high resolution display (called a Retina + display on OSX or high-dpi on Windows and Linux), the width and height of the + Py5Graphics drawing surface does not change, but the number of pixels is doubled. As a result, all operations that use pixels (like - ``Py5Graphics.load_pixels()``, ``Py5Graphics.get()``, etc.) happen in this - doubled space. As a convenience, the variables ``Py5Graphics.pixel_width`` and - ``pixel_height`` hold the actual width and height of the drawing surface in + `Py5Graphics.load_pixels()`, `Py5Graphics.get_pixels()`, etc.) happen in this + doubled space. As a convenience, the variables `Py5Graphics.pixel_width` and + `pixel_height` hold the actual width and height of the drawing surface in pixels. This is useful for any Py5Graphics objects that use the - ``Py5Graphics.pixels[]`` or ``Py5Graphics.np_pixels[]`` arrays, for instance, - because the number of elements in each array will be - ``pixel_width*pixel_height``, not ``width*height``. + `Py5Graphics.pixels[]` or `Py5Graphics.np_pixels[]` arrays, for instance, + because the number of elements in each array will be `pixel_width*pixel_height`, + not `width*height`. - This field is the same as ``pixel_height`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``pixel_height``.""") + This field is the same as `pixel_height` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `pixel_height`.""") def _get_pixel_width(self) -> int: """Width of the Py5Graphics drawing surface in pixels. @@ -425,21 +449,21 @@ def _get_pixel_width(self) -> int: Notes ----- - Width of the Py5Graphics drawing surface in pixels. When ``pixel_density(2)`` - was used in ``settings()`` to make use of a high resolution display (called a - Retina display on OSX or high-dpi on Windows and Linux), the width and height of - the Py5Graphics drawing surface does not change, but the number of pixels is + Width of the Py5Graphics drawing surface in pixels. When `pixel_density(2)` was + used in `settings()` to make use of a high resolution display (called a Retina + display on OSX or high-dpi on Windows and Linux), the width and height of the + Py5Graphics drawing surface does not change, but the number of pixels is doubled. As a result, all operations that use pixels (like - ``Py5Graphics.load_pixels()``, ``Py5Graphics.get()``, etc.) happen in this - doubled space. As a convenience, the variables ``pixel_width`` and - ``Py5Graphics.pixel_height`` hold the actual width and height of the drawing + `Py5Graphics.load_pixels()`, `Py5Graphics.get_pixels()`, etc.) happen in this + doubled space. As a convenience, the variables `pixel_width` and + `Py5Graphics.pixel_height` hold the actual width and height of the drawing surface in pixels. This is useful for any Py5Graphics objects that use the - ``Py5Graphics.pixels[]`` or ``Py5Graphics.np_pixels[]`` arrays, for instance, - because the number of elements in each array will be - ``pixel_width*pixel_height``, not ``width*height``. + `Py5Graphics.pixels[]` or `Py5Graphics.np_pixels[]` arrays, for instance, + because the number of elements in each array will be `pixel_width*pixel_height`, + not `width*height`. - This field is the same as ``pixel_width`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``pixel_width``. + This field is the same as `pixel_width` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `pixel_width`. """ return self._instance.pixelWidth pixel_width: int = property( @@ -451,21 +475,21 @@ def _get_pixel_width(self) -> int: Notes ----- - Width of the Py5Graphics drawing surface in pixels. When ``pixel_density(2)`` - was used in ``settings()`` to make use of a high resolution display (called a - Retina display on OSX or high-dpi on Windows and Linux), the width and height of - the Py5Graphics drawing surface does not change, but the number of pixels is + Width of the Py5Graphics drawing surface in pixels. When `pixel_density(2)` was + used in `settings()` to make use of a high resolution display (called a Retina + display on OSX or high-dpi on Windows and Linux), the width and height of the + Py5Graphics drawing surface does not change, but the number of pixels is doubled. As a result, all operations that use pixels (like - ``Py5Graphics.load_pixels()``, ``Py5Graphics.get()``, etc.) happen in this - doubled space. As a convenience, the variables ``pixel_width`` and - ``Py5Graphics.pixel_height`` hold the actual width and height of the drawing + `Py5Graphics.load_pixels()`, `Py5Graphics.get_pixels()`, etc.) happen in this + doubled space. As a convenience, the variables `pixel_width` and + `Py5Graphics.pixel_height` hold the actual width and height of the drawing surface in pixels. This is useful for any Py5Graphics objects that use the - ``Py5Graphics.pixels[]`` or ``Py5Graphics.np_pixels[]`` arrays, for instance, - because the number of elements in each array will be - ``pixel_width*pixel_height``, not ``width*height``. + `Py5Graphics.pixels[]` or `Py5Graphics.np_pixels[]` arrays, for instance, + because the number of elements in each array will be `pixel_width*pixel_height`, + not `width*height`. - This field is the same as ``pixel_width`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``pixel_width``.""") + This field is the same as `pixel_width` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `pixel_width`.""") def _get_width(self) -> int: """System variable that stores the width of the Py5Graphics drawing surface. @@ -476,12 +500,12 @@ def _get_width(self) -> int: ----- System variable that stores the width of the Py5Graphics drawing surface. This - value is set when creating the ``Py5Graphics`` object with the - ``create_graphics()`` method. For example, ``create_graphics(320, 240)`` sets - the ``width`` variable to the value 320. + value is set when creating the `Py5Graphics` object with the `create_graphics()` + method. For example, `create_graphics(320, 240)` sets the `width` variable to + the value 320. - This field is the same as ``width`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``width``. + This field is the same as `width` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `width`. """ return self._instance.width width: int = property( @@ -494,17 +518,17 @@ def _get_width(self) -> int: ----- System variable that stores the width of the Py5Graphics drawing surface. This - value is set when creating the ``Py5Graphics`` object with the - ``create_graphics()`` method. For example, ``create_graphics(320, 240)`` sets - the ``width`` variable to the value 320. + value is set when creating the `Py5Graphics` object with the `create_graphics()` + method. For example, `create_graphics(320, 240)` sets the `width` variable to + the value 320. - This field is the same as ``width`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``width``.""") + This field is the same as `width` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `width`.""") @_convert_hex_color() def alpha(self, rgb: int, /) -> float: """Extracts the alpha value from a color, scaled to match current - ``Py5Graphics.color_mode()``. + `Py5Graphics.color_mode()`. Underlying Processing method: PGraphics.alpha @@ -518,17 +542,17 @@ def alpha(self, rgb: int, /) -> float: ----- Extracts the alpha value from a color, scaled to match current - ``Py5Graphics.color_mode()``. + `Py5Graphics.color_mode()`. - The ``alpha()`` function is easy to use and understand, but it is slower than a - technique called bit shifting. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``alpha()`` but with greater speed by using the - right shift operator (``>>``) with a bit mask. For example, ``alpha(c)`` and ``c - >> 24 & 0xFF`` both extract the alpha value from a color variable ``c`` but the - later is faster. + The `alpha()` function is easy to use and understand, but it is slower than a + technique called bit shifting. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `alpha()` but with greater speed by using the right + shift operator (`>>`) with a bit mask. For example, `alpha(c)` and `c >> 24 & + 0xFF` both extract the alpha value from a color variable `c` but the later is + faster. - This method is the same as ``alpha()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``alpha()``. + This method is the same as `alpha()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `alpha()`. """ return self._instance.alpha(rgb) @@ -571,13 +595,13 @@ def ambient(self, gray: float, /) -> None: Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect and half of the green light to reflect. Use in combination with - ``Py5Graphics.emissive()``, ``Py5Graphics.specular()``, and - ``Py5Graphics.shininess()`` to set the material properties of shapes. + `Py5Graphics.emissive()`, `Py5Graphics.specular()`, and + `Py5Graphics.shininess()` to set the material properties of shapes. - This method is the same as ``ambient()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``ambient()``. + This method is the same as `ambient()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `ambient()`. """ pass @@ -620,13 +644,13 @@ def ambient(self, v1: float, v2: float, v3: float, /) -> None: Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect and half of the green light to reflect. Use in combination with - ``Py5Graphics.emissive()``, ``Py5Graphics.specular()``, and - ``Py5Graphics.shininess()`` to set the material properties of shapes. + `Py5Graphics.emissive()`, `Py5Graphics.specular()`, and + `Py5Graphics.shininess()` to set the material properties of shapes. - This method is the same as ``ambient()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``ambient()``. + This method is the same as `ambient()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `ambient()`. """ pass @@ -669,13 +693,13 @@ def ambient(self, rgb: int, /) -> None: Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect and half of the green light to reflect. Use in combination with - ``Py5Graphics.emissive()``, ``Py5Graphics.specular()``, and - ``Py5Graphics.shininess()`` to set the material properties of shapes. + `Py5Graphics.emissive()`, `Py5Graphics.specular()`, and + `Py5Graphics.shininess()` to set the material properties of shapes. - This method is the same as ``ambient()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``ambient()``. + This method is the same as `ambient()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `ambient()`. """ pass @@ -718,13 +742,13 @@ def ambient(self, *args): Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect and half of the green light to reflect. Use in combination with - ``Py5Graphics.emissive()``, ``Py5Graphics.specular()``, and - ``Py5Graphics.shininess()`` to set the material properties of shapes. + `Py5Graphics.emissive()`, `Py5Graphics.specular()`, and + `Py5Graphics.shininess()` to set the material properties of shapes. - This method is the same as ``ambient()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``ambient()``. + This method is the same as `ambient()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `ambient()`. """ return self._instance.ambient(*args) @@ -769,11 +793,11 @@ def ambient_light(self, v1: float, v2: float, v3: float, /) -> None: Adds an ambient light. Ambient light doesn't come from a specific direction, the rays of light have bounced around so much that objects are evenly lit from all sides. Ambient lights are almost always used in combination with other types of - lights. The ``v1``, ``v2``, and ``v3`` parameters are interpreted as either - ``RGB`` or ``HSB`` values, depending on the current color mode. + lights. The `v1`, `v2`, and `v3` parameters are interpreted as either `RGB` or + `HSB` values, depending on the current color mode. - This method is the same as ``ambient_light()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``ambient_light()``. + This method is the same as `ambient_light()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `ambient_light()`. """ pass @@ -819,11 +843,11 @@ def ambient_light(self, v1: float, v2: float, v3: float, Adds an ambient light. Ambient light doesn't come from a specific direction, the rays of light have bounced around so much that objects are evenly lit from all sides. Ambient lights are almost always used in combination with other types of - lights. The ``v1``, ``v2``, and ``v3`` parameters are interpreted as either - ``RGB`` or ``HSB`` values, depending on the current color mode. + lights. The `v1`, `v2`, and `v3` parameters are interpreted as either `RGB` or + `HSB` values, depending on the current color mode. - This method is the same as ``ambient_light()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``ambient_light()``. + This method is the same as `ambient_light()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `ambient_light()`. """ pass @@ -867,11 +891,11 @@ def ambient_light(self, *args): Adds an ambient light. Ambient light doesn't come from a specific direction, the rays of light have bounced around so much that objects are evenly lit from all sides. Ambient lights are almost always used in combination with other types of - lights. The ``v1``, ``v2``, and ``v3`` parameters are interpreted as either - ``RGB`` or ``HSB`` values, depending on the current color mode. + lights. The `v1`, `v2`, and `v3` parameters are interpreted as either `RGB` or + `HSB` values, depending on the current color mode. - This method is the same as ``ambient_light()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``ambient_light()``. + This method is the same as `ambient_light()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `ambient_light()`. """ return self._instance.ambientLight(*args) @@ -951,10 +975,10 @@ def apply_matrix(self, n00: float, n01: float, n02: float, Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. - This method is the same as ``apply_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``apply_matrix()``. + This method is the same as `apply_matrix()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `apply_matrix()`. """ pass @@ -1051,10 +1075,10 @@ def apply_matrix( Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. - This method is the same as ``apply_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``apply_matrix()``. + This method is the same as `apply_matrix()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `apply_matrix()`. """ pass @@ -1133,10 +1157,10 @@ def apply_matrix(self, source: npt.NDArray[np.floating], /) -> None: Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. - This method is the same as ``apply_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``apply_matrix()``. + This method is the same as `apply_matrix()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `apply_matrix()`. """ pass @@ -1214,10 +1238,10 @@ def apply_matrix(self, *args): Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. - This method is the same as ``apply_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``apply_matrix()``. + This method is the same as `apply_matrix()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `apply_matrix()`. """ return self._instance.applyMatrix(*args) @@ -1264,24 +1288,23 @@ def arc(self, a: float, b: float, c: float, d: float, ----- Draws an arc to the screen. Arcs are drawn along the outer edge of an ellipse - defined by the ``a``, ``b``, ``c``, and ``d`` parameters. The origin of the - arc's ellipse may be changed with the ``Py5Graphics.ellipse_mode()`` function. - Use the ``start`` and ``stop`` parameters to specify the angles (in radians) at - which to draw the arc. The start/stop values must be in clockwise order. + defined by the `a`, `b`, `c`, and `d` parameters. The origin of the arc's + ellipse may be changed with the `Py5Graphics.ellipse_mode()` function. Use the + `start` and `stop` parameters to specify the angles (in radians) at which to + draw the arc. The start/stop values must be in clockwise order. There are three ways to draw an arc; the rendering technique used is defined by the optional seventh parameter. The three options, depicted in the examples, are - ``PIE``, ``OPEN``, and ``CHORD``. The default mode is the ``OPEN`` stroke with a - ``PIE`` fill. + `PIE`, `OPEN`, and `CHORD`. The default mode is the `OPEN` stroke with a `PIE` + fill. - In some cases, the ``arc()`` function isn't accurate enough for smooth drawing. + In some cases, the `arc()` function isn't accurate enough for smooth drawing. For example, the shape may jitter on screen when rotating slowly. If you're having an issue with how arcs are rendered, you'll need to draw the arc yourself - with ``Py5Graphics.begin_shape()`` & ``Py5Graphics.end_shape()`` or a - ``Py5Shape``. + with `Py5Graphics.begin_shape()` & `Py5Graphics.end_shape()` or a `Py5Shape`. - This method is the same as ``arc()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``arc()``. + This method is the same as `arc()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `arc()`. """ pass @@ -1328,24 +1351,23 @@ def arc(self, a: float, b: float, c: float, d: float, ----- Draws an arc to the screen. Arcs are drawn along the outer edge of an ellipse - defined by the ``a``, ``b``, ``c``, and ``d`` parameters. The origin of the - arc's ellipse may be changed with the ``Py5Graphics.ellipse_mode()`` function. - Use the ``start`` and ``stop`` parameters to specify the angles (in radians) at - which to draw the arc. The start/stop values must be in clockwise order. + defined by the `a`, `b`, `c`, and `d` parameters. The origin of the arc's + ellipse may be changed with the `Py5Graphics.ellipse_mode()` function. Use the + `start` and `stop` parameters to specify the angles (in radians) at which to + draw the arc. The start/stop values must be in clockwise order. There are three ways to draw an arc; the rendering technique used is defined by the optional seventh parameter. The three options, depicted in the examples, are - ``PIE``, ``OPEN``, and ``CHORD``. The default mode is the ``OPEN`` stroke with a - ``PIE`` fill. + `PIE`, `OPEN`, and `CHORD`. The default mode is the `OPEN` stroke with a `PIE` + fill. - In some cases, the ``arc()`` function isn't accurate enough for smooth drawing. + In some cases, the `arc()` function isn't accurate enough for smooth drawing. For example, the shape may jitter on screen when rotating slowly. If you're having an issue with how arcs are rendered, you'll need to draw the arc yourself - with ``Py5Graphics.begin_shape()`` & ``Py5Graphics.end_shape()`` or a - ``Py5Shape``. + with `Py5Graphics.begin_shape()` & `Py5Graphics.end_shape()` or a `Py5Shape`. - This method is the same as ``arc()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``arc()``. + This method is the same as `arc()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `arc()`. """ pass @@ -1390,31 +1412,30 @@ def arc(self, *args): ----- Draws an arc to the screen. Arcs are drawn along the outer edge of an ellipse - defined by the ``a``, ``b``, ``c``, and ``d`` parameters. The origin of the - arc's ellipse may be changed with the ``Py5Graphics.ellipse_mode()`` function. - Use the ``start`` and ``stop`` parameters to specify the angles (in radians) at - which to draw the arc. The start/stop values must be in clockwise order. + defined by the `a`, `b`, `c`, and `d` parameters. The origin of the arc's + ellipse may be changed with the `Py5Graphics.ellipse_mode()` function. Use the + `start` and `stop` parameters to specify the angles (in radians) at which to + draw the arc. The start/stop values must be in clockwise order. There are three ways to draw an arc; the rendering technique used is defined by the optional seventh parameter. The three options, depicted in the examples, are - ``PIE``, ``OPEN``, and ``CHORD``. The default mode is the ``OPEN`` stroke with a - ``PIE`` fill. + `PIE`, `OPEN`, and `CHORD`. The default mode is the `OPEN` stroke with a `PIE` + fill. - In some cases, the ``arc()`` function isn't accurate enough for smooth drawing. + In some cases, the `arc()` function isn't accurate enough for smooth drawing. For example, the shape may jitter on screen when rotating slowly. If you're having an issue with how arcs are rendered, you'll need to draw the arc yourself - with ``Py5Graphics.begin_shape()`` & ``Py5Graphics.end_shape()`` or a - ``Py5Shape``. + with `Py5Graphics.begin_shape()` & `Py5Graphics.end_shape()` or a `Py5Shape`. - This method is the same as ``arc()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``arc()``. + This method is the same as `arc()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `arc()`. """ return self._instance.arc(*args) @overload def background(self, gray: float, /) -> None: - """The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. + """The `background()` function sets the color used for the background of the + `Py5Graphics` object. Underlying Processing method: PGraphics.background @@ -1458,24 +1479,24 @@ def background(self, gray: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. The default background is 100% transparent. + The `background()` function sets the color used for the background of the + `Py5Graphics` object. The default background is 100% transparent. An image can also be used as the background, although the image's width and - height must match that of the ``Py5Graphics`` object. Images used with - ``background()`` will ignore the current ``Py5Graphics.tint()`` setting. To - resize an image to the size of the ``Py5Graphics`` object, use - ``image.resize(width, height)``. + height must match that of the `Py5Graphics` object. Images used with + `background()` will ignore the current `Py5Graphics.tint()` setting. To resize + an image to the size of the `Py5Graphics` object, use `image.resize(width, + height)`. - This method is the same as ``background()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``background()``. + This method is the same as `background()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `background()`. """ pass @overload def background(self, gray: float, alpha: float, /) -> None: - """The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. + """The `background()` function sets the color used for the background of the + `Py5Graphics` object. Underlying Processing method: PGraphics.background @@ -1519,24 +1540,24 @@ def background(self, gray: float, alpha: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. The default background is 100% transparent. + The `background()` function sets the color used for the background of the + `Py5Graphics` object. The default background is 100% transparent. An image can also be used as the background, although the image's width and - height must match that of the ``Py5Graphics`` object. Images used with - ``background()`` will ignore the current ``Py5Graphics.tint()`` setting. To - resize an image to the size of the ``Py5Graphics`` object, use - ``image.resize(width, height)``. + height must match that of the `Py5Graphics` object. Images used with + `background()` will ignore the current `Py5Graphics.tint()` setting. To resize + an image to the size of the `Py5Graphics` object, use `image.resize(width, + height)`. - This method is the same as ``background()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``background()``. + This method is the same as `background()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `background()`. """ pass @overload def background(self, v1: float, v2: float, v3: float, /) -> None: - """The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. + """The `background()` function sets the color used for the background of the + `Py5Graphics` object. Underlying Processing method: PGraphics.background @@ -1580,25 +1601,25 @@ def background(self, v1: float, v2: float, v3: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. The default background is 100% transparent. + The `background()` function sets the color used for the background of the + `Py5Graphics` object. The default background is 100% transparent. An image can also be used as the background, although the image's width and - height must match that of the ``Py5Graphics`` object. Images used with - ``background()`` will ignore the current ``Py5Graphics.tint()`` setting. To - resize an image to the size of the ``Py5Graphics`` object, use - ``image.resize(width, height)``. + height must match that of the `Py5Graphics` object. Images used with + `background()` will ignore the current `Py5Graphics.tint()` setting. To resize + an image to the size of the `Py5Graphics` object, use `image.resize(width, + height)`. - This method is the same as ``background()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``background()``. + This method is the same as `background()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `background()`. """ pass @overload def background(self, v1: float, v2: float, v3: float, alpha: float, /) -> None: - """The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. + """The `background()` function sets the color used for the background of the + `Py5Graphics` object. Underlying Processing method: PGraphics.background @@ -1642,24 +1663,24 @@ def background(self, v1: float, v2: float, Notes ----- - The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. The default background is 100% transparent. + The `background()` function sets the color used for the background of the + `Py5Graphics` object. The default background is 100% transparent. An image can also be used as the background, although the image's width and - height must match that of the ``Py5Graphics`` object. Images used with - ``background()`` will ignore the current ``Py5Graphics.tint()`` setting. To - resize an image to the size of the ``Py5Graphics`` object, use - ``image.resize(width, height)``. + height must match that of the `Py5Graphics` object. Images used with + `background()` will ignore the current `Py5Graphics.tint()` setting. To resize + an image to the size of the `Py5Graphics` object, use `image.resize(width, + height)`. - This method is the same as ``background()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``background()``. + This method is the same as `background()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `background()`. """ pass @overload def background(self, rgb: int, /) -> None: - """The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. + """The `background()` function sets the color used for the background of the + `Py5Graphics` object. Underlying Processing method: PGraphics.background @@ -1703,24 +1724,24 @@ def background(self, rgb: int, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. The default background is 100% transparent. + The `background()` function sets the color used for the background of the + `Py5Graphics` object. The default background is 100% transparent. An image can also be used as the background, although the image's width and - height must match that of the ``Py5Graphics`` object. Images used with - ``background()`` will ignore the current ``Py5Graphics.tint()`` setting. To - resize an image to the size of the ``Py5Graphics`` object, use - ``image.resize(width, height)``. + height must match that of the `Py5Graphics` object. Images used with + `background()` will ignore the current `Py5Graphics.tint()` setting. To resize + an image to the size of the `Py5Graphics` object, use `image.resize(width, + height)`. - This method is the same as ``background()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``background()``. + This method is the same as `background()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `background()`. """ pass @overload def background(self, rgb: int, alpha: float, /) -> None: - """The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. + """The `background()` function sets the color used for the background of the + `Py5Graphics` object. Underlying Processing method: PGraphics.background @@ -1764,24 +1785,24 @@ def background(self, rgb: int, alpha: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. The default background is 100% transparent. + The `background()` function sets the color used for the background of the + `Py5Graphics` object. The default background is 100% transparent. An image can also be used as the background, although the image's width and - height must match that of the ``Py5Graphics`` object. Images used with - ``background()`` will ignore the current ``Py5Graphics.tint()`` setting. To - resize an image to the size of the ``Py5Graphics`` object, use - ``image.resize(width, height)``. + height must match that of the `Py5Graphics` object. Images used with + `background()` will ignore the current `Py5Graphics.tint()` setting. To resize + an image to the size of the `Py5Graphics` object, use `image.resize(width, + height)`. - This method is the same as ``background()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``background()``. + This method is the same as `background()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `background()`. """ pass @overload def background(self, image: Py5Image, /) -> None: - """The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. + """The `background()` function sets the color used for the background of the + `Py5Graphics` object. Underlying Processing method: PGraphics.background @@ -1825,24 +1846,24 @@ def background(self, image: Py5Image, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. The default background is 100% transparent. + The `background()` function sets the color used for the background of the + `Py5Graphics` object. The default background is 100% transparent. An image can also be used as the background, although the image's width and - height must match that of the ``Py5Graphics`` object. Images used with - ``background()`` will ignore the current ``Py5Graphics.tint()`` setting. To - resize an image to the size of the ``Py5Graphics`` object, use - ``image.resize(width, height)``. + height must match that of the `Py5Graphics` object. Images used with + `background()` will ignore the current `Py5Graphics.tint()` setting. To resize + an image to the size of the `Py5Graphics` object, use `image.resize(width, + height)`. - This method is the same as ``background()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``background()``. + This method is the same as `background()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `background()`. """ pass @_convert_hex_color() def background(self, *args): - """The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. + """The `background()` function sets the color used for the background of the + `Py5Graphics` object. Underlying Processing method: PGraphics.background @@ -1886,60 +1907,59 @@ def background(self, *args): Notes ----- - The ``background()`` function sets the color used for the background of the - ``Py5Graphics`` object. The default background is 100% transparent. + The `background()` function sets the color used for the background of the + `Py5Graphics` object. The default background is 100% transparent. An image can also be used as the background, although the image's width and - height must match that of the ``Py5Graphics`` object. Images used with - ``background()`` will ignore the current ``Py5Graphics.tint()`` setting. To - resize an image to the size of the ``Py5Graphics`` object, use - ``image.resize(width, height)``. + height must match that of the `Py5Graphics` object. Images used with + `background()` will ignore the current `Py5Graphics.tint()` setting. To resize + an image to the size of the `Py5Graphics` object, use `image.resize(width, + height)`. - This method is the same as ``background()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``background()``. + This method is the same as `background()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `background()`. """ return self._instance.background(*args) @_context_wrapper('end_camera') def begin_camera(self) -> None: - """The ``begin_camera()`` and ``Py5Graphics.end_camera()`` functions enable - advanced customization of the camera space. + """The `begin_camera()` and `Py5Graphics.end_camera()` functions enable advanced + customization of the camera space. Underlying Processing method: PGraphics.beginCamera Notes ----- - The ``begin_camera()`` and ``Py5Graphics.end_camera()`` functions enable - advanced customization of the camera space. The functions are useful if you want - to more control over camera movement, however for most users, the - ``Py5Graphics.camera()`` function will be sufficient. The camera functions will - replace any transformations (such as ``Py5Graphics.rotate()`` or - ``Py5Graphics.translate()``) that occur before them, but they will not - automatically replace the camera transform itself. For this reason, camera - functions should be placed right after the call to ``Py5Graphics.begin_draw()`` - (so that transformations happen afterwards), and the ``Py5Graphics.camera()`` - function can be used after ``begin_camera()`` if you want to reset the camera - before applying transformations. + The `begin_camera()` and `Py5Graphics.end_camera()` functions enable advanced + customization of the camera space. The functions are useful if you want to more + control over camera movement, however for most users, the `Py5Graphics.camera()` + function will be sufficient. The camera functions will replace any + transformations (such as `Py5Graphics.rotate()` or `Py5Graphics.translate()`) + that occur before them, but they will not automatically replace the camera + transform itself. For this reason, camera functions should be placed right after + the call to `Py5Graphics.begin_draw()` (so that transformations happen + afterwards), and the `Py5Graphics.camera()` function can be used after + `begin_camera()` if you want to reset the camera before applying + transformations. This function sets the matrix mode to the camera matrix so calls such as - ``Py5Graphics.translate()``, ``Py5Graphics.rotate()``, - ``Py5Graphics.apply_matrix()`` and ``Py5Graphics.reset_matrix()`` affect the - camera. ``begin_camera()`` should always be used with a following - ``Py5Graphics.end_camera()`` and pairs of ``begin_camera()`` and - ``Py5Graphics.end_camera()`` cannot be nested. + `Py5Graphics.translate()`, `Py5Graphics.rotate()`, `Py5Graphics.apply_matrix()` + and `Py5Graphics.reset_matrix()` affect the camera. `begin_camera()` should + always be used with a following `Py5Graphics.end_camera()` and pairs of + `begin_camera()` and `Py5Graphics.end_camera()` cannot be nested. This method can be used as a context manager to ensure that - ``Py5Graphics.end_camera()`` always gets called, as shown in the example. + `Py5Graphics.end_camera()` always gets called, as shown in the example. - This method is the same as ``begin_camera()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``begin_camera()``. + This method is the same as `begin_camera()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `begin_camera()`. """ return self._instance.beginCamera() @_context_wrapper('end_contour') def begin_contour(self) -> None: - """Use the ``begin_contour()`` and ``Py5Graphics.end_contour()`` methods to create + """Use the `begin_contour()` and `Py5Graphics.end_contour()` methods to create negative shapes within shapes such as the center of the letter 'O'. Underlying Processing method: PGraphics.beginContour @@ -1947,52 +1967,51 @@ def begin_contour(self) -> None: Notes ----- - Use the ``begin_contour()`` and ``Py5Graphics.end_contour()`` methods to create + Use the `begin_contour()` and `Py5Graphics.end_contour()` methods to create negative shapes within shapes such as the center of the letter 'O'. The - ``begin_contour()`` method begins recording vertices for the shape and - ``Py5Graphics.end_contour()`` stops recording. The vertices that define a - negative shape must "wind" in the opposite direction from the exterior shape. - First draw vertices for the exterior shape in clockwise order, then for internal - shapes, draw vertices counterclockwise. - - These methods can only be used within a ``Py5Graphics.begin_shape()`` & - ``Py5Graphics.end_shape()`` pair and transformations such as - ``Py5Graphics.translate()``, ``Py5Graphics.rotate()``, and - ``Py5Graphics.scale()`` do not work within a ``begin_contour()`` & - ``Py5Graphics.end_contour()`` pair. It is also not possible to use other shapes, - such as ``Py5Graphics.ellipse()`` or ``Py5Graphics.rect()`` within. + `begin_contour()` method begins recording vertices for the shape and + `Py5Graphics.end_contour()` stops recording. The vertices that define a negative + shape must "wind" in the opposite direction from the exterior shape. First draw + vertices for the exterior shape in clockwise order, then for internal shapes, + draw vertices counterclockwise. + + These methods can only be used within a `Py5Graphics.begin_shape()` & + `Py5Graphics.end_shape()` pair and transformations such as + `Py5Graphics.translate()`, `Py5Graphics.rotate()`, and `Py5Graphics.scale()` do + not work within a `begin_contour()` & `Py5Graphics.end_contour()` pair. It is + also not possible to use other shapes, such as `Py5Graphics.ellipse()` or + `Py5Graphics.rect()` within. This method can be used as a context manager to ensure that - ``Py5Graphics.end_contour()`` always gets called, as shown in the example. + `Py5Graphics.end_contour()` always gets called, as shown in the example. - This method is the same as ``begin_contour()`` but linked to a ``Py5Graphics`` + This method is the same as `begin_contour()` but linked to a `Py5Graphics` object. """ return self._instance.beginContour() @_context_wrapper('end_draw') def begin_draw(self) -> None: - """Sets the default properties for a ``Py5Graphics`` object. + """Sets the default properties for a `Py5Graphics` object. Underlying Processing method: PGraphics.beginDraw Notes ----- - Sets the default properties for a ``Py5Graphics`` object. It should be called + Sets the default properties for a `Py5Graphics` object. It should be called before anything is drawn into the object. After the drawing commands have - concluded, call ``Py5Graphics.end_draw()`` to finalize the ``Py5Graphics`` - object. + concluded, call `Py5Graphics.end_draw()` to finalize the `Py5Graphics` object. This method can be used as a context manager to ensure that - ``Py5Graphics.end_draw()`` always gets called, as shown in the second example. + `Py5Graphics.end_draw()` always gets called, as shown in the second example. """ return self._instance.beginDraw() @_context_wrapper('end_raw') def begin_raw(self, raw_graphics: Py5Graphics, /) -> None: - """To create vectors from 3D data, use the ``begin_raw()`` and - ``Py5Graphics.end_raw()`` commands. + """To create vectors from 3D data, use the `begin_raw()` and + `Py5Graphics.end_raw()` commands. Underlying Processing method: PGraphics.beginRaw @@ -2005,40 +2024,40 @@ def begin_raw(self, raw_graphics: Py5Graphics, /) -> None: Notes ----- - To create vectors from 3D data, use the ``begin_raw()`` and - ``Py5Graphics.end_raw()`` commands. These commands will grab the shape data just - before it is rendered to the ``Py5Graphics`` object. At this stage, the - ``Py5Graphics`` object contains nothing but a long list of individual lines and - triangles. This means that a shape created with ``Py5Graphics.sphere()`` - function will be made up of hundreds of triangles, rather than a single object. - Or that a multi-segment line shape (such as a curve) will be rendered as - individual segments. + To create vectors from 3D data, use the `begin_raw()` and + `Py5Graphics.end_raw()` commands. These commands will grab the shape data just + before it is rendered to the `Py5Graphics` object. At this stage, the + `Py5Graphics` object contains nothing but a long list of individual lines and + triangles. This means that a shape created with `Py5Graphics.sphere()` function + will be made up of hundreds of triangles, rather than a single object. Or that a + multi-segment line shape (such as a curve) will be rendered as individual + segments. - When using ``begin_raw()`` and ``Py5Graphics.end_raw()``, it's possible to write - to either a 2D or 3D renderer. For instance, ``begin_raw()`` with the ``PDF`` - library will write the geometry as flattened triangles and lines, even if - recording from the ``P3D`` renderer. + When using `begin_raw()` and `Py5Graphics.end_raw()`, it's possible to write to + either a 2D or 3D renderer. For instance, `begin_raw()` with the `PDF` library + will write the geometry as flattened triangles and lines, even if recording from + the `P3D` renderer. - If you want a background to show up in your files, use ``rect(0, 0, width, - height)`` after setting the ``Py5Graphics.fill()`` to the background color. + If you want a background to show up in your files, use `rect(0, 0, width, + height)` after setting the `Py5Graphics.fill()` to the background color. Otherwise the background will not be rendered to the file because the background is not a shape. This method can be used as a context manager to ensure that - ``Py5Graphics.end_raw()`` always gets called, as shown in the example. + `Py5Graphics.end_raw()` always gets called, as shown in the example. - Using ``hint(ENABLE_DEPTH_SORT)`` can improve the appearance of 3D geometry - drawn to 2D file formats. + Using `hint(ENABLE_DEPTH_SORT)` can improve the appearance of 3D geometry drawn + to 2D file formats. - This method is the same as ``begin_raw()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``begin_raw()``. + This method is the same as `begin_raw()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `begin_raw()`. """ return self._instance.beginRaw(raw_graphics) @overload def begin_shape(self) -> None: - """Using the ``begin_shape()`` and ``Py5Graphics.end_shape()`` functions allow - creating more complex forms. + """Using the `begin_shape()` and `Py5Graphics.end_shape()` functions allow creating + more complex forms. Underlying Processing method: PGraphics.beginShape @@ -2059,46 +2078,46 @@ def begin_shape(self) -> None: Notes ----- - Using the ``begin_shape()`` and ``Py5Graphics.end_shape()`` functions allow - creating more complex forms. ``begin_shape()`` begins recording vertices for a - shape and ``Py5Graphics.end_shape()`` stops recording. The value of the ``kind`` - parameter tells it which types of shapes to create from the provided vertices. - With no mode specified, the shape can be any irregular polygon. The parameters - available for ``begin_shape()`` are ``POINTS``, ``LINES``, ``TRIANGLES``, - ``TRIANGLE_FAN``, ``TRIANGLE_STRIP``, ``QUADS``, and ``QUAD_STRIP``. After - calling the ``begin_shape()`` function, a series of ``Py5Graphics.vertex()`` - commands must follow. To stop drawing the shape, call - ``Py5Graphics.end_shape()``. The ``Py5Graphics.vertex()`` function with two - parameters specifies a position in 2D and the ``Py5Graphics.vertex()`` function - with three parameters specifies a position in 3D. Each shape will be outlined - with the current stroke color and filled with the fill color. + Using the `begin_shape()` and `Py5Graphics.end_shape()` functions allow creating + more complex forms. `begin_shape()` begins recording vertices for a shape and + `Py5Graphics.end_shape()` stops recording. The value of the `kind` parameter + tells it which types of shapes to create from the provided vertices. With no + mode specified, the shape can be any irregular polygon. The parameters available + for `begin_shape()` are `POINTS`, `LINES`, `TRIANGLES`, `TRIANGLE_FAN`, + `TRIANGLE_STRIP`, `QUADS`, and `QUAD_STRIP`. After calling the `begin_shape()` + function, a series of `Py5Graphics.vertex()` commands must follow. To stop + drawing the shape, call `Py5Graphics.end_shape()`. The `Py5Graphics.vertex()` + function with two parameters specifies a position in 2D and the + `Py5Graphics.vertex()` function with three parameters specifies a position in + 3D. Each shape will be outlined with the current stroke color and filled with + the fill color. - Transformations such as ``Py5Graphics.translate()``, ``Py5Graphics.rotate()``, - and ``Py5Graphics.scale()`` do not work within ``begin_shape()``. It is also not - possible to use other shapes, such as ``Py5Graphics.ellipse()`` or - ``Py5Graphics.rect()`` within ``begin_shape()``. + Transformations such as `Py5Graphics.translate()`, `Py5Graphics.rotate()`, and + `Py5Graphics.scale()` do not work within `begin_shape()`. It is also not + possible to use other shapes, such as `Py5Graphics.ellipse()` or + `Py5Graphics.rect()` within `begin_shape()`. - The ``P2D`` and ``P3D`` renderers allow ``Py5Graphics.stroke()`` and - ``Py5Graphics.fill()`` to be altered on a per-vertex basis, but the default - renderer does not. Settings such as ``Py5Graphics.stroke_weight()``, - ``Py5Graphics.stroke_cap()``, and ``Py5Graphics.stroke_join()`` cannot be - changed while inside a ``begin_shape()`` & ``Py5Graphics.end_shape()`` block - with any renderer. + The `P2D` and `P3D` renderers allow `Py5Graphics.stroke()` and + `Py5Graphics.fill()` to be altered on a per-vertex basis, but the default + renderer does not. Settings such as `Py5Graphics.stroke_weight()`, + `Py5Graphics.stroke_cap()`, and `Py5Graphics.stroke_join()` cannot be changed + while inside a `begin_shape()` & `Py5Graphics.end_shape()` block with any + renderer. This method can be used as a context manager to ensure that - ``Py5Graphics.end_shape()`` always gets called, as shown in the example. Use - ``Py5Graphics.begin_closed_shape()`` to create a context manager that will pass - the ``CLOSE`` parameter to ``end_shape()``, closing the shape. + `Py5Graphics.end_shape()` always gets called, as shown in the example. Use + `Py5Graphics.begin_closed_shape()` to create a context manager that will pass + the `CLOSE` parameter to `end_shape()`, closing the shape. - This method is the same as ``begin_shape()`` but linked to a ``Py5Graphics`` - object. To see more example code for how it can be used, see ``begin_shape()``. + This method is the same as `begin_shape()` but linked to a `Py5Graphics` object. + To see more example code for how it can be used, see `begin_shape()`. """ pass @overload def begin_shape(self, kind: int, /) -> None: - """Using the ``begin_shape()`` and ``Py5Graphics.end_shape()`` functions allow - creating more complex forms. + """Using the `begin_shape()` and `Py5Graphics.end_shape()` functions allow creating + more complex forms. Underlying Processing method: PGraphics.beginShape @@ -2119,46 +2138,46 @@ def begin_shape(self, kind: int, /) -> None: Notes ----- - Using the ``begin_shape()`` and ``Py5Graphics.end_shape()`` functions allow - creating more complex forms. ``begin_shape()`` begins recording vertices for a - shape and ``Py5Graphics.end_shape()`` stops recording. The value of the ``kind`` - parameter tells it which types of shapes to create from the provided vertices. - With no mode specified, the shape can be any irregular polygon. The parameters - available for ``begin_shape()`` are ``POINTS``, ``LINES``, ``TRIANGLES``, - ``TRIANGLE_FAN``, ``TRIANGLE_STRIP``, ``QUADS``, and ``QUAD_STRIP``. After - calling the ``begin_shape()`` function, a series of ``Py5Graphics.vertex()`` - commands must follow. To stop drawing the shape, call - ``Py5Graphics.end_shape()``. The ``Py5Graphics.vertex()`` function with two - parameters specifies a position in 2D and the ``Py5Graphics.vertex()`` function - with three parameters specifies a position in 3D. Each shape will be outlined - with the current stroke color and filled with the fill color. + Using the `begin_shape()` and `Py5Graphics.end_shape()` functions allow creating + more complex forms. `begin_shape()` begins recording vertices for a shape and + `Py5Graphics.end_shape()` stops recording. The value of the `kind` parameter + tells it which types of shapes to create from the provided vertices. With no + mode specified, the shape can be any irregular polygon. The parameters available + for `begin_shape()` are `POINTS`, `LINES`, `TRIANGLES`, `TRIANGLE_FAN`, + `TRIANGLE_STRIP`, `QUADS`, and `QUAD_STRIP`. After calling the `begin_shape()` + function, a series of `Py5Graphics.vertex()` commands must follow. To stop + drawing the shape, call `Py5Graphics.end_shape()`. The `Py5Graphics.vertex()` + function with two parameters specifies a position in 2D and the + `Py5Graphics.vertex()` function with three parameters specifies a position in + 3D. Each shape will be outlined with the current stroke color and filled with + the fill color. - Transformations such as ``Py5Graphics.translate()``, ``Py5Graphics.rotate()``, - and ``Py5Graphics.scale()`` do not work within ``begin_shape()``. It is also not - possible to use other shapes, such as ``Py5Graphics.ellipse()`` or - ``Py5Graphics.rect()`` within ``begin_shape()``. + Transformations such as `Py5Graphics.translate()`, `Py5Graphics.rotate()`, and + `Py5Graphics.scale()` do not work within `begin_shape()`. It is also not + possible to use other shapes, such as `Py5Graphics.ellipse()` or + `Py5Graphics.rect()` within `begin_shape()`. - The ``P2D`` and ``P3D`` renderers allow ``Py5Graphics.stroke()`` and - ``Py5Graphics.fill()`` to be altered on a per-vertex basis, but the default - renderer does not. Settings such as ``Py5Graphics.stroke_weight()``, - ``Py5Graphics.stroke_cap()``, and ``Py5Graphics.stroke_join()`` cannot be - changed while inside a ``begin_shape()`` & ``Py5Graphics.end_shape()`` block - with any renderer. + The `P2D` and `P3D` renderers allow `Py5Graphics.stroke()` and + `Py5Graphics.fill()` to be altered on a per-vertex basis, but the default + renderer does not. Settings such as `Py5Graphics.stroke_weight()`, + `Py5Graphics.stroke_cap()`, and `Py5Graphics.stroke_join()` cannot be changed + while inside a `begin_shape()` & `Py5Graphics.end_shape()` block with any + renderer. This method can be used as a context manager to ensure that - ``Py5Graphics.end_shape()`` always gets called, as shown in the example. Use - ``Py5Graphics.begin_closed_shape()`` to create a context manager that will pass - the ``CLOSE`` parameter to ``end_shape()``, closing the shape. + `Py5Graphics.end_shape()` always gets called, as shown in the example. Use + `Py5Graphics.begin_closed_shape()` to create a context manager that will pass + the `CLOSE` parameter to `end_shape()`, closing the shape. - This method is the same as ``begin_shape()`` but linked to a ``Py5Graphics`` - object. To see more example code for how it can be used, see ``begin_shape()``. + This method is the same as `begin_shape()` but linked to a `Py5Graphics` object. + To see more example code for how it can be used, see `begin_shape()`. """ pass @_context_wrapper('end_shape') def begin_shape(self, *args): - """Using the ``begin_shape()`` and ``Py5Graphics.end_shape()`` functions allow - creating more complex forms. + """Using the `begin_shape()` and `Py5Graphics.end_shape()` functions allow creating + more complex forms. Underlying Processing method: PGraphics.beginShape @@ -2179,39 +2198,39 @@ def begin_shape(self, *args): Notes ----- - Using the ``begin_shape()`` and ``Py5Graphics.end_shape()`` functions allow - creating more complex forms. ``begin_shape()`` begins recording vertices for a - shape and ``Py5Graphics.end_shape()`` stops recording. The value of the ``kind`` - parameter tells it which types of shapes to create from the provided vertices. - With no mode specified, the shape can be any irregular polygon. The parameters - available for ``begin_shape()`` are ``POINTS``, ``LINES``, ``TRIANGLES``, - ``TRIANGLE_FAN``, ``TRIANGLE_STRIP``, ``QUADS``, and ``QUAD_STRIP``. After - calling the ``begin_shape()`` function, a series of ``Py5Graphics.vertex()`` - commands must follow. To stop drawing the shape, call - ``Py5Graphics.end_shape()``. The ``Py5Graphics.vertex()`` function with two - parameters specifies a position in 2D and the ``Py5Graphics.vertex()`` function - with three parameters specifies a position in 3D. Each shape will be outlined - with the current stroke color and filled with the fill color. + Using the `begin_shape()` and `Py5Graphics.end_shape()` functions allow creating + more complex forms. `begin_shape()` begins recording vertices for a shape and + `Py5Graphics.end_shape()` stops recording. The value of the `kind` parameter + tells it which types of shapes to create from the provided vertices. With no + mode specified, the shape can be any irregular polygon. The parameters available + for `begin_shape()` are `POINTS`, `LINES`, `TRIANGLES`, `TRIANGLE_FAN`, + `TRIANGLE_STRIP`, `QUADS`, and `QUAD_STRIP`. After calling the `begin_shape()` + function, a series of `Py5Graphics.vertex()` commands must follow. To stop + drawing the shape, call `Py5Graphics.end_shape()`. The `Py5Graphics.vertex()` + function with two parameters specifies a position in 2D and the + `Py5Graphics.vertex()` function with three parameters specifies a position in + 3D. Each shape will be outlined with the current stroke color and filled with + the fill color. - Transformations such as ``Py5Graphics.translate()``, ``Py5Graphics.rotate()``, - and ``Py5Graphics.scale()`` do not work within ``begin_shape()``. It is also not - possible to use other shapes, such as ``Py5Graphics.ellipse()`` or - ``Py5Graphics.rect()`` within ``begin_shape()``. + Transformations such as `Py5Graphics.translate()`, `Py5Graphics.rotate()`, and + `Py5Graphics.scale()` do not work within `begin_shape()`. It is also not + possible to use other shapes, such as `Py5Graphics.ellipse()` or + `Py5Graphics.rect()` within `begin_shape()`. - The ``P2D`` and ``P3D`` renderers allow ``Py5Graphics.stroke()`` and - ``Py5Graphics.fill()`` to be altered on a per-vertex basis, but the default - renderer does not. Settings such as ``Py5Graphics.stroke_weight()``, - ``Py5Graphics.stroke_cap()``, and ``Py5Graphics.stroke_join()`` cannot be - changed while inside a ``begin_shape()`` & ``Py5Graphics.end_shape()`` block - with any renderer. + The `P2D` and `P3D` renderers allow `Py5Graphics.stroke()` and + `Py5Graphics.fill()` to be altered on a per-vertex basis, but the default + renderer does not. Settings such as `Py5Graphics.stroke_weight()`, + `Py5Graphics.stroke_cap()`, and `Py5Graphics.stroke_join()` cannot be changed + while inside a `begin_shape()` & `Py5Graphics.end_shape()` block with any + renderer. This method can be used as a context manager to ensure that - ``Py5Graphics.end_shape()`` always gets called, as shown in the example. Use - ``Py5Graphics.begin_closed_shape()`` to create a context manager that will pass - the ``CLOSE`` parameter to ``end_shape()``, closing the shape. + `Py5Graphics.end_shape()` always gets called, as shown in the example. Use + `Py5Graphics.begin_closed_shape()` to create a context manager that will pass + the `CLOSE` parameter to `end_shape()`, closing the shape. - This method is the same as ``begin_shape()`` but linked to a ``Py5Graphics`` - object. To see more example code for how it can be used, see ``begin_shape()``. + This method is the same as `begin_shape()` but linked to a `Py5Graphics` object. + To see more example code for how it can be used, see `begin_shape()`. """ return self._instance.beginShape(*args) @@ -2240,16 +2259,16 @@ def begin_closed_shape(self) -> None: This method is used to start a custom closed shape. This method should only be used as a context manager, as shown in the example. When used as a context - manager, this will ensure that ``Py5Graphics.end_shape()`` always gets called, - just like when using ``Py5Graphics.begin_shape()`` as a context manager. The - difference is that when exiting, the parameter ``CLOSE`` will be passed to - ``Py5Graphics.end_shape()``, connecting the last vertex to the first. This will + manager, this will ensure that `Py5Graphics.end_shape()` always gets called, + just like when using `Py5Graphics.begin_shape()` as a context manager. The + difference is that when exiting, the parameter `CLOSE` will be passed to + `Py5Graphics.end_shape()`, connecting the last vertex to the first. This will close the shape. If this method were to be used not as a context manager, it won't be able to close the shape by making the call to - ``Py5Graphics.end_shape()``. + `Py5Graphics.end_shape()`. - This method is the same as ``begin_closed_shape()`` but linked to a - ``Py5Graphics`` object. + This method is the same as `begin_closed_shape()` but linked to a `Py5Graphics` + object. """ pass @@ -2278,16 +2297,16 @@ def begin_closed_shape(self, kind: int, /) -> None: This method is used to start a custom closed shape. This method should only be used as a context manager, as shown in the example. When used as a context - manager, this will ensure that ``Py5Graphics.end_shape()`` always gets called, - just like when using ``Py5Graphics.begin_shape()`` as a context manager. The - difference is that when exiting, the parameter ``CLOSE`` will be passed to - ``Py5Graphics.end_shape()``, connecting the last vertex to the first. This will + manager, this will ensure that `Py5Graphics.end_shape()` always gets called, + just like when using `Py5Graphics.begin_shape()` as a context manager. The + difference is that when exiting, the parameter `CLOSE` will be passed to + `Py5Graphics.end_shape()`, connecting the last vertex to the first. This will close the shape. If this method were to be used not as a context manager, it won't be able to close the shape by making the call to - ``Py5Graphics.end_shape()``. + `Py5Graphics.end_shape()`. - This method is the same as ``begin_closed_shape()`` but linked to a - ``Py5Graphics`` object. + This method is the same as `begin_closed_shape()` but linked to a `Py5Graphics` + object. """ pass @@ -2316,23 +2335,23 @@ def begin_closed_shape(self, *args): This method is used to start a custom closed shape. This method should only be used as a context manager, as shown in the example. When used as a context - manager, this will ensure that ``Py5Graphics.end_shape()`` always gets called, - just like when using ``Py5Graphics.begin_shape()`` as a context manager. The - difference is that when exiting, the parameter ``CLOSE`` will be passed to - ``Py5Graphics.end_shape()``, connecting the last vertex to the first. This will + manager, this will ensure that `Py5Graphics.end_shape()` always gets called, + just like when using `Py5Graphics.begin_shape()` as a context manager. The + difference is that when exiting, the parameter `CLOSE` will be passed to + `Py5Graphics.end_shape()`, connecting the last vertex to the first. This will close the shape. If this method were to be used not as a context manager, it won't be able to close the shape by making the call to - ``Py5Graphics.end_shape()``. + `Py5Graphics.end_shape()`. - This method is the same as ``begin_closed_shape()`` but linked to a - ``Py5Graphics`` object. + This method is the same as `begin_closed_shape()` but linked to a `Py5Graphics` + object. """ return self._instance.beginShape(*args) @overload def bezier(self, x1: float, y1: float, x2: float, y2: float, x3: float, y3: float, x4: float, y4: float, /) -> None: - """Draws a Bezier curve on the ``Py5Graphics`` object. + """Draws a Bezier curve on the `Py5Graphics` object. Underlying Processing method: PGraphics.bezier @@ -2386,22 +2405,22 @@ def bezier(self, x1: float, y1: float, x2: float, y2: float, Notes ----- - Draws a Bezier curve on the ``Py5Graphics`` object. These curves are defined by - a series of anchor and control points. The first two parameters specify the - first anchor point and the last two parameters specify the other anchor point. - The middle parameters specify the control points which define the shape of the + Draws a Bezier curve on the `Py5Graphics` object. These curves are defined by a + series of anchor and control points. The first two parameters specify the first + anchor point and the last two parameters specify the other anchor point. The + middle parameters specify the control points which define the shape of the curve. Bezier curves were developed by French engineer Pierre Bezier. Using the - 3D version requires rendering with ``P3D``. + 3D version requires rendering with `P3D`. - This method is the same as ``bezier()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``bezier()``. + This method is the same as `bezier()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `bezier()`. """ pass @overload def bezier(self, x1: float, y1: float, z1: float, x2: float, y2: float, z2: float, x3: float, y3: float, z3: float, x4: float, y4: float, z4: float, /) -> None: - """Draws a Bezier curve on the ``Py5Graphics`` object. + """Draws a Bezier curve on the `Py5Graphics` object. Underlying Processing method: PGraphics.bezier @@ -2455,20 +2474,20 @@ def bezier(self, x1: float, y1: float, z1: float, x2: float, y2: float, z2: floa Notes ----- - Draws a Bezier curve on the ``Py5Graphics`` object. These curves are defined by - a series of anchor and control points. The first two parameters specify the - first anchor point and the last two parameters specify the other anchor point. - The middle parameters specify the control points which define the shape of the + Draws a Bezier curve on the `Py5Graphics` object. These curves are defined by a + series of anchor and control points. The first two parameters specify the first + anchor point and the last two parameters specify the other anchor point. The + middle parameters specify the control points which define the shape of the curve. Bezier curves were developed by French engineer Pierre Bezier. Using the - 3D version requires rendering with ``P3D``. + 3D version requires rendering with `P3D`. - This method is the same as ``bezier()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``bezier()``. + This method is the same as `bezier()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `bezier()`. """ pass def bezier(self, *args): - """Draws a Bezier curve on the ``Py5Graphics`` object. + """Draws a Bezier curve on the `Py5Graphics` object. Underlying Processing method: PGraphics.bezier @@ -2522,15 +2541,15 @@ def bezier(self, *args): Notes ----- - Draws a Bezier curve on the ``Py5Graphics`` object. These curves are defined by - a series of anchor and control points. The first two parameters specify the - first anchor point and the last two parameters specify the other anchor point. - The middle parameters specify the control points which define the shape of the + Draws a Bezier curve on the `Py5Graphics` object. These curves are defined by a + series of anchor and control points. The first two parameters specify the first + anchor point and the last two parameters specify the other anchor point. The + middle parameters specify the control points which define the shape of the curve. Bezier curves were developed by French engineer Pierre Bezier. Using the - 3D version requires rendering with ``P3D``. + 3D version requires rendering with `P3D`. - This method is the same as ``bezier()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``bezier()``. + This method is the same as `bezier()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `bezier()`. """ return self._instance.bezier(*args) @@ -2549,11 +2568,11 @@ def bezier_detail(self, detail: int, /) -> None: ----- Sets the resolution at which Beziers display. The default value is 20. This - function is only useful when using the ``P3D`` renderer; the default ``P2D`` + function is only useful when using the `P3D` renderer; the default `P2D` renderer does not use this information. - This method is the same as ``bezier_detail()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``bezier_detail()``. + This method is the same as `bezier_detail()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `bezier_detail()`. """ return self._instance.bezierDetail(detail) @@ -2589,8 +2608,8 @@ def bezier_point(self, a: float, b: float, c: float, points. This can be done once with the x coordinates and a second time with the y coordinates to get the location of a bezier curve at t. - This method is the same as ``bezier_point()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``bezier_point()``. + This method is the same as `bezier_point()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `bezier_point()`. """ return self._instance.bezierPoint(a, b, c, d, t) @@ -2624,8 +2643,8 @@ def bezier_tangent(self, a: float, b: float, c: float, Calculates the tangent of a point on a Bezier curve. There is a good definition of *tangent* on Wikipedia. - This method is the same as ``bezier_tangent()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``bezier_tangent()``. + This method is the same as `bezier_tangent()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `bezier_tangent()`. """ return self._instance.bezierTangent(a, b, c, d, t) @@ -2677,18 +2696,17 @@ def bezier_vertex(self, x2: float, y2: float, x3: float, Notes ----- - Specifies vertex coordinates for Bezier curves. Each call to ``bezier_vertex()`` + Specifies vertex coordinates for Bezier curves. Each call to `bezier_vertex()` defines the position of two control points and one anchor point of a Bezier - curve, adding a new segment to a line or shape. The first time - ``bezier_vertex()`` is used within a ``Py5Graphics.begin_shape()`` call, it must - be prefaced with a call to ``Py5Graphics.vertex()`` to set the first anchor - point. This function must be used between ``Py5Graphics.begin_shape()`` and - ``Py5Graphics.end_shape()`` and only when there is no ``MODE`` parameter - specified to ``Py5Graphics.begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + curve, adding a new segment to a line or shape. The first time `bezier_vertex()` + is used within a `Py5Graphics.begin_shape()` call, it must be prefaced with a + call to `Py5Graphics.vertex()` to set the first anchor point. This function must + be used between `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` and + only when there is no `MODE` parameter specified to `Py5Graphics.begin_shape()`. + Using the 3D version requires rendering with `P3D`. - This method is the same as ``bezier_vertex()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``bezier_vertex()``. + This method is the same as `bezier_vertex()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `bezier_vertex()`. """ pass @@ -2740,18 +2758,17 @@ def bezier_vertex(self, x2: float, y2: float, z2: float, x3: float, Notes ----- - Specifies vertex coordinates for Bezier curves. Each call to ``bezier_vertex()`` + Specifies vertex coordinates for Bezier curves. Each call to `bezier_vertex()` defines the position of two control points and one anchor point of a Bezier - curve, adding a new segment to a line or shape. The first time - ``bezier_vertex()`` is used within a ``Py5Graphics.begin_shape()`` call, it must - be prefaced with a call to ``Py5Graphics.vertex()`` to set the first anchor - point. This function must be used between ``Py5Graphics.begin_shape()`` and - ``Py5Graphics.end_shape()`` and only when there is no ``MODE`` parameter - specified to ``Py5Graphics.begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + curve, adding a new segment to a line or shape. The first time `bezier_vertex()` + is used within a `Py5Graphics.begin_shape()` call, it must be prefaced with a + call to `Py5Graphics.vertex()` to set the first anchor point. This function must + be used between `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` and + only when there is no `MODE` parameter specified to `Py5Graphics.begin_shape()`. + Using the 3D version requires rendering with `P3D`. - This method is the same as ``bezier_vertex()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``bezier_vertex()``. + This method is the same as `bezier_vertex()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `bezier_vertex()`. """ pass @@ -2801,18 +2818,17 @@ def bezier_vertex(self, *args): Notes ----- - Specifies vertex coordinates for Bezier curves. Each call to ``bezier_vertex()`` + Specifies vertex coordinates for Bezier curves. Each call to `bezier_vertex()` defines the position of two control points and one anchor point of a Bezier - curve, adding a new segment to a line or shape. The first time - ``bezier_vertex()`` is used within a ``Py5Graphics.begin_shape()`` call, it must - be prefaced with a call to ``Py5Graphics.vertex()`` to set the first anchor - point. This function must be used between ``Py5Graphics.begin_shape()`` and - ``Py5Graphics.end_shape()`` and only when there is no ``MODE`` parameter - specified to ``Py5Graphics.begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + curve, adding a new segment to a line or shape. The first time `bezier_vertex()` + is used within a `Py5Graphics.begin_shape()` call, it must be prefaced with a + call to `Py5Graphics.vertex()` to set the first anchor point. This function must + be used between `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` and + only when there is no `MODE` parameter specified to `Py5Graphics.begin_shape()`. + Using the 3D version requires rendering with `P3D`. - This method is the same as ``bezier_vertex()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``bezier_vertex()``. + This method is the same as `bezier_vertex()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `bezier_vertex()`. """ return self._instance.bezierVertex(*args) @@ -2872,11 +2888,11 @@ def blend(self, sx: int, sy: int, sw: int, sh: int, dx: int, full alpha channel support. There is a choice of the following modes to blend the source pixels (A) with the ones of pixels in the destination image (B): - * BLEND: linear interpolation of colors: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colors: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -2893,14 +2909,14 @@ def blend(self, sx: int, sy: int, sw: int, sh: int, dx: int, All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the Py5Graphics drawing surface is used as the - source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the Py5Graphics drawing surface is used as the source + image. - This function ignores ``Py5Graphics.image_mode()``. + This function ignores `Py5Graphics.image_mode()`. - This method is the same as ``blend()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``blend()``. + This method is the same as `blend()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `blend()`. """ pass @@ -2960,11 +2976,11 @@ def blend(self, src: Py5Image, sx: int, sy: int, sw: int, sh: int, full alpha channel support. There is a choice of the following modes to blend the source pixels (A) with the ones of pixels in the destination image (B): - * BLEND: linear interpolation of colors: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colors: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -2981,14 +2997,14 @@ def blend(self, src: Py5Image, sx: int, sy: int, sw: int, sh: int, All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the Py5Graphics drawing surface is used as the - source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the Py5Graphics drawing surface is used as the source + image. - This function ignores ``Py5Graphics.image_mode()``. + This function ignores `Py5Graphics.image_mode()`. - This method is the same as ``blend()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``blend()``. + This method is the same as `blend()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `blend()`. """ pass @@ -3046,11 +3062,11 @@ def blend(self, *args): full alpha channel support. There is a choice of the following modes to blend the source pixels (A) with the ones of pixels in the destination image (B): - * BLEND: linear interpolation of colors: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colors: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -3067,14 +3083,14 @@ def blend(self, *args): All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the Py5Graphics drawing surface is used as the - source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the Py5Graphics drawing surface is used as the source + image. - This function ignores ``Py5Graphics.image_mode()``. + This function ignores `Py5Graphics.image_mode()`. - This method is the same as ``blend()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``blend()``. + This method is the same as `blend()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `blend()`. """ return self._instance.blend(*args) @@ -3100,12 +3116,12 @@ def blend_mode(self, mode: int, /) -> None: channel of (A) and (B) independently. The red channel is compared with red, green with green, and blue with blue. - * BLEND: linear interpolation of colors: ``C = A*factor + B``. This is the + * BLEND: linear interpolation of colors: `C = A*factor + B`. This is the default. - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: multiply the colors, result will always be darker. @@ -3113,21 +3129,21 @@ def blend_mode(self, mode: int, /) -> None: * REPLACE: the pixels entirely replace the others and don't utilize alpha (transparency) values - We recommend using ``blend_mode()`` and not the previous ``Py5Graphics.blend()`` - function. However, unlike ``Py5Graphics.blend()``, the ``blend_mode()`` function - does not support the following: ``HARD_LIGHT``, ``SOFT_LIGHT``, ``OVERLAY``, - ``DODGE``, ``BURN``. On older hardware, the ``LIGHTEST``, ``DARKEST``, and - ``DIFFERENCE`` modes might not be available as well. + We recommend using `blend_mode()` and not the previous `Py5Graphics.blend()` + function. However, unlike `Py5Graphics.blend()`, the `blend_mode()` function + does not support the following: `HARD_LIGHT`, `SOFT_LIGHT`, `OVERLAY`, `DODGE`, + `BURN`. On older hardware, the `LIGHTEST`, `DARKEST`, and `DIFFERENCE` modes + might not be available as well. - This method is the same as ``blend_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``blend_mode()``. + This method is the same as `blend_mode()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `blend_mode()`. """ return self._instance.blendMode(mode) @_convert_hex_color() def blue(self, rgb: int, /) -> float: """Extracts the blue value from a color, scaled to match current - ``Py5Graphics.color_mode()``. + `Py5Graphics.color_mode()`. Underlying Processing method: PGraphics.blue @@ -3141,17 +3157,16 @@ def blue(self, rgb: int, /) -> float: ----- Extracts the blue value from a color, scaled to match current - ``Py5Graphics.color_mode()``. + `Py5Graphics.color_mode()`. - The ``blue()`` function is easy to use and understand, but it is slower than a - technique called bit masking. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``blue()`` but with greater speed by using a bit - mask to remove the other color components. For example, ``blue(c)`` and ``c & - 0xFF`` both extract the blue value from a color variable ``c`` but the later is - faster. + The `blue()` function is easy to use and understand, but it is slower than a + technique called bit masking. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `blue()` but with greater speed by using a bit mask + to remove the other color components. For example, `blue(c)` and `c & 0xFF` both + extract the blue value from a color variable `c` but the later is faster. - This method is the same as ``blue()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``blue()``. + This method is the same as `blue()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `blue()`. """ return self._instance.blue(rgb) @@ -3190,8 +3205,8 @@ def box(self, size: float, /) -> None: A box is an extruded rectangle. A box with equal dimensions on all sides is a cube. - This method is the same as ``box()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``box()``. + This method is the same as `box()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `box()`. """ pass @@ -3230,8 +3245,8 @@ def box(self, w: float, h: float, d: float, /) -> None: A box is an extruded rectangle. A box with equal dimensions on all sides is a cube. - This method is the same as ``box()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``box()``. + This method is the same as `box()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `box()`. """ pass @@ -3269,8 +3284,8 @@ def box(self, *args): A box is an extruded rectangle. A box with equal dimensions on all sides is a cube. - This method is the same as ``box()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``box()``. + This method is the same as `box()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `box()`. """ return self._instance.box(*args) @@ -3291,8 +3306,8 @@ def brightness(self, rgb: int, /) -> float: Extracts the brightness value from a color. - This method is the same as ``brightness()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``brightness()``. + This method is the same as `brightness()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `brightness()`. """ return self._instance.brightness(rgb) @@ -3349,13 +3364,13 @@ def camera(self) -> None: direction it is pointing (the center of the scene) allows the images to be seen from different angles. The version without any parameters sets the camera to the default position, pointing to the center of the Py5Graphics drawing surface with - the Y axis as up. The default values are ``camera(width//2.0, height//2.0, - (height//2.0) / tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)``. - This function is similar to ``glu_look_at()`` in OpenGL, but it first clears the + the Y axis as up. The default values are `camera(width//2.0, height//2.0, + (height//2.0) / tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)`. + This function is similar to `glu_look_at()` in OpenGL, but it first clears the current camera settings. - This method is the same as ``camera()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``camera()``. + This method is the same as `camera()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `camera()`. """ pass @@ -3423,13 +3438,13 @@ def camera( direction it is pointing (the center of the scene) allows the images to be seen from different angles. The version without any parameters sets the camera to the default position, pointing to the center of the Py5Graphics drawing surface with - the Y axis as up. The default values are ``camera(width//2.0, height//2.0, - (height//2.0) / tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)``. - This function is similar to ``glu_look_at()`` in OpenGL, but it first clears the + the Y axis as up. The default values are `camera(width//2.0, height//2.0, + (height//2.0) / tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)`. + This function is similar to `glu_look_at()` in OpenGL, but it first clears the current camera settings. - This method is the same as ``camera()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``camera()``. + This method is the same as `camera()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `camera()`. """ pass @@ -3485,13 +3500,13 @@ def camera(self, *args): direction it is pointing (the center of the scene) allows the images to be seen from different angles. The version without any parameters sets the camera to the default position, pointing to the center of the Py5Graphics drawing surface with - the Y axis as up. The default values are ``camera(width//2.0, height//2.0, - (height//2.0) / tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)``. - This function is similar to ``glu_look_at()`` in OpenGL, but it first clears the + the Y axis as up. The default values are `camera(width//2.0, height//2.0, + (height//2.0) / tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)`. + This function is similar to `glu_look_at()` in OpenGL, but it first clears the current camera settings. - This method is the same as ``camera()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``camera()``. + This method is the same as `camera()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `camera()`. """ return self._instance.camera(*args) @@ -3517,10 +3532,10 @@ def circle(self, x: float, y: float, extent: float, /) -> None: Draws a circle to the screen. By default, the first two parameters set the location of the center, and the third sets the shape's width and height. The - origin may be changed with the ``Py5Graphics.ellipse_mode()`` function. + origin may be changed with the `Py5Graphics.ellipse_mode()` function. - This method is the same as ``circle()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``circle()``. + This method is the same as `circle()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `circle()`. """ return self._instance.circle(x, y, extent) @@ -3533,9 +3548,9 @@ def clear(self) -> None: ----- Clears the pixels within a buffer. Unlike the main graphics context (the display - window), pixels in ``Py5Graphics`` objects created with ``create_graphics()`` - can be entirely or partially transparent. This function clears everything in a - ``Py5Graphics`` object to make all of the pixels 100% transparent. + window), pixels in `Py5Graphics` objects created with `create_graphics()` can be + entirely or partially transparent. This function clears everything in a + `Py5Graphics` object to make all of the pixels 100% transparent. """ return self._instance.clear() @@ -3563,17 +3578,17 @@ def clip(self, a: float, b: float, c: float, d: float, /) -> None: ----- Limits the rendering to the boundaries of a rectangle defined by the parameters. - The boundaries are drawn based on the state of the ``Py5Graphics.image_mode()`` - fuction, either ``CORNER``, ``CORNERS``, or ``CENTER``. + The boundaries are drawn based on the state of the `Py5Graphics.image_mode()` + fuction, either `CORNER`, `CORNERS`, or `CENTER`. - This method is the same as ``clip()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``clip()``. + This method is the same as `clip()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `clip()`. """ return self._instance.clip(a, b, c, d) @overload def color(self, gray: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PGraphics.color @@ -3635,28 +3650,28 @@ def color(self, gray: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``Py5Graphics.color_mode()``. The default mode is ``RGB`` values - from 0 to 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow - color (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `Py5Graphics.color_mode()`. The default mode is `RGB` values from 0 + to 255 and, therefore, `color(255, 204, 0)` will return a bright yellow color + (see the first example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. - Note that when using hexadecimal notation, it is not necessary to use - ``color()``, as in: ``c = 0x006699`` + Note that when using hexadecimal notation, it is not necessary to use `color()`, + as in: `c = 0x006699` - This method is the same as ``color()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``color()``. + This method is the same as `color()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `color()`. """ pass @overload def color(self, gray: float, alpha: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PGraphics.color @@ -3718,28 +3733,28 @@ def color(self, gray: float, alpha: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``Py5Graphics.color_mode()``. The default mode is ``RGB`` values - from 0 to 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow - color (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `Py5Graphics.color_mode()`. The default mode is `RGB` values from 0 + to 255 and, therefore, `color(255, 204, 0)` will return a bright yellow color + (see the first example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. - Note that when using hexadecimal notation, it is not necessary to use - ``color()``, as in: ``c = 0x006699`` + Note that when using hexadecimal notation, it is not necessary to use `color()`, + as in: `c = 0x006699` - This method is the same as ``color()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``color()``. + This method is the same as `color()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `color()`. """ pass @overload def color(self, v1: float, v2: float, v3: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PGraphics.color @@ -3801,28 +3816,28 @@ def color(self, v1: float, v2: float, v3: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``Py5Graphics.color_mode()``. The default mode is ``RGB`` values - from 0 to 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow - color (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `Py5Graphics.color_mode()`. The default mode is `RGB` values from 0 + to 255 and, therefore, `color(255, 204, 0)` will return a bright yellow color + (see the first example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. - Note that when using hexadecimal notation, it is not necessary to use - ``color()``, as in: ``c = 0x006699`` + Note that when using hexadecimal notation, it is not necessary to use `color()`, + as in: `c = 0x006699` - This method is the same as ``color()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``color()``. + This method is the same as `color()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `color()`. """ pass @overload def color(self, v1: float, v2: float, v3: float, a: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PGraphics.color @@ -3884,28 +3899,28 @@ def color(self, v1: float, v2: float, v3: float, a: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``Py5Graphics.color_mode()``. The default mode is ``RGB`` values - from 0 to 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow - color (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `Py5Graphics.color_mode()`. The default mode is `RGB` values from 0 + to 255 and, therefore, `color(255, 204, 0)` will return a bright yellow color + (see the first example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. - Note that when using hexadecimal notation, it is not necessary to use - ``color()``, as in: ``c = 0x006699`` + Note that when using hexadecimal notation, it is not necessary to use `color()`, + as in: `c = 0x006699` - This method is the same as ``color()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``color()``. + This method is the same as `color()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `color()`. """ pass @overload def color(self, c: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PGraphics.color @@ -3967,28 +3982,28 @@ def color(self, c: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``Py5Graphics.color_mode()``. The default mode is ``RGB`` values - from 0 to 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow - color (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `Py5Graphics.color_mode()`. The default mode is `RGB` values from 0 + to 255 and, therefore, `color(255, 204, 0)` will return a bright yellow color + (see the first example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. - Note that when using hexadecimal notation, it is not necessary to use - ``color()``, as in: ``c = 0x006699`` + Note that when using hexadecimal notation, it is not necessary to use `color()`, + as in: `c = 0x006699` - This method is the same as ``color()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``color()``. + This method is the same as `color()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `color()`. """ pass @overload def color(self, c: int, alpha: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PGraphics.color @@ -4050,28 +4065,28 @@ def color(self, c: int, alpha: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``Py5Graphics.color_mode()``. The default mode is ``RGB`` values - from 0 to 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow - color (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `Py5Graphics.color_mode()`. The default mode is `RGB` values from 0 + to 255 and, therefore, `color(255, 204, 0)` will return a bright yellow color + (see the first example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. - Note that when using hexadecimal notation, it is not necessary to use - ``color()``, as in: ``c = 0x006699`` + Note that when using hexadecimal notation, it is not necessary to use `color()`, + as in: `c = 0x006699` - This method is the same as ``color()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``color()``. + This method is the same as `color()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `color()`. """ pass @overload def color(self, c: int, alpha: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PGraphics.color @@ -4133,28 +4148,28 @@ def color(self, c: int, alpha: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``Py5Graphics.color_mode()``. The default mode is ``RGB`` values - from 0 to 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow - color (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `Py5Graphics.color_mode()`. The default mode is `RGB` values from 0 + to 255 and, therefore, `color(255, 204, 0)` will return a bright yellow color + (see the first example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. - Note that when using hexadecimal notation, it is not necessary to use - ``color()``, as in: ``c = 0x006699`` + Note that when using hexadecimal notation, it is not necessary to use `color()`, + as in: `c = 0x006699` - This method is the same as ``color()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``color()``. + This method is the same as `color()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `color()`. """ pass @overload def color(self, v1: int, v2: int, v3: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PGraphics.color @@ -4216,28 +4231,28 @@ def color(self, v1: int, v2: int, v3: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``Py5Graphics.color_mode()``. The default mode is ``RGB`` values - from 0 to 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow - color (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `Py5Graphics.color_mode()`. The default mode is `RGB` values from 0 + to 255 and, therefore, `color(255, 204, 0)` will return a bright yellow color + (see the first example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. - Note that when using hexadecimal notation, it is not necessary to use - ``color()``, as in: ``c = 0x006699`` + Note that when using hexadecimal notation, it is not necessary to use `color()`, + as in: `c = 0x006699` - This method is the same as ``color()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``color()``. + This method is the same as `color()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `color()`. """ pass @overload def color(self, v1: int, v2: int, v3: int, a: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PGraphics.color @@ -4299,28 +4314,28 @@ def color(self, v1: int, v2: int, v3: int, a: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``Py5Graphics.color_mode()``. The default mode is ``RGB`` values - from 0 to 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow - color (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `Py5Graphics.color_mode()`. The default mode is `RGB` values from 0 + to 255 and, therefore, `color(255, 204, 0)` will return a bright yellow color + (see the first example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. - Note that when using hexadecimal notation, it is not necessary to use - ``color()``, as in: ``c = 0x006699`` + Note that when using hexadecimal notation, it is not necessary to use `color()`, + as in: `c = 0x006699` - This method is the same as ``color()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``color()``. + This method is the same as `color()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `color()`. """ pass @_convert_hex_color() def color(self, *args): - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PGraphics.color @@ -4382,22 +4397,22 @@ def color(self, *args): Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``Py5Graphics.color_mode()``. The default mode is ``RGB`` values - from 0 to 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow - color (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `Py5Graphics.color_mode()`. The default mode is `RGB` values from 0 + to 255 and, therefore, `color(255, 204, 0)` will return a bright yellow color + (see the first example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. - Note that when using hexadecimal notation, it is not necessary to use - ``color()``, as in: ``c = 0x006699`` + Note that when using hexadecimal notation, it is not necessary to use `color()`, + as in: `c = 0x006699` - This method is the same as ``color()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``color()``. + This method is the same as `color()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `color()`. """ return self._instance.color(*args) @@ -4442,24 +4457,24 @@ def color_mode(self, mode: int, /) -> None: ----- Changes the way py5 interprets color data. By default, the parameters for - ``Py5Graphics.fill()``, ``Py5Graphics.stroke()``, ``Py5Graphics.background()``, - and ``Py5Graphics.color()`` are defined by values between 0 and 255 using the - ``RGB`` color model. The ``color_mode()`` function is used to change the - numerical range used for specifying colors and to switch color systems. For - example, calling ``color_mode(RGB, 1.0)`` will specify that values are specified - between 0 and 1. The limits for defining colors are altered by setting the - parameters ``max``, ``max1``, ``max2``, ``max3``, and ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `Py5Graphics.fill()`, `Py5Graphics.stroke()`, `Py5Graphics.background()`, and + `Py5Graphics.color()` are defined by values between 0 and 255 using the `RGB` + color model. The `color_mode()` function is used to change the numerical range + used for specifying colors and to switch color systems. For example, calling + `color_mode(RGB, 1.0)` will specify that values are specified between 0 and 1. + The limits for defining colors are altered by setting the parameters `max`, + `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. - This method is the same as ``color_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``color_mode()``. + This method is the same as `color_mode()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `color_mode()`. """ pass @@ -4504,24 +4519,24 @@ def color_mode(self, mode: int, max: float, /) -> None: ----- Changes the way py5 interprets color data. By default, the parameters for - ``Py5Graphics.fill()``, ``Py5Graphics.stroke()``, ``Py5Graphics.background()``, - and ``Py5Graphics.color()`` are defined by values between 0 and 255 using the - ``RGB`` color model. The ``color_mode()`` function is used to change the - numerical range used for specifying colors and to switch color systems. For - example, calling ``color_mode(RGB, 1.0)`` will specify that values are specified - between 0 and 1. The limits for defining colors are altered by setting the - parameters ``max``, ``max1``, ``max2``, ``max3``, and ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `Py5Graphics.fill()`, `Py5Graphics.stroke()`, `Py5Graphics.background()`, and + `Py5Graphics.color()` are defined by values between 0 and 255 using the `RGB` + color model. The `color_mode()` function is used to change the numerical range + used for specifying colors and to switch color systems. For example, calling + `color_mode(RGB, 1.0)` will specify that values are specified between 0 and 1. + The limits for defining colors are altered by setting the parameters `max`, + `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. - This method is the same as ``color_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``color_mode()``. + This method is the same as `color_mode()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `color_mode()`. """ pass @@ -4567,24 +4582,24 @@ def color_mode(self, mode: int, max1: float, ----- Changes the way py5 interprets color data. By default, the parameters for - ``Py5Graphics.fill()``, ``Py5Graphics.stroke()``, ``Py5Graphics.background()``, - and ``Py5Graphics.color()`` are defined by values between 0 and 255 using the - ``RGB`` color model. The ``color_mode()`` function is used to change the - numerical range used for specifying colors and to switch color systems. For - example, calling ``color_mode(RGB, 1.0)`` will specify that values are specified - between 0 and 1. The limits for defining colors are altered by setting the - parameters ``max``, ``max1``, ``max2``, ``max3``, and ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `Py5Graphics.fill()`, `Py5Graphics.stroke()`, `Py5Graphics.background()`, and + `Py5Graphics.color()` are defined by values between 0 and 255 using the `RGB` + color model. The `color_mode()` function is used to change the numerical range + used for specifying colors and to switch color systems. For example, calling + `color_mode(RGB, 1.0)` will specify that values are specified between 0 and 1. + The limits for defining colors are altered by setting the parameters `max`, + `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. - This method is the same as ``color_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``color_mode()``. + This method is the same as `color_mode()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `color_mode()`. """ pass @@ -4630,24 +4645,24 @@ def color_mode(self, mode: int, max1: float, max2: float, ----- Changes the way py5 interprets color data. By default, the parameters for - ``Py5Graphics.fill()``, ``Py5Graphics.stroke()``, ``Py5Graphics.background()``, - and ``Py5Graphics.color()`` are defined by values between 0 and 255 using the - ``RGB`` color model. The ``color_mode()`` function is used to change the - numerical range used for specifying colors and to switch color systems. For - example, calling ``color_mode(RGB, 1.0)`` will specify that values are specified - between 0 and 1. The limits for defining colors are altered by setting the - parameters ``max``, ``max1``, ``max2``, ``max3``, and ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `Py5Graphics.fill()`, `Py5Graphics.stroke()`, `Py5Graphics.background()`, and + `Py5Graphics.color()` are defined by values between 0 and 255 using the `RGB` + color model. The `color_mode()` function is used to change the numerical range + used for specifying colors and to switch color systems. For example, calling + `color_mode(RGB, 1.0)` will specify that values are specified between 0 and 1. + The limits for defining colors are altered by setting the parameters `max`, + `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. - This method is the same as ``color_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``color_mode()``. + This method is the same as `color_mode()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `color_mode()`. """ pass @@ -4691,32 +4706,32 @@ def color_mode(self, *args): ----- Changes the way py5 interprets color data. By default, the parameters for - ``Py5Graphics.fill()``, ``Py5Graphics.stroke()``, ``Py5Graphics.background()``, - and ``Py5Graphics.color()`` are defined by values between 0 and 255 using the - ``RGB`` color model. The ``color_mode()`` function is used to change the - numerical range used for specifying colors and to switch color systems. For - example, calling ``color_mode(RGB, 1.0)`` will specify that values are specified - between 0 and 1. The limits for defining colors are altered by setting the - parameters ``max``, ``max1``, ``max2``, ``max3``, and ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `Py5Graphics.fill()`, `Py5Graphics.stroke()`, `Py5Graphics.background()`, and + `Py5Graphics.color()` are defined by values between 0 and 255 using the `RGB` + color model. The `color_mode()` function is used to change the numerical range + used for specifying colors and to switch color systems. For example, calling + `color_mode(RGB, 1.0)` will specify that values are specified between 0 and 1. + The limits for defining colors are altered by setting the parameters `max`, + `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. - This method is the same as ``color_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``color_mode()``. + This method is the same as `color_mode()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `color_mode()`. """ return self._instance.colorMode(*args) @overload def copy(self) -> Py5Image: - """Copies a region of pixels from the ``Py5Graphics`` object to another area of the - canvas and copies a region of pixels from an image used as the ``src_img`` - parameter into the ``Py5Graphics`` object. + """Copies a region of pixels from the `Py5Graphics` object to another area of the + canvas and copies a region of pixels from an image used as the `src_img` + parameter into the `Py5Graphics` object. Underlying Processing method: PGraphics.copy @@ -4762,26 +4777,26 @@ def copy(self) -> Py5Image: Notes ----- - Copies a region of pixels from the ``Py5Graphics`` object to another area of the - canvas and copies a region of pixels from an image used as the ``src_img`` - parameter into the ``Py5Graphics`` object. If the source and destination regions + Copies a region of pixels from the `Py5Graphics` object to another area of the + canvas and copies a region of pixels from an image used as the `src_img` + parameter into the `Py5Graphics` object. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``Py5Graphics.image_mode()``. + This function ignores `Py5Graphics.image_mode()`. - This method is the same as ``copy()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``copy()``. + This method is the same as `copy()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `copy()`. """ pass @overload def copy(self, sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, /) -> None: - """Copies a region of pixels from the ``Py5Graphics`` object to another area of the - canvas and copies a region of pixels from an image used as the ``src_img`` - parameter into the ``Py5Graphics`` object. + """Copies a region of pixels from the `Py5Graphics` object to another area of the + canvas and copies a region of pixels from an image used as the `src_img` + parameter into the `Py5Graphics` object. Underlying Processing method: PGraphics.copy @@ -4827,26 +4842,26 @@ def copy(self, sx: int, sy: int, sw: int, sh: int, Notes ----- - Copies a region of pixels from the ``Py5Graphics`` object to another area of the - canvas and copies a region of pixels from an image used as the ``src_img`` - parameter into the ``Py5Graphics`` object. If the source and destination regions + Copies a region of pixels from the `Py5Graphics` object to another area of the + canvas and copies a region of pixels from an image used as the `src_img` + parameter into the `Py5Graphics` object. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``Py5Graphics.image_mode()``. + This function ignores `Py5Graphics.image_mode()`. - This method is the same as ``copy()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``copy()``. + This method is the same as `copy()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `copy()`. """ pass @overload def copy(self, src: Py5Image, sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, /) -> None: - """Copies a region of pixels from the ``Py5Graphics`` object to another area of the - canvas and copies a region of pixels from an image used as the ``src_img`` - parameter into the ``Py5Graphics`` object. + """Copies a region of pixels from the `Py5Graphics` object to another area of the + canvas and copies a region of pixels from an image used as the `src_img` + parameter into the `Py5Graphics` object. Underlying Processing method: PGraphics.copy @@ -4892,25 +4907,25 @@ def copy(self, src: Py5Image, sx: int, sy: int, sw: int, Notes ----- - Copies a region of pixels from the ``Py5Graphics`` object to another area of the - canvas and copies a region of pixels from an image used as the ``src_img`` - parameter into the ``Py5Graphics`` object. If the source and destination regions + Copies a region of pixels from the `Py5Graphics` object to another area of the + canvas and copies a region of pixels from an image used as the `src_img` + parameter into the `Py5Graphics` object. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``Py5Graphics.image_mode()``. + This function ignores `Py5Graphics.image_mode()`. - This method is the same as ``copy()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``copy()``. + This method is the same as `copy()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `copy()`. """ pass @_return_py5image def copy(self, *args): - """Copies a region of pixels from the ``Py5Graphics`` object to another area of the - canvas and copies a region of pixels from an image used as the ``src_img`` - parameter into the ``Py5Graphics`` object. + """Copies a region of pixels from the `Py5Graphics` object to another area of the + canvas and copies a region of pixels from an image used as the `src_img` + parameter into the `Py5Graphics` object. Underlying Processing method: PGraphics.copy @@ -4956,23 +4971,23 @@ def copy(self, *args): Notes ----- - Copies a region of pixels from the ``Py5Graphics`` object to another area of the - canvas and copies a region of pixels from an image used as the ``src_img`` - parameter into the ``Py5Graphics`` object. If the source and destination regions + Copies a region of pixels from the `Py5Graphics` object to another area of the + canvas and copies a region of pixels from an image used as the `src_img` + parameter into the `Py5Graphics` object. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``Py5Graphics.image_mode()``. + This function ignores `Py5Graphics.image_mode()`. - This method is the same as ``copy()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``copy()``. + This method is the same as `copy()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `copy()`. """ return self._instance.copy(*args) @overload def create_shape(self) -> Py5Shape: - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PGraphics.createShape @@ -5000,39 +5015,39 @@ def create_shape(self) -> Py5Shape: Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``Py5Graphics.shape()`` function. The basic way - to use the function defines new primitive shapes. One of the following - parameters are used as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, - ``TRIANGLE``, ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for - each of these different shapes are the same as their corresponding functions: - ``Py5Graphics.ellipse()``, ``Py5Graphics.rect()``, ``Py5Graphics.arc()``, - ``Py5Graphics.triangle()``, ``Py5Graphics.sphere()``, ``Py5Graphics.box()``, - ``Py5Graphics.quad()``, and ``Py5Graphics.line()``. + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `Py5Graphics.shape()` function. The basic way to use + the function defines new primitive shapes. One of the following parameters are + used as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, + `BOX`, `QUAD`, or `LINE`. The parameters for each of these different shapes are + the same as their corresponding functions: `Py5Graphics.ellipse()`, + `Py5Graphics.rect()`, `Py5Graphics.arc()`, `Py5Graphics.triangle()`, + `Py5Graphics.sphere()`, `Py5Graphics.box()`, `Py5Graphics.quad()`, and + `Py5Graphics.line()`. - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``Py5Graphics.begin_shape()`` and - ``Py5Graphics.end_shape()`` methods. See reference for - ``Py5Graphics.begin_shape()`` for all of its options. + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `Py5Graphics.begin_shape()` and + `Py5Graphics.end_shape()` methods. See reference for `Py5Graphics.begin_shape()` + for all of its options. - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. - This method is the same as ``create_shape()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``create_shape()``. + This method is the same as `create_shape()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `create_shape()`. """ pass @overload def create_shape(self, type: int, /) -> Py5Shape: - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PGraphics.createShape @@ -5060,39 +5075,39 @@ def create_shape(self, type: int, /) -> Py5Shape: Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``Py5Graphics.shape()`` function. The basic way - to use the function defines new primitive shapes. One of the following - parameters are used as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, - ``TRIANGLE``, ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for - each of these different shapes are the same as their corresponding functions: - ``Py5Graphics.ellipse()``, ``Py5Graphics.rect()``, ``Py5Graphics.arc()``, - ``Py5Graphics.triangle()``, ``Py5Graphics.sphere()``, ``Py5Graphics.box()``, - ``Py5Graphics.quad()``, and ``Py5Graphics.line()``. + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `Py5Graphics.shape()` function. The basic way to use + the function defines new primitive shapes. One of the following parameters are + used as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, + `BOX`, `QUAD`, or `LINE`. The parameters for each of these different shapes are + the same as their corresponding functions: `Py5Graphics.ellipse()`, + `Py5Graphics.rect()`, `Py5Graphics.arc()`, `Py5Graphics.triangle()`, + `Py5Graphics.sphere()`, `Py5Graphics.box()`, `Py5Graphics.quad()`, and + `Py5Graphics.line()`. - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``Py5Graphics.begin_shape()`` and - ``Py5Graphics.end_shape()`` methods. See reference for - ``Py5Graphics.begin_shape()`` for all of its options. + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `Py5Graphics.begin_shape()` and + `Py5Graphics.end_shape()` methods. See reference for `Py5Graphics.begin_shape()` + for all of its options. - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. - This method is the same as ``create_shape()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``create_shape()``. + This method is the same as `create_shape()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `create_shape()`. """ pass @overload def create_shape(self, kind: int, /, *p: float) -> Py5Shape: - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PGraphics.createShape @@ -5120,39 +5135,39 @@ def create_shape(self, kind: int, /, *p: float) -> Py5Shape: Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``Py5Graphics.shape()`` function. The basic way - to use the function defines new primitive shapes. One of the following - parameters are used as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, - ``TRIANGLE``, ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for - each of these different shapes are the same as their corresponding functions: - ``Py5Graphics.ellipse()``, ``Py5Graphics.rect()``, ``Py5Graphics.arc()``, - ``Py5Graphics.triangle()``, ``Py5Graphics.sphere()``, ``Py5Graphics.box()``, - ``Py5Graphics.quad()``, and ``Py5Graphics.line()``. + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `Py5Graphics.shape()` function. The basic way to use + the function defines new primitive shapes. One of the following parameters are + used as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, + `BOX`, `QUAD`, or `LINE`. The parameters for each of these different shapes are + the same as their corresponding functions: `Py5Graphics.ellipse()`, + `Py5Graphics.rect()`, `Py5Graphics.arc()`, `Py5Graphics.triangle()`, + `Py5Graphics.sphere()`, `Py5Graphics.box()`, `Py5Graphics.quad()`, and + `Py5Graphics.line()`. - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``Py5Graphics.begin_shape()`` and - ``Py5Graphics.end_shape()`` methods. See reference for - ``Py5Graphics.begin_shape()`` for all of its options. + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `Py5Graphics.begin_shape()` and + `Py5Graphics.end_shape()` methods. See reference for `Py5Graphics.begin_shape()` + for all of its options. - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. - This method is the same as ``create_shape()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``create_shape()``. + This method is the same as `create_shape()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `create_shape()`. """ pass @_return_py5shape def create_shape(self, *args): - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PGraphics.createShape @@ -5180,40 +5195,40 @@ def create_shape(self, *args): Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``Py5Graphics.shape()`` function. The basic way - to use the function defines new primitive shapes. One of the following - parameters are used as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, - ``TRIANGLE``, ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for - each of these different shapes are the same as their corresponding functions: - ``Py5Graphics.ellipse()``, ``Py5Graphics.rect()``, ``Py5Graphics.arc()``, - ``Py5Graphics.triangle()``, ``Py5Graphics.sphere()``, ``Py5Graphics.box()``, - ``Py5Graphics.quad()``, and ``Py5Graphics.line()``. + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `Py5Graphics.shape()` function. The basic way to use + the function defines new primitive shapes. One of the following parameters are + used as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, + `BOX`, `QUAD`, or `LINE`. The parameters for each of these different shapes are + the same as their corresponding functions: `Py5Graphics.ellipse()`, + `Py5Graphics.rect()`, `Py5Graphics.arc()`, `Py5Graphics.triangle()`, + `Py5Graphics.sphere()`, `Py5Graphics.box()`, `Py5Graphics.quad()`, and + `Py5Graphics.line()`. - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``Py5Graphics.begin_shape()`` and - ``Py5Graphics.end_shape()`` methods. See reference for - ``Py5Graphics.begin_shape()`` for all of its options. + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `Py5Graphics.begin_shape()` and + `Py5Graphics.end_shape()` methods. See reference for `Py5Graphics.begin_shape()` + for all of its options. - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. - This method is the same as ``create_shape()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``create_shape()``. + This method is the same as `create_shape()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `create_shape()`. """ return self._instance.createShape(*args) @overload def curve(self, x1: float, y1: float, x2: float, y2: float, x3: float, y3: float, x4: float, y4: float, /) -> None: - """Draws a curved line on the ``Py5Graphics`` object. + """Draws a curved line on the `Py5Graphics` object. Underlying Processing method: PGraphics.curve @@ -5267,25 +5282,24 @@ def curve(self, x1: float, y1: float, x2: float, y2: float, Notes ----- - Draws a curved line on the ``Py5Graphics`` object. The first and second - parameters specify the beginning control point and the last two parameters - specify the ending control point. The middle parameters specify the start and - stop of the curve. Longer curves can be created by putting a series of - ``curve()`` functions together or using ``Py5Graphics.curve_vertex()``. An - additional function called ``Py5Graphics.curve_tightness()`` provides control - for the visual quality of the curve. The ``curve()`` function is an - implementation of Catmull-Rom splines. Using the 3D version requires rendering - with ``P3D``. + Draws a curved line on the `Py5Graphics` object. The first and second parameters + specify the beginning control point and the last two parameters specify the + ending control point. The middle parameters specify the start and stop of the + curve. Longer curves can be created by putting a series of `curve()` functions + together or using `Py5Graphics.curve_vertex()`. An additional function called + `Py5Graphics.curve_tightness()` provides control for the visual quality of the + curve. The `curve()` function is an implementation of Catmull-Rom splines. Using + the 3D version requires rendering with `P3D`. - This method is the same as ``curve()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``curve()``. + This method is the same as `curve()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `curve()`. """ pass @overload def curve(self, x1: float, y1: float, z1: float, x2: float, y2: float, z2: float, x3: float, y3: float, z3: float, x4: float, y4: float, z4: float, /) -> None: - """Draws a curved line on the ``Py5Graphics`` object. + """Draws a curved line on the `Py5Graphics` object. Underlying Processing method: PGraphics.curve @@ -5339,23 +5353,22 @@ def curve(self, x1: float, y1: float, z1: float, x2: float, y2: float, z2: float Notes ----- - Draws a curved line on the ``Py5Graphics`` object. The first and second - parameters specify the beginning control point and the last two parameters - specify the ending control point. The middle parameters specify the start and - stop of the curve. Longer curves can be created by putting a series of - ``curve()`` functions together or using ``Py5Graphics.curve_vertex()``. An - additional function called ``Py5Graphics.curve_tightness()`` provides control - for the visual quality of the curve. The ``curve()`` function is an - implementation of Catmull-Rom splines. Using the 3D version requires rendering - with ``P3D``. + Draws a curved line on the `Py5Graphics` object. The first and second parameters + specify the beginning control point and the last two parameters specify the + ending control point. The middle parameters specify the start and stop of the + curve. Longer curves can be created by putting a series of `curve()` functions + together or using `Py5Graphics.curve_vertex()`. An additional function called + `Py5Graphics.curve_tightness()` provides control for the visual quality of the + curve. The `curve()` function is an implementation of Catmull-Rom splines. Using + the 3D version requires rendering with `P3D`. - This method is the same as ``curve()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``curve()``. + This method is the same as `curve()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `curve()`. """ pass def curve(self, *args): - """Draws a curved line on the ``Py5Graphics`` object. + """Draws a curved line on the `Py5Graphics` object. Underlying Processing method: PGraphics.curve @@ -5409,18 +5422,17 @@ def curve(self, *args): Notes ----- - Draws a curved line on the ``Py5Graphics`` object. The first and second - parameters specify the beginning control point and the last two parameters - specify the ending control point. The middle parameters specify the start and - stop of the curve. Longer curves can be created by putting a series of - ``curve()`` functions together or using ``Py5Graphics.curve_vertex()``. An - additional function called ``Py5Graphics.curve_tightness()`` provides control - for the visual quality of the curve. The ``curve()`` function is an - implementation of Catmull-Rom splines. Using the 3D version requires rendering - with ``P3D``. + Draws a curved line on the `Py5Graphics` object. The first and second parameters + specify the beginning control point and the last two parameters specify the + ending control point. The middle parameters specify the start and stop of the + curve. Longer curves can be created by putting a series of `curve()` functions + together or using `Py5Graphics.curve_vertex()`. An additional function called + `Py5Graphics.curve_tightness()` provides control for the visual quality of the + curve. The `curve()` function is an implementation of Catmull-Rom splines. Using + the 3D version requires rendering with `P3D`. - This method is the same as ``curve()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``curve()``. + This method is the same as `curve()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `curve()`. """ return self._instance.curve(*args) @@ -5439,17 +5451,17 @@ def curve_detail(self, detail: int, /) -> None: ----- Sets the resolution at which curves display. The default value is 20. This - function is only useful when using the ``P3D`` renderer as the default ``P2D`` + function is only useful when using the `P3D` renderer as the default `P2D` renderer does not use this information. - This method is the same as ``curve_detail()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``curve_detail()``. + This method is the same as `curve_detail()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `curve_detail()`. """ return self._instance.curveDetail(detail) def curve_point(self, a: float, b: float, c: float, d: float, t: float, /) -> float: - """Evaluates the curve at point ``t`` for points ``a``, ``b``, ``c``, ``d``. + """Evaluates the curve at point `t` for points `a`, `b`, `c`, `d`. Underlying Processing method: PGraphics.curvePoint @@ -5474,15 +5486,14 @@ def curve_point(self, a: float, b: float, c: float, Notes ----- - Evaluates the curve at point ``t`` for points ``a``, ``b``, ``c``, ``d``. The - parameter ``t`` may range from 0 (the start of the curve) and 1 (the end of the - curve). ``a`` and ``d`` are the control points, and ``b`` and ``c`` are points - on the curve. As seen in the example, this can be used once with the ``x`` - coordinates and a second time with the ``y`` coordinates to get the location of - a curve at ``t``. + Evaluates the curve at point `t` for points `a`, `b`, `c`, `d`. The parameter + `t` may range from 0 (the start of the curve) and 1 (the end of the curve). `a` + and `d` are the control points, and `b` and `c` are points on the curve. As seen + in the example, this can be used once with the `x` coordinates and a second time + with the `y` coordinates to get the location of a curve at `t`. - This method is the same as ``curve_point()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``curve_point()``. + This method is the same as `curve_point()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `curve_point()`. """ return self._instance.curvePoint(a, b, c, d, t) @@ -5516,14 +5527,14 @@ def curve_tangent(self, a: float, b: float, c: float, Calculates the tangent of a point on a curve. There's a good definition of *tangent* on Wikipedia. - This method is the same as ``curve_tangent()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``curve_tangent()``. + This method is the same as `curve_tangent()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `curve_tangent()`. """ return self._instance.curveTangent(a, b, c, d, t) def curve_tightness(self, tightness: float, /) -> None: - """Modifies the quality of forms created with ``Py5Graphics.curve()`` and - ``Py5Graphics.curve_vertex()``. + """Modifies the quality of forms created with `Py5Graphics.curve()` and + `Py5Graphics.curve_vertex()`. Underlying Processing method: PGraphics.curveTightness @@ -5536,16 +5547,16 @@ def curve_tightness(self, tightness: float, /) -> None: Notes ----- - Modifies the quality of forms created with ``Py5Graphics.curve()`` and - ``Py5Graphics.curve_vertex()``. The parameter ``tightness`` determines how the - curve fits to the vertex points. The value 0.0 is the default value for - ``tightness`` (this value defines the curves to be Catmull-Rom splines) and the - value 1.0 connects all the points with straight lines. Values within the range - -5.0 and 5.0 will deform the curves but will leave them recognizable and as - values increase in magnitude, they will continue to deform. + Modifies the quality of forms created with `Py5Graphics.curve()` and + `Py5Graphics.curve_vertex()`. The parameter `tightness` determines how the curve + fits to the vertex points. The value 0.0 is the default value for `tightness` + (this value defines the curves to be Catmull-Rom splines) and the value 1.0 + connects all the points with straight lines. Values within the range -5.0 and + 5.0 will deform the curves but will leave them recognizable and as values + increase in magnitude, they will continue to deform. - This method is the same as ``curve_tightness()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``curve_tightness()``. + This method is the same as `curve_tightness()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `curve_tightness()`. """ return self._instance.curveTightness(tightness) @@ -5579,17 +5590,17 @@ def curve_vertex(self, x: float, y: float, /) -> None: ----- Specifies vertex coordinates for curves. This method may only be used between - ``Py5Graphics.begin_shape()`` and ``Py5Graphics.end_shape()`` and only when - there is no ``MODE`` parameter specified to ``Py5Graphics.begin_shape()``. The - first and last points in a series of ``curve_vertex()`` lines will be used to - guide the beginning and end of the curve. A minimum of four points is required - to draw a tiny curve between the second and third points. Adding a fifth point - with ``curve_vertex()`` will draw the curve between the second, third, and - fourth points. The ``curve_vertex()`` method is an implementation of Catmull-Rom - splines. Using the 3D version requires rendering with ``P3D``. + `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` and only when there is + no `MODE` parameter specified to `Py5Graphics.begin_shape()`. The first and last + points in a series of `curve_vertex()` lines will be used to guide the beginning + and end of the curve. A minimum of four points is required to draw a tiny curve + between the second and third points. Adding a fifth point with `curve_vertex()` + will draw the curve between the second, third, and fourth points. The + `curve_vertex()` method is an implementation of Catmull-Rom splines. Using the + 3D version requires rendering with `P3D`. - This method is the same as ``curve_vertex()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``curve_vertex()``. + This method is the same as `curve_vertex()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `curve_vertex()`. """ pass @@ -5623,17 +5634,17 @@ def curve_vertex(self, x: float, y: float, z: float, /) -> None: ----- Specifies vertex coordinates for curves. This method may only be used between - ``Py5Graphics.begin_shape()`` and ``Py5Graphics.end_shape()`` and only when - there is no ``MODE`` parameter specified to ``Py5Graphics.begin_shape()``. The - first and last points in a series of ``curve_vertex()`` lines will be used to - guide the beginning and end of the curve. A minimum of four points is required - to draw a tiny curve between the second and third points. Adding a fifth point - with ``curve_vertex()`` will draw the curve between the second, third, and - fourth points. The ``curve_vertex()`` method is an implementation of Catmull-Rom - splines. Using the 3D version requires rendering with ``P3D``. + `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` and only when there is + no `MODE` parameter specified to `Py5Graphics.begin_shape()`. The first and last + points in a series of `curve_vertex()` lines will be used to guide the beginning + and end of the curve. A minimum of four points is required to draw a tiny curve + between the second and third points. Adding a fifth point with `curve_vertex()` + will draw the curve between the second, third, and fourth points. The + `curve_vertex()` method is an implementation of Catmull-Rom splines. Using the + 3D version requires rendering with `P3D`. - This method is the same as ``curve_vertex()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``curve_vertex()``. + This method is the same as `curve_vertex()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `curve_vertex()`. """ pass @@ -5666,17 +5677,17 @@ def curve_vertex(self, *args): ----- Specifies vertex coordinates for curves. This method may only be used between - ``Py5Graphics.begin_shape()`` and ``Py5Graphics.end_shape()`` and only when - there is no ``MODE`` parameter specified to ``Py5Graphics.begin_shape()``. The - first and last points in a series of ``curve_vertex()`` lines will be used to - guide the beginning and end of the curve. A minimum of four points is required - to draw a tiny curve between the second and third points. Adding a fifth point - with ``curve_vertex()`` will draw the curve between the second, third, and - fourth points. The ``curve_vertex()`` method is an implementation of Catmull-Rom - splines. Using the 3D version requires rendering with ``P3D``. - - This method is the same as ``curve_vertex()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``curve_vertex()``. + `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` and only when there is + no `MODE` parameter specified to `Py5Graphics.begin_shape()`. The first and last + points in a series of `curve_vertex()` lines will be used to guide the beginning + and end of the curve. A minimum of four points is required to draw a tiny curve + between the second and third points. Adding a fifth point with `curve_vertex()` + will draw the curve between the second, third, and fourth points. The + `curve_vertex()` method is an implementation of Catmull-Rom splines. Using the + 3D version requires rendering with `P3D`. + + This method is the same as `curve_vertex()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `curve_vertex()`. """ return self._instance.curveVertex(*args) @@ -5713,17 +5724,16 @@ def directional_light(self, v1: float, v2: float, v3: float, Adds a directional light. Directional light comes from one direction: it is stronger when hitting a surface squarely, and weaker if it hits at a gentle angle. After hitting a surface, directional light scatters in all directions. - Lights need to be included in the ``draw()`` to remain persistent in a looping - program. Placing them in the ``setup()`` of a looping program will cause them to - only have an effect the first time through the loop. The ``v1``, ``v2``, and - ``v3`` parameters are interpreted as either ``RGB`` or ``HSB`` values, depending - on the current color mode. The ``nx``, ``ny``, and ``nz`` parameters specify the - direction the light is facing. For example, setting ``ny`` to -1 will cause the - geometry to be lit from below (since the light would be facing directly upward). - - This method is the same as ``directional_light()`` but linked to a - ``Py5Graphics`` object. To see example code for how it can be used, see - ``directional_light()``. + Lights need to be included in the `draw()` to remain persistent in a looping + program. Placing them in the `setup()` of a looping program will cause them to + only have an effect the first time through the loop. The `v1`, `v2`, and `v3` + parameters are interpreted as either `RGB` or `HSB` values, depending on the + current color mode. The `nx`, `ny`, and `nz` parameters specify the direction + the light is facing. For example, setting `ny` to -1 will cause the geometry to + be lit from below (since the light would be facing directly upward). + + This method is the same as `directional_light()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `directional_light()`. """ return self._instance.directionalLight(v1, v2, v3, nx, ny, nz) @@ -5753,16 +5763,16 @@ def ellipse(self, a: float, b: float, c: float, d: float, /) -> None: Draws an ellipse (oval) to the screen. An ellipse with equal width and height is a circle. By default, the first two parameters set the location, and the third and fourth parameters set the shape's width and height. The origin may be - changed with the ``Py5Graphics.ellipse_mode()`` function. + changed with the `Py5Graphics.ellipse_mode()` function. - This method is the same as ``ellipse()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``ellipse()``. + This method is the same as `ellipse()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `ellipse()`. """ return self._instance.ellipse(a, b, c, d) def ellipse_mode(self, mode: int, /) -> None: """Modifies the location from which ellipses are drawn by changing the way in which - parameters given to ``Py5Graphics.ellipse()`` are intepreted. + parameters given to `Py5Graphics.ellipse()` are intepreted. Underlying Processing method: PGraphics.ellipseMode @@ -5776,30 +5786,29 @@ def ellipse_mode(self, mode: int, /) -> None: ----- Modifies the location from which ellipses are drawn by changing the way in which - parameters given to ``Py5Graphics.ellipse()`` are intepreted. + parameters given to `Py5Graphics.ellipse()` are intepreted. - The default mode is ``ellipse_mode(CENTER)``, which interprets the first two - parameters of ``Py5Graphics.ellipse()`` as the shape's center point, while the + The default mode is `ellipse_mode(CENTER)`, which interprets the first two + parameters of `Py5Graphics.ellipse()` as the shape's center point, while the third and fourth parameters are its width and height. - ``ellipse_mode(RADIUS)`` also uses the first two parameters of - ``Py5Graphics.ellipse()`` as the shape's center point, but uses the third and + `ellipse_mode(RADIUS)` also uses the first two parameters of + `Py5Graphics.ellipse()` as the shape's center point, but uses the third and fourth parameters to specify half of the shapes's width and height. - ``ellipse_mode(CORNER)`` interprets the first two parameters of - ``Py5Graphics.ellipse()`` as the upper-left corner of the shape, while the third + `ellipse_mode(CORNER)` interprets the first two parameters of + `Py5Graphics.ellipse()` as the upper-left corner of the shape, while the third and fourth parameters are its width and height. - ``ellipse_mode(CORNERS)`` interprets the first two parameters of - ``Py5Graphics.ellipse()`` as the location of one corner of the ellipse's - bounding box, and the third and fourth parameters as the location of the - opposite corner. + `ellipse_mode(CORNERS)` interprets the first two parameters of + `Py5Graphics.ellipse()` as the location of one corner of the ellipse's bounding + box, and the third and fourth parameters as the location of the opposite corner. The parameter must be written in ALL CAPS because Python is a case-sensitive language. - This method is the same as ``ellipse_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``ellipse_mode()``. + This method is the same as `ellipse_mode()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `ellipse_mode()`. """ return self._instance.ellipseMode(mode) @@ -5841,12 +5850,12 @@ def emissive(self, gray: float, /) -> None: ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``Py5Graphics.ambient()``, - ``Py5Graphics.specular()``, and ``Py5Graphics.shininess()`` to set the material + screen. Use in combination with `Py5Graphics.ambient()`, + `Py5Graphics.specular()`, and `Py5Graphics.shininess()` to set the material properties of shapes. - This method is the same as ``emissive()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``emissive()``. + This method is the same as `emissive()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `emissive()`. """ pass @@ -5888,12 +5897,12 @@ def emissive(self, v1: float, v2: float, v3: float, /) -> None: ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``Py5Graphics.ambient()``, - ``Py5Graphics.specular()``, and ``Py5Graphics.shininess()`` to set the material + screen. Use in combination with `Py5Graphics.ambient()`, + `Py5Graphics.specular()`, and `Py5Graphics.shininess()` to set the material properties of shapes. - This method is the same as ``emissive()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``emissive()``. + This method is the same as `emissive()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `emissive()`. """ pass @@ -5935,12 +5944,12 @@ def emissive(self, rgb: int, /) -> None: ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``Py5Graphics.ambient()``, - ``Py5Graphics.specular()``, and ``Py5Graphics.shininess()`` to set the material + screen. Use in combination with `Py5Graphics.ambient()`, + `Py5Graphics.specular()`, and `Py5Graphics.shininess()` to set the material properties of shapes. - This method is the same as ``emissive()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``emissive()``. + This method is the same as `emissive()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `emissive()`. """ pass @@ -5982,17 +5991,17 @@ def emissive(self, *args): ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``Py5Graphics.ambient()``, - ``Py5Graphics.specular()``, and ``Py5Graphics.shininess()`` to set the material + screen. Use in combination with `Py5Graphics.ambient()`, + `Py5Graphics.specular()`, and `Py5Graphics.shininess()` to set the material properties of shapes. - This method is the same as ``emissive()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``emissive()``. + This method is the same as `emissive()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `emissive()`. """ return self._instance.emissive(*args) def end_camera(self) -> None: - """The ``Py5Graphics.begin_camera()`` and ``end_camera()`` methods enable advanced + """The `Py5Graphics.begin_camera()` and `end_camera()` methods enable advanced customization of the camera space. Underlying Processing method: PGraphics.endCamera @@ -6000,17 +6009,17 @@ def end_camera(self) -> None: Notes ----- - The ``Py5Graphics.begin_camera()`` and ``end_camera()`` methods enable advanced + The `Py5Graphics.begin_camera()` and `end_camera()` methods enable advanced customization of the camera space. Please see the reference for - ``Py5Graphics.begin_camera()`` for a description of how the methods are used. + `Py5Graphics.begin_camera()` for a description of how the methods are used. - This method is the same as ``end_camera()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``end_camera()``. + This method is the same as `end_camera()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `end_camera()`. """ return self._instance.endCamera() def end_contour(self) -> None: - """Use the ``Py5Graphics.begin_contour()`` and ``end_contour()`` methods to create + """Use the `Py5Graphics.begin_contour()` and `end_contour()` methods to create negative shapes within shapes such as the center of the letter 'O'. Underlying Processing method: PGraphics.endContour @@ -6018,28 +6027,28 @@ def end_contour(self) -> None: Notes ----- - Use the ``Py5Graphics.begin_contour()`` and ``end_contour()`` methods to create + Use the `Py5Graphics.begin_contour()` and `end_contour()` methods to create negative shapes within shapes such as the center of the letter 'O'. The - ``Py5Graphics.begin_contour()`` method begins recording vertices for the shape - and ``end_contour()`` stops recording. The vertices that define a negative shape - must "wind" in the opposite direction from the exterior shape. First draw - vertices for the exterior shape in clockwise order, then for internal shapes, - draw vertices counterclockwise. - - These methods can only be used within a ``Py5Graphics.begin_shape()`` & - ``Py5Graphics.end_shape()`` pair and transformations such as - ``Py5Graphics.translate()``, ``Py5Graphics.rotate()``, and - ``Py5Graphics.scale()`` do not work within a ``Py5Graphics.begin_contour()`` & - ``end_contour()`` pair. It is also not possible to use other shapes, such as - ``Py5Graphics.ellipse()`` or ``Py5Graphics.rect()`` within. - - This method is the same as ``end_contour()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``end_contour()``. + `Py5Graphics.begin_contour()` method begins recording vertices for the shape and + `end_contour()` stops recording. The vertices that define a negative shape must + "wind" in the opposite direction from the exterior shape. First draw vertices + for the exterior shape in clockwise order, then for internal shapes, draw + vertices counterclockwise. + + These methods can only be used within a `Py5Graphics.begin_shape()` & + `Py5Graphics.end_shape()` pair and transformations such as + `Py5Graphics.translate()`, `Py5Graphics.rotate()`, and `Py5Graphics.scale()` do + not work within a `Py5Graphics.begin_contour()` & `end_contour()` pair. It is + also not possible to use other shapes, such as `Py5Graphics.ellipse()` or + `Py5Graphics.rect()` within. + + This method is the same as `end_contour()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `end_contour()`. """ return self._instance.endContour() def end_draw(self) -> None: - """Finalizes the rendering of a ``Py5Graphics`` object so that it can be shown on + """Finalizes the rendering of a `Py5Graphics` object so that it can be shown on screen. Underlying Processing method: PGraphics.endDraw @@ -6047,31 +6056,31 @@ def end_draw(self) -> None: Notes ----- - Finalizes the rendering of a ``Py5Graphics`` object so that it can be shown on + Finalizes the rendering of a `Py5Graphics` object so that it can be shown on screen. """ return self._instance.endDraw() def end_raw(self) -> None: - """Complement to ``Py5Graphics.begin_raw()``; they must always be used together. + """Complement to `Py5Graphics.begin_raw()`; they must always be used together. Underlying Processing method: PGraphics.endRaw Notes ----- - Complement to ``Py5Graphics.begin_raw()``; they must always be used together. - See the ``Py5Graphics.begin_raw()`` reference for details. + Complement to `Py5Graphics.begin_raw()`; they must always be used together. See + the `Py5Graphics.begin_raw()` reference for details. - This method is the same as ``end_raw()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``end_raw()``. + This method is the same as `end_raw()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `end_raw()`. """ return self._instance.endRaw() @overload def end_shape(self) -> None: - """The ``end_shape()`` function is the companion to ``Py5Graphics.begin_shape()`` - and may only be called after ``Py5Graphics.begin_shape()``. + """The `end_shape()` function is the companion to `Py5Graphics.begin_shape()` and + may only be called after `Py5Graphics.begin_shape()`. Underlying Processing method: PGraphics.endShape @@ -6092,22 +6101,22 @@ def end_shape(self) -> None: Notes ----- - The ``end_shape()`` function is the companion to ``Py5Graphics.begin_shape()`` - and may only be called after ``Py5Graphics.begin_shape()``. When ``end_shape()`` - is called, all of image data defined since the previous call to - ``Py5Graphics.begin_shape()`` is written into the image buffer. The constant - ``CLOSE`` as the value for the ``MODE`` parameter to close the shape (to connect - the beginning and the end). + The `end_shape()` function is the companion to `Py5Graphics.begin_shape()` and + may only be called after `Py5Graphics.begin_shape()`. When `end_shape()` is + called, all of image data defined since the previous call to + `Py5Graphics.begin_shape()` is written into the image buffer. The constant + `CLOSE` as the value for the `MODE` parameter to close the shape (to connect the + beginning and the end). - This method is the same as ``end_shape()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``end_shape()``. + This method is the same as `end_shape()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `end_shape()`. """ pass @overload def end_shape(self, mode: int, /) -> None: - """The ``end_shape()`` function is the companion to ``Py5Graphics.begin_shape()`` - and may only be called after ``Py5Graphics.begin_shape()``. + """The `end_shape()` function is the companion to `Py5Graphics.begin_shape()` and + may only be called after `Py5Graphics.begin_shape()`. Underlying Processing method: PGraphics.endShape @@ -6128,21 +6137,21 @@ def end_shape(self, mode: int, /) -> None: Notes ----- - The ``end_shape()`` function is the companion to ``Py5Graphics.begin_shape()`` - and may only be called after ``Py5Graphics.begin_shape()``. When ``end_shape()`` - is called, all of image data defined since the previous call to - ``Py5Graphics.begin_shape()`` is written into the image buffer. The constant - ``CLOSE`` as the value for the ``MODE`` parameter to close the shape (to connect - the beginning and the end). + The `end_shape()` function is the companion to `Py5Graphics.begin_shape()` and + may only be called after `Py5Graphics.begin_shape()`. When `end_shape()` is + called, all of image data defined since the previous call to + `Py5Graphics.begin_shape()` is written into the image buffer. The constant + `CLOSE` as the value for the `MODE` parameter to close the shape (to connect the + beginning and the end). - This method is the same as ``end_shape()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``end_shape()``. + This method is the same as `end_shape()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `end_shape()`. """ pass def end_shape(self, *args): - """The ``end_shape()`` function is the companion to ``Py5Graphics.begin_shape()`` - and may only be called after ``Py5Graphics.begin_shape()``. + """The `end_shape()` function is the companion to `Py5Graphics.begin_shape()` and + may only be called after `Py5Graphics.begin_shape()`. Underlying Processing method: PGraphics.endShape @@ -6163,15 +6172,15 @@ def end_shape(self, *args): Notes ----- - The ``end_shape()`` function is the companion to ``Py5Graphics.begin_shape()`` - and may only be called after ``Py5Graphics.begin_shape()``. When ``end_shape()`` - is called, all of image data defined since the previous call to - ``Py5Graphics.begin_shape()`` is written into the image buffer. The constant - ``CLOSE`` as the value for the ``MODE`` parameter to close the shape (to connect - the beginning and the end). + The `end_shape()` function is the companion to `Py5Graphics.begin_shape()` and + may only be called after `Py5Graphics.begin_shape()`. When `end_shape()` is + called, all of image data defined since the previous call to + `Py5Graphics.begin_shape()` is written into the image buffer. The constant + `CLOSE` as the value for the `MODE` parameter to close the shape (to connect the + beginning and the end). - This method is the same as ``end_shape()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``end_shape()``. + This method is the same as `end_shape()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `end_shape()`. """ return self._instance.endShape(*args) @@ -6217,35 +6226,35 @@ def fill(self, gray: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``Py5Graphics.color_mode()``. The default color space is ``RGB``, with each - value in the range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current + `Py5Graphics.color_mode()`. The default color space is `RGB`, with each value in + the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``Py5Graphics.tint()``. + To change the color of an image or a texture, use `Py5Graphics.tint()`. - This method is the same as ``fill()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``fill()``. + This method is the same as `fill()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `fill()`. """ pass @@ -6291,35 +6300,35 @@ def fill(self, gray: float, alpha: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``Py5Graphics.color_mode()``. The default color space is ``RGB``, with each - value in the range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current + `Py5Graphics.color_mode()`. The default color space is `RGB`, with each value in + the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``Py5Graphics.tint()``. + To change the color of an image or a texture, use `Py5Graphics.tint()`. - This method is the same as ``fill()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``fill()``. + This method is the same as `fill()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `fill()`. """ pass @@ -6365,35 +6374,35 @@ def fill(self, v1: float, v2: float, v3: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``Py5Graphics.color_mode()``. The default color space is ``RGB``, with each - value in the range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current + `Py5Graphics.color_mode()`. The default color space is `RGB`, with each value in + the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``Py5Graphics.tint()``. + To change the color of an image or a texture, use `Py5Graphics.tint()`. - This method is the same as ``fill()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``fill()``. + This method is the same as `fill()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `fill()`. """ pass @@ -6439,35 +6448,35 @@ def fill(self, v1: float, v2: float, v3: float, alpha: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``Py5Graphics.color_mode()``. The default color space is ``RGB``, with each - value in the range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current + `Py5Graphics.color_mode()`. The default color space is `RGB`, with each value in + the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``Py5Graphics.tint()``. + To change the color of an image or a texture, use `Py5Graphics.tint()`. - This method is the same as ``fill()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``fill()``. + This method is the same as `fill()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `fill()`. """ pass @@ -6513,35 +6522,35 @@ def fill(self, rgb: int, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``Py5Graphics.color_mode()``. The default color space is ``RGB``, with each - value in the range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current + `Py5Graphics.color_mode()`. The default color space is `RGB`, with each value in + the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``Py5Graphics.tint()``. + To change the color of an image or a texture, use `Py5Graphics.tint()`. - This method is the same as ``fill()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``fill()``. + This method is the same as `fill()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `fill()`. """ pass @@ -6587,35 +6596,35 @@ def fill(self, rgb: int, alpha: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``Py5Graphics.color_mode()``. The default color space is ``RGB``, with each - value in the range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current + `Py5Graphics.color_mode()`. The default color space is `RGB`, with each value in + the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``Py5Graphics.tint()``. + To change the color of an image or a texture, use `Py5Graphics.tint()`. - This method is the same as ``fill()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``fill()``. + This method is the same as `fill()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `fill()`. """ pass @@ -6661,35 +6670,35 @@ def fill(self, *args): Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``Py5Graphics.color_mode()``. The default color space is ``RGB``, with each - value in the range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current + `Py5Graphics.color_mode()`. The default color space is `RGB`, with each value in + the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``Py5Graphics.tint()``. + To change the color of an image or a texture, use `Py5Graphics.tint()`. - This method is the same as ``fill()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``fill()``. + This method is the same as `fill()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `fill()`. """ return self._instance.fill(*args) @@ -6725,8 +6734,8 @@ def apply_filter(self, kind: int, /) -> None: ----- Filters the Py5Graphics drawing surface using a preset filter or with a custom - shader. Using a shader with ``apply_filter()`` is much faster than without. - Shaders require the ``P2D`` or ``P3D`` renderer in ``size()``. + shader. Using a shader with `apply_filter()` is much faster than without. + Shaders require the `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -6746,8 +6755,8 @@ def apply_filter(self, kind: int, /) -> None: * ERODE: Reduces the light areas. No parameter is used. * DILATE: Increases the light areas. No parameter is used. - This method is the same as ``apply_filter()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``apply_filter()``. + This method is the same as `apply_filter()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `apply_filter()`. """ pass @@ -6783,8 +6792,8 @@ def apply_filter(self, kind: int, param: float, /) -> None: ----- Filters the Py5Graphics drawing surface using a preset filter or with a custom - shader. Using a shader with ``apply_filter()`` is much faster than without. - Shaders require the ``P2D`` or ``P3D`` renderer in ``size()``. + shader. Using a shader with `apply_filter()` is much faster than without. + Shaders require the `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -6804,8 +6813,8 @@ def apply_filter(self, kind: int, param: float, /) -> None: * ERODE: Reduces the light areas. No parameter is used. * DILATE: Increases the light areas. No parameter is used. - This method is the same as ``apply_filter()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``apply_filter()``. + This method is the same as `apply_filter()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `apply_filter()`. """ pass @@ -6841,8 +6850,8 @@ def apply_filter(self, shader: Py5Shader, /) -> None: ----- Filters the Py5Graphics drawing surface using a preset filter or with a custom - shader. Using a shader with ``apply_filter()`` is much faster than without. - Shaders require the ``P2D`` or ``P3D`` renderer in ``size()``. + shader. Using a shader with `apply_filter()` is much faster than without. + Shaders require the `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -6862,8 +6871,8 @@ def apply_filter(self, shader: Py5Shader, /) -> None: * ERODE: Reduces the light areas. No parameter is used. * DILATE: Increases the light areas. No parameter is used. - This method is the same as ``apply_filter()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``apply_filter()``. + This method is the same as `apply_filter()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `apply_filter()`. """ pass @@ -6898,8 +6907,8 @@ def apply_filter(self, *args): ----- Filters the Py5Graphics drawing surface using a preset filter or with a custom - shader. Using a shader with ``apply_filter()`` is much faster than without. - Shaders require the ``P2D`` or ``P3D`` renderer in ``size()``. + shader. Using a shader with `apply_filter()` is much faster than without. + Shaders require the `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -6919,8 +6928,8 @@ def apply_filter(self, *args): * ERODE: Reduces the light areas. No parameter is used. * DILATE: Increases the light areas. No parameter is used. - This method is the same as ``apply_filter()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``apply_filter()``. + This method is the same as `apply_filter()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `apply_filter()`. """ return self._instance.filter(*args) @@ -6936,7 +6945,7 @@ def flush(self) -> None: absolutely nothing. There are not a lot of good reasons to use this method, but if you need it, it is available for your use. - This method is the same as ``flush()`` but linked to a ``Py5Graphics`` object. + This method is the same as `flush()` but linked to a `Py5Graphics` object. """ return self._instance.flush() @@ -6980,7 +6989,7 @@ def frustum(self, left: float, right: float, bottom: float, Setting the frustum has the effect of changing the *perspective* with which the scene is rendered. This can be achieved more simply in many cases by using - ``Py5Graphics.perspective()``. + `Py5Graphics.perspective()`. Note that the near value must be greater than zero (as the point of the frustum "pyramid" cannot converge "behind" the viewer). Similarly, the far value must @@ -6990,14 +6999,14 @@ def frustum(self, left: float, right: float, bottom: float, Works like glFrustum, except it wipes out the current perspective matrix rather than multiplying itself with it. - This method is the same as ``frustum()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``frustum()``. + This method is the same as `frustum()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `frustum()`. """ return self._instance.frustum(left, right, bottom, top, near, far) @overload - def get(self) -> Py5Image: - """Reads the color of any pixel or grabs a section of an ``Py5Graphics`` object + def get_pixels(self) -> Py5Image: + """Reads the color of any pixel or grabs a section of an `Py5Graphics` object canvas. Underlying Processing method: PGraphics.get @@ -7007,9 +7016,9 @@ def get(self) -> Py5Image: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -7029,39 +7038,39 @@ def get(self) -> Py5Image: Notes ----- - Reads the color of any pixel or grabs a section of an ``Py5Graphics`` object + Reads the color of any pixel or grabs a section of an `Py5Graphics` object canvas. If no parameters are specified, the entire canvas is returned. Use the - ``x`` and ``y`` parameters to get the value of one pixel. Get a section of the - Py5Graphics drawing surface by specifying additional ``w`` and ``h`` parameters. - When getting an image, the ``x`` and ``y`` parameters define the coordinates for - the upper-left corner of the returned image, regardless of the current - ``Py5Graphics.image_mode()``. + `x` and `y` parameters to get the value of one pixel. Get a section of the + Py5Graphics drawing surface by specifying additional `w` and `h` parameters. + When getting an image, the `x` and `y` parameters define the coordinates for the + upper-left corner of the returned image, regardless of the current + `Py5Graphics.image_mode()`. - If the pixel requested is outside of the ``Py5Graphics`` object canvas, black is + If the pixel requested is outside of the `Py5Graphics` object canvas, black is returned. The numbers returned are scaled according to the current color ranges, - but only ``RGB`` values are returned by this function. For example, even though - you may have drawn a shape with ``color_mode(HSB)``, the numbers returned will - be in ``RGB`` format. + but only `RGB` values are returned by this function. For example, even though + you may have drawn a shape with `color_mode(HSB)`, the numbers returned will be + in `RGB` format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``Py5Graphics.pixels[]`` or - ``Py5Graphics.np_pixels[]``. The equivalent statement to ``get(x, y)`` using - ``Py5Graphics.pixels[]`` is ``pixels[y*width+x]``. Using - ``Py5Graphics.np_pixels[]`` it is ``np_pixels[y, x]``. See the reference for - ``Py5Graphics.pixels[]`` and ``Py5Graphics.np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `Py5Graphics.pixels[]` or + `Py5Graphics.np_pixels[]`. The equivalent statement to `get_pixels(x, y)` using + `Py5Graphics.pixels[]` is `pixels[y*width+x]`. Using `Py5Graphics.np_pixels[]` + it is `np_pixels[y, x]`. See the reference for `Py5Graphics.pixels[]` and + `Py5Graphics.np_pixels[]` for more information. - This method is the same as ``get()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``get()``. + This method is the same as `get_pixels()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `get_pixels()`. """ pass @overload - def get(self, x: int, y: int, /) -> int: - """Reads the color of any pixel or grabs a section of an ``Py5Graphics`` object + def get_pixels(self, x: int, y: int, /) -> int: + """Reads the color of any pixel or grabs a section of an `Py5Graphics` object canvas. Underlying Processing method: PGraphics.get @@ -7071,9 +7080,9 @@ def get(self, x: int, y: int, /) -> int: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -7093,39 +7102,39 @@ def get(self, x: int, y: int, /) -> int: Notes ----- - Reads the color of any pixel or grabs a section of an ``Py5Graphics`` object + Reads the color of any pixel or grabs a section of an `Py5Graphics` object canvas. If no parameters are specified, the entire canvas is returned. Use the - ``x`` and ``y`` parameters to get the value of one pixel. Get a section of the - Py5Graphics drawing surface by specifying additional ``w`` and ``h`` parameters. - When getting an image, the ``x`` and ``y`` parameters define the coordinates for - the upper-left corner of the returned image, regardless of the current - ``Py5Graphics.image_mode()``. + `x` and `y` parameters to get the value of one pixel. Get a section of the + Py5Graphics drawing surface by specifying additional `w` and `h` parameters. + When getting an image, the `x` and `y` parameters define the coordinates for the + upper-left corner of the returned image, regardless of the current + `Py5Graphics.image_mode()`. - If the pixel requested is outside of the ``Py5Graphics`` object canvas, black is + If the pixel requested is outside of the `Py5Graphics` object canvas, black is returned. The numbers returned are scaled according to the current color ranges, - but only ``RGB`` values are returned by this function. For example, even though - you may have drawn a shape with ``color_mode(HSB)``, the numbers returned will - be in ``RGB`` format. + but only `RGB` values are returned by this function. For example, even though + you may have drawn a shape with `color_mode(HSB)`, the numbers returned will be + in `RGB` format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``Py5Graphics.pixels[]`` or - ``Py5Graphics.np_pixels[]``. The equivalent statement to ``get(x, y)`` using - ``Py5Graphics.pixels[]`` is ``pixels[y*width+x]``. Using - ``Py5Graphics.np_pixels[]`` it is ``np_pixels[y, x]``. See the reference for - ``Py5Graphics.pixels[]`` and ``Py5Graphics.np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `Py5Graphics.pixels[]` or + `Py5Graphics.np_pixels[]`. The equivalent statement to `get_pixels(x, y)` using + `Py5Graphics.pixels[]` is `pixels[y*width+x]`. Using `Py5Graphics.np_pixels[]` + it is `np_pixels[y, x]`. See the reference for `Py5Graphics.pixels[]` and + `Py5Graphics.np_pixels[]` for more information. - This method is the same as ``get()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``get()``. + This method is the same as `get_pixels()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `get_pixels()`. """ pass @overload - def get(self, x: int, y: int, w: int, h: int, /) -> Py5Image: - """Reads the color of any pixel or grabs a section of an ``Py5Graphics`` object + def get_pixels(self, x: int, y: int, w: int, h: int, /) -> Py5Image: + """Reads the color of any pixel or grabs a section of an `Py5Graphics` object canvas. Underlying Processing method: PGraphics.get @@ -7135,9 +7144,9 @@ def get(self, x: int, y: int, w: int, h: int, /) -> Py5Image: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -7157,39 +7166,39 @@ def get(self, x: int, y: int, w: int, h: int, /) -> Py5Image: Notes ----- - Reads the color of any pixel or grabs a section of an ``Py5Graphics`` object + Reads the color of any pixel or grabs a section of an `Py5Graphics` object canvas. If no parameters are specified, the entire canvas is returned. Use the - ``x`` and ``y`` parameters to get the value of one pixel. Get a section of the - Py5Graphics drawing surface by specifying additional ``w`` and ``h`` parameters. - When getting an image, the ``x`` and ``y`` parameters define the coordinates for - the upper-left corner of the returned image, regardless of the current - ``Py5Graphics.image_mode()``. + `x` and `y` parameters to get the value of one pixel. Get a section of the + Py5Graphics drawing surface by specifying additional `w` and `h` parameters. + When getting an image, the `x` and `y` parameters define the coordinates for the + upper-left corner of the returned image, regardless of the current + `Py5Graphics.image_mode()`. - If the pixel requested is outside of the ``Py5Graphics`` object canvas, black is + If the pixel requested is outside of the `Py5Graphics` object canvas, black is returned. The numbers returned are scaled according to the current color ranges, - but only ``RGB`` values are returned by this function. For example, even though - you may have drawn a shape with ``color_mode(HSB)``, the numbers returned will - be in ``RGB`` format. + but only `RGB` values are returned by this function. For example, even though + you may have drawn a shape with `color_mode(HSB)`, the numbers returned will be + in `RGB` format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``Py5Graphics.pixels[]`` or - ``Py5Graphics.np_pixels[]``. The equivalent statement to ``get(x, y)`` using - ``Py5Graphics.pixels[]`` is ``pixels[y*width+x]``. Using - ``Py5Graphics.np_pixels[]`` it is ``np_pixels[y, x]``. See the reference for - ``Py5Graphics.pixels[]`` and ``Py5Graphics.np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `Py5Graphics.pixels[]` or + `Py5Graphics.np_pixels[]`. The equivalent statement to `get_pixels(x, y)` using + `Py5Graphics.pixels[]` is `pixels[y*width+x]`. Using `Py5Graphics.np_pixels[]` + it is `np_pixels[y, x]`. See the reference for `Py5Graphics.pixels[]` and + `Py5Graphics.np_pixels[]` for more information. - This method is the same as ``get()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``get()``. + This method is the same as `get_pixels()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `get_pixels()`. """ pass @_return_py5image - def get(self, *args): - """Reads the color of any pixel or grabs a section of an ``Py5Graphics`` object + def get_pixels(self, *args): + """Reads the color of any pixel or grabs a section of an `Py5Graphics` object canvas. Underlying Processing method: PGraphics.get @@ -7199,9 +7208,9 @@ def get(self, *args): You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -7221,33 +7230,33 @@ def get(self, *args): Notes ----- - Reads the color of any pixel or grabs a section of an ``Py5Graphics`` object + Reads the color of any pixel or grabs a section of an `Py5Graphics` object canvas. If no parameters are specified, the entire canvas is returned. Use the - ``x`` and ``y`` parameters to get the value of one pixel. Get a section of the - Py5Graphics drawing surface by specifying additional ``w`` and ``h`` parameters. - When getting an image, the ``x`` and ``y`` parameters define the coordinates for - the upper-left corner of the returned image, regardless of the current - ``Py5Graphics.image_mode()``. + `x` and `y` parameters to get the value of one pixel. Get a section of the + Py5Graphics drawing surface by specifying additional `w` and `h` parameters. + When getting an image, the `x` and `y` parameters define the coordinates for the + upper-left corner of the returned image, regardless of the current + `Py5Graphics.image_mode()`. - If the pixel requested is outside of the ``Py5Graphics`` object canvas, black is + If the pixel requested is outside of the `Py5Graphics` object canvas, black is returned. The numbers returned are scaled according to the current color ranges, - but only ``RGB`` values are returned by this function. For example, even though - you may have drawn a shape with ``color_mode(HSB)``, the numbers returned will - be in ``RGB`` format. + but only `RGB` values are returned by this function. For example, even though + you may have drawn a shape with `color_mode(HSB)`, the numbers returned will be + in `RGB` format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``Py5Graphics.pixels[]`` or - ``Py5Graphics.np_pixels[]``. The equivalent statement to ``get(x, y)`` using - ``Py5Graphics.pixels[]`` is ``pixels[y*width+x]``. Using - ``Py5Graphics.np_pixels[]`` it is ``np_pixels[y, x]``. See the reference for - ``Py5Graphics.pixels[]`` and ``Py5Graphics.np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `Py5Graphics.pixels[]` or + `Py5Graphics.np_pixels[]`. The equivalent statement to `get_pixels(x, y)` using + `Py5Graphics.pixels[]` is `pixels[y*width+x]`. Using `Py5Graphics.np_pixels[]` + it is `np_pixels[y, x]`. See the reference for `Py5Graphics.pixels[]` and + `Py5Graphics.np_pixels[]` for more information. - This method is the same as ``get()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``get()``. + This method is the same as `get_pixels()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `get_pixels()`. """ return self._instance.get(*args) @@ -7274,11 +7283,11 @@ def get_matrix(self) -> npt.NDArray[np.floating]: Notes ----- - Get the current matrix as a numpy array. Use the ``target`` parameter to put the + Get the current matrix as a numpy array. Use the `target` parameter to put the matrix data in a properly sized and typed numpy array. - This method is the same as ``get_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``get_matrix()``. + This method is the same as `get_matrix()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `get_matrix()`. """ pass @@ -7306,11 +7315,11 @@ def get_matrix( Notes ----- - Get the current matrix as a numpy array. Use the ``target`` parameter to put the + Get the current matrix as a numpy array. Use the `target` parameter to put the matrix data in a properly sized and typed numpy array. - This method is the same as ``get_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``get_matrix()``. + This method is the same as `get_matrix()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `get_matrix()`. """ pass @@ -7337,18 +7346,18 @@ def get_matrix(self, *args): Notes ----- - Get the current matrix as a numpy array. Use the ``target`` parameter to put the + Get the current matrix as a numpy array. Use the `target` parameter to put the matrix data in a properly sized and typed numpy array. - This method is the same as ``get_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``get_matrix()``. + This method is the same as `get_matrix()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `get_matrix()`. """ return self._instance.getMatrix(*args) @_convert_hex_color() def green(self, rgb: int, /) -> float: """Extracts the green value from a color, scaled to match current - ``Py5Graphics.color_mode()``. + `Py5Graphics.color_mode()`. Underlying Processing method: PGraphics.green @@ -7362,17 +7371,17 @@ def green(self, rgb: int, /) -> float: ----- Extracts the green value from a color, scaled to match current - ``Py5Graphics.color_mode()``. + `Py5Graphics.color_mode()`. - The ``green()`` function is easy to use and understand, but it is slower than a - technique called bit shifting. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``green()`` but with greater speed by using the - right shift operator (``>>``) with a bit mask. For example, ``green(c)`` and ``c - >> 8 & 0xFF`` both extract the green value from a color variable ``c`` but the - later is faster. + The `green()` function is easy to use and understand, but it is slower than a + technique called bit shifting. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `green()` but with greater speed by using the right + shift operator (`>>`) with a bit mask. For example, `green(c)` and `c >> 8 & + 0xFF` both extract the green value from a color variable `c` but the later is + faster. - This method is the same as ``green()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``green()``. + This method is the same as `green()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `green()`. """ return self._instance.green(rgb) @@ -7395,74 +7404,73 @@ def hint(self, which: int, /) -> None: graphics are drawn. In the course of developing Processing, the developers had to make hard decisions about tradeoffs between performance and visual quality. They put significant effort into determining what makes most sense for the - largest number of users, and then use functions like ``hint()`` to allow people - to tune the settings for their particular Sketch. Implementing a ``hint()`` is a - last resort that's used when a more elegant solution cannot be found. Some - options might graduate to standard features instead of hints over time, or be - added and removed between (major) releases. + largest number of users, and then use functions like `hint()` to allow people to + tune the settings for their particular Sketch. Implementing a `hint()` is a last + resort that's used when a more elegant solution cannot be found. Some options + might graduate to standard features instead of hints over time, or be added and + removed between (major) releases. - Like other ``Py5Graphics`` methods, ``hint()`` can only be used between calls to - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. + Like other `Py5Graphics` methods, `hint()` can only be used between calls to + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. Hints used by the Default Renderer ---------------------------------- - * ``ENABLE_STROKE_PURE``: Fixes a problem with shapes that have a stroke and are - rendered using small steps (for instance, using ``Py5Graphics.vertex()`` with + * `ENABLE_STROKE_PURE`: Fixes a problem with shapes that have a stroke and are + rendered using small steps (for instance, using `Py5Graphics.vertex()` with points that are close to one another), or are drawn at small sizes. - Hints for use with ``P2D`` and ``P3D`` + Hints for use with `P2D` and `P3D` -------------------------------------- - * ``DISABLE_OPENGL_ERRORS``: Speeds up the ``P3D`` renderer setting by not - checking for errors while running. - * ``DISABLE_TEXTURE_MIPMAPS``: Disable generation of texture mipmaps in ``P2D`` - or ``P3D``. This results in lower quality - but faster - rendering of texture - images when they appear smaller than their native resolutions (the mipmaps are - scaled-down versions of a texture that make it look better when drawing it at a - small size). However, the difference in performance is fairly minor on recent - desktop video cards. + * `DISABLE_OPENGL_ERRORS`: Speeds up the `P3D` renderer setting by not checking + for errors while running. + * `DISABLE_TEXTURE_MIPMAPS`: Disable generation of texture mipmaps in `P2D` or + `P3D`. This results in lower quality - but faster - rendering of texture images + when they appear smaller than their native resolutions (the mipmaps are scaled- + down versions of a texture that make it look better when drawing it at a small + size). However, the difference in performance is fairly minor on recent desktop + video cards. - Hints for use with ``P3D`` only + Hints for use with `P3D` only ------------------------------- - * ``DISABLE_DEPTH_MASK``: Disables writing into the depth buffer. This means - that a shape drawn with this hint can be hidden by another shape drawn later, + * `DISABLE_DEPTH_MASK`: Disables writing into the depth buffer. This means that + a shape drawn with this hint can be hidden by another shape drawn later, irrespective of their distances to the camera. Note that this is different from disabling the depth test. The depth test is still applied, as long as the - ``DISABLE_DEPTH_TEST`` hint is not called, but the depth values of the objects - are not recorded. This is useful when drawing a semi-transparent 3D object - without depth sorting, in order to avoid visual glitches due the faces of the - object being at different distances from the camera, but still having the object + `DISABLE_DEPTH_TEST` hint is not called, but the depth values of the objects are + not recorded. This is useful when drawing a semi-transparent 3D object without + depth sorting, in order to avoid visual glitches due the faces of the object + being at different distances from the camera, but still having the object properly occluded by the rest of the objects in the scene. - * ``ENABLE_DEPTH_SORT``: Enable primitive z-sorting of triangles and lines in - ``P3D``. This can slow performance considerably, and the algorithm is not yet + * `ENABLE_DEPTH_SORT`: Enable primitive z-sorting of triangles and lines in + `P3D`. This can slow performance considerably, and the algorithm is not yet perfect. - * ``DISABLE_DEPTH_TEST``: Disable the zbuffer, allowing you to draw on top of + * `DISABLE_DEPTH_TEST`: Disable the zbuffer, allowing you to draw on top of everything at will. When depth testing is disabled, items will be drawn to the screen sequentially, like a painting. This hint is most often used to draw in 3D, then draw in 2D on top of it (for instance, to draw GUI controls in 2D on top of a 3D interface). When called, this will also clear the depth buffer. - Restore the default with ``hint(ENABLE_DEPTH_TEST)``, but note that with the - depth buffer cleared, any 3D drawing that happens later in will ignore existing - shapes on the screen. - * ``DISABLE_OPTIMIZED_STROKE``: Forces the ``P3D`` renderer to draw each shape + Restore the default with `hint(ENABLE_DEPTH_TEST)`, but note that with the depth + buffer cleared, any 3D drawing that happens later in will ignore existing shapes + on the screen. + * `DISABLE_OPTIMIZED_STROKE`: Forces the `P3D` renderer to draw each shape (including its strokes) separately, instead of batching them into larger groups for better performance. One consequence of this is that 2D items drawn with - ``P3D`` are correctly stacked on the screen, depending on the order in which - they were drawn. Otherwise, glitches such as the stroke lines being drawn on top - of the interior of all the shapes will occur. However, this hint can make - rendering substantially slower, so it is recommended to use it only when drawing - a small amount of shapes. For drawing two-dimensional scenes, use the ``P2D`` - renderer instead, which doesn't need the hint to properly stack shapes and their - strokes. - * ``ENABLE_STROKE_PERSPECTIVE``: Enables stroke geometry (lines and points) to - be affected by the perspective, meaning that they will look smaller as they move + `P3D` are correctly stacked on the screen, depending on the order in which they + were drawn. Otherwise, glitches such as the stroke lines being drawn on top of + the interior of all the shapes will occur. However, this hint can make rendering + substantially slower, so it is recommended to use it only when drawing a small + amount of shapes. For drawing two-dimensional scenes, use the `P2D` renderer + instead, which doesn't need the hint to properly stack shapes and their strokes. + * `ENABLE_STROKE_PERSPECTIVE`: Enables stroke geometry (lines and points) to be + affected by the perspective, meaning that they will look smaller as they move away from the camera. - This method is the same as ``hint()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``hint()``. + This method is the same as `hint()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `hint()`. """ return self._instance.hint(which) @@ -7483,14 +7491,14 @@ def hue(self, rgb: int, /) -> float: Extracts the hue value from a color. - This method is the same as ``hue()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``hue()``. + This method is the same as `hue()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `hue()`. """ return self._instance.hue(rgb) @overload def image(self, img: Py5Image, a: float, b: float, /) -> None: - """The ``image()`` function draws an image to the Py5Graphics drawing surface. + """The `image()` function draws an image to the Py5Graphics drawing surface. Underlying Processing method: PGraphics.image @@ -7536,32 +7544,32 @@ def image(self, img: Py5Image, a: float, b: float, /) -> None: Notes ----- - The ``image()`` function draws an image to the Py5Graphics drawing surface. - Images must be in the Sketch's "data" directory to load correctly. Py5 currently - works with GIF, JPEG, and PNG images. + The `image()` function draws an image to the Py5Graphics drawing surface. Images + must be in the Sketch's "data" directory to load correctly. Py5 currently works + with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``Py5Graphics.image_mode()`` function can be used to change + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `Py5Graphics.image_mode()` function can be used to change the way these parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``Py5Graphics.texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `Py5Graphics.texture_mode()` setting. - The color of an image may be modified with the ``Py5Graphics.tint()`` function. + The color of an image may be modified with the `Py5Graphics.tint()` function. This function will maintain transparency for GIF and PNG images. - This method is the same as ``image()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``image()``. + This method is the same as `image()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `image()`. """ pass @overload def image(self, img: Py5Image, a: float, b: float, c: float, d: float, /) -> None: - """The ``image()`` function draws an image to the Py5Graphics drawing surface. + """The `image()` function draws an image to the Py5Graphics drawing surface. Underlying Processing method: PGraphics.image @@ -7607,32 +7615,32 @@ def image(self, img: Py5Image, a: float, b: float, Notes ----- - The ``image()`` function draws an image to the Py5Graphics drawing surface. - Images must be in the Sketch's "data" directory to load correctly. Py5 currently - works with GIF, JPEG, and PNG images. + The `image()` function draws an image to the Py5Graphics drawing surface. Images + must be in the Sketch's "data" directory to load correctly. Py5 currently works + with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``Py5Graphics.image_mode()`` function can be used to change + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `Py5Graphics.image_mode()` function can be used to change the way these parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``Py5Graphics.texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `Py5Graphics.texture_mode()` setting. - The color of an image may be modified with the ``Py5Graphics.tint()`` function. + The color of an image may be modified with the `Py5Graphics.tint()` function. This function will maintain transparency for GIF and PNG images. - This method is the same as ``image()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``image()``. + This method is the same as `image()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `image()`. """ pass @overload def image(self, img: Py5Image, a: float, b: float, c: float, d: float, u1: int, v1: int, u2: int, v2: int, /) -> None: - """The ``image()`` function draws an image to the Py5Graphics drawing surface. + """The `image()` function draws an image to the Py5Graphics drawing surface. Underlying Processing method: PGraphics.image @@ -7678,30 +7686,30 @@ def image(self, img: Py5Image, a: float, b: float, c: float, Notes ----- - The ``image()`` function draws an image to the Py5Graphics drawing surface. - Images must be in the Sketch's "data" directory to load correctly. Py5 currently - works with GIF, JPEG, and PNG images. + The `image()` function draws an image to the Py5Graphics drawing surface. Images + must be in the Sketch's "data" directory to load correctly. Py5 currently works + with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``Py5Graphics.image_mode()`` function can be used to change + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `Py5Graphics.image_mode()` function can be used to change the way these parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``Py5Graphics.texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `Py5Graphics.texture_mode()` setting. - The color of an image may be modified with the ``Py5Graphics.tint()`` function. + The color of an image may be modified with the `Py5Graphics.tint()` function. This function will maintain transparency for GIF and PNG images. - This method is the same as ``image()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``image()``. + This method is the same as `image()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `image()`. """ pass def image(self, *args): - """The ``image()`` function draws an image to the Py5Graphics drawing surface. + """The `image()` function draws an image to the Py5Graphics drawing surface. Underlying Processing method: PGraphics.image @@ -7747,31 +7755,31 @@ def image(self, *args): Notes ----- - The ``image()`` function draws an image to the Py5Graphics drawing surface. - Images must be in the Sketch's "data" directory to load correctly. Py5 currently - works with GIF, JPEG, and PNG images. + The `image()` function draws an image to the Py5Graphics drawing surface. Images + must be in the Sketch's "data" directory to load correctly. Py5 currently works + with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``Py5Graphics.image_mode()`` function can be used to change + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `Py5Graphics.image_mode()` function can be used to change the way these parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``Py5Graphics.texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `Py5Graphics.texture_mode()` setting. - The color of an image may be modified with the ``Py5Graphics.tint()`` function. + The color of an image may be modified with the `Py5Graphics.tint()` function. This function will maintain transparency for GIF and PNG images. - This method is the same as ``image()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``image()``. + This method is the same as `image()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `image()`. """ return self._instance.image(*args) def image_mode(self, mode: int, /) -> None: """Modifies the location from which images are drawn by changing the way in which - parameters given to ``Py5Graphics.image()`` are intepreted. + parameters given to `Py5Graphics.image()` are intepreted. Underlying Processing method: PGraphics.imageMode @@ -7785,26 +7793,26 @@ def image_mode(self, mode: int, /) -> None: ----- Modifies the location from which images are drawn by changing the way in which - parameters given to ``Py5Graphics.image()`` are intepreted. + parameters given to `Py5Graphics.image()` are intepreted. - The default mode is ``image_mode(CORNER)``, which interprets the second and - third parameters of ``Py5Graphics.image()`` as the upper-left corner of the - image. If two additional parameters are specified, they are used to set the - image's width and height. + The default mode is `image_mode(CORNER)`, which interprets the second and third + parameters of `Py5Graphics.image()` as the upper-left corner of the image. If + two additional parameters are specified, they are used to set the image's width + and height. - ``image_mode(CORNERS)`` interprets the second and third parameters of - ``Py5Graphics.image()`` as the location of one corner, and the fourth and fifth + `image_mode(CORNERS)` interprets the second and third parameters of + `Py5Graphics.image()` as the location of one corner, and the fourth and fifth parameters as the opposite corner. - ``image_mode(CENTER)`` interprets the second and third parameters of - ``Py5Graphics.image()`` as the image's center point. If two additional - parameters are specified, they are used to set the image's width and height. + `image_mode(CENTER)` interprets the second and third parameters of + `Py5Graphics.image()` as the image's center point. If two additional parameters + are specified, they are used to set the image's width and height. The parameter must be written in ALL CAPS because Python is a case-sensitive language. - This method is the same as ``image_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``image_mode()``. + This method is the same as `image_mode()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `image_mode()`. """ return self._instance.imageMode(mode) @@ -7840,17 +7848,17 @@ def lerp_color(self, c1: int, c2: int, amt: float, /) -> int: Notes ----- - Calculates a color between two colors at a specific increment. The ``amt`` + Calculates a color between two colors at a specific increment. The `amt` parameter is the amount to interpolate between the two values where 0.0 is equal to the first point, 0.1 is very near the first point, 0.5 is halfway in between, etc. An amount below 0 will be treated as 0. Likewise, amounts above 1 will be capped - at 1. This is different from the behavior of ``lerp()``, but necessary because + at 1. This is different from the behavior of `lerp()`, but necessary because otherwise numbers outside the range will produce strange and unexpected colors. - This method is the same as ``lerp_color()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``lerp_color()``. + This method is the same as `lerp_color()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `lerp_color()`. """ pass @@ -7886,17 +7894,17 @@ def lerp_color(self, c1: int, c2: int, amt: float, mode: int, /) -> int: Notes ----- - Calculates a color between two colors at a specific increment. The ``amt`` + Calculates a color between two colors at a specific increment. The `amt` parameter is the amount to interpolate between the two values where 0.0 is equal to the first point, 0.1 is very near the first point, 0.5 is halfway in between, etc. An amount below 0 will be treated as 0. Likewise, amounts above 1 will be capped - at 1. This is different from the behavior of ``lerp()``, but necessary because + at 1. This is different from the behavior of `lerp()`, but necessary because otherwise numbers outside the range will produce strange and unexpected colors. - This method is the same as ``lerp_color()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``lerp_color()``. + This method is the same as `lerp_color()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `lerp_color()`. """ pass @@ -7932,17 +7940,17 @@ def lerp_color(self, *args): Notes ----- - Calculates a color between two colors at a specific increment. The ``amt`` + Calculates a color between two colors at a specific increment. The `amt` parameter is the amount to interpolate between the two values where 0.0 is equal to the first point, 0.1 is very near the first point, 0.5 is halfway in between, etc. An amount below 0 will be treated as 0. Likewise, amounts above 1 will be capped - at 1. This is different from the behavior of ``lerp()``, but necessary because + at 1. This is different from the behavior of `lerp()`, but necessary because otherwise numbers outside the range will produce strange and unexpected colors. - This method is the same as ``lerp_color()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``lerp_color()``. + This method is the same as `lerp_color()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `lerp_color()`. """ return self._instance.lerpColor(*args) @@ -7968,11 +7976,11 @@ def light_falloff(self, constant: float, linear: float, ----- Sets the falloff rates for point lights, spot lights, and ambient lights. Like - ``Py5Graphics.fill()``, it affects only the elements which are created after it - in the code. The default value is ``light_falloff(1.0, 0.0, 0.0)``, and the - parameters are used to calculate the falloff with the equation ``falloff = 1 / - (CONSTANT + d * ``LINEAR`` + (d*d) * QUADRATIC)``, where ``d`` is the distance - from light position to vertex position. + `Py5Graphics.fill()`, it affects only the elements which are created after it in + the code. The default value is `light_falloff(1.0, 0.0, 0.0)`, and the + parameters are used to calculate the falloff with the equation `falloff = 1 / + (CONSTANT + d * `LINEAR` + (d*d) * QUADRATIC)`, where `d` is the distance from + light position to vertex position. Thinking about an ambient light with a falloff can be tricky. If you want a region of your scene to be lit ambiently with one color and another region to be @@ -7980,8 +7988,8 @@ def light_falloff(self, constant: float, linear: float, and falloff. You can think of it as a point light that doesn't care which direction a surface is facing. - This method is the same as ``light_falloff()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``light_falloff()``. + This method is the same as `light_falloff()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `light_falloff()`. """ return self._instance.lightFalloff(constant, linear, quadratic) @@ -8005,16 +8013,15 @@ def light_specular(self, v1: float, v2: float, v3: float, /) -> None: Notes ----- - Sets the specular color for lights. Like ``Py5Graphics.fill()``, it affects only + Sets the specular color for lights. Like `Py5Graphics.fill()`, it affects only the elements which are created after it in the code. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a diffuse light) and is used for creating highlights. The specular quality of a light interacts with the specular material qualities set - through the ``Py5Graphics.specular()`` and ``Py5Graphics.shininess()`` - functions. + through the `Py5Graphics.specular()` and `Py5Graphics.shininess()` functions. - This method is the same as ``light_specular()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``light_specular()``. + This method is the same as `light_specular()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `light_specular()`. """ return self._instance.lightSpecular(v1, v2, v3) @@ -8027,12 +8034,11 @@ def lights(self) -> None: ----- Sets the default ambient light, directional light, falloff, and specular values. - The defaults are ``ambientLight(128, 128, 128)`` and ``directionalLight(128, - 128, 128, 0, 0, -1)``, ``lightFalloff(1, 0, 0)``, and ``lightSpecular(0, 0, - 0)``. + The defaults are `ambientLight(128, 128, 128)` and `directionalLight(128, 128, + 128, 0, 0, -1)`, `lightFalloff(1, 0, 0)`, and `lightSpecular(0, 0, 0)`. - This method is the same as ``lights()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``lights()``. + This method is the same as `lights()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `lights()`. """ return self._instance.lights() @@ -8076,16 +8082,16 @@ def line(self, x1: float, y1: float, x2: float, y2: float, /) -> None: ----- Draws a line (a direct path between two points) to the Py5Graphics drawing - surface. The version of ``line()`` with four parameters draws the line in 2D. - To color a line, use the ``Py5Graphics.stroke()`` function. A line cannot be - filled, therefore the ``Py5Graphics.fill()`` function will not affect the color - of a line. 2D lines are drawn with a width of one pixel by default, but this can - be changed with the ``Py5Graphics.stroke_weight()`` function. The version with - six parameters allows the line to be placed anywhere within XYZ space. Drawing - this shape in 3D with the ``z`` parameter requires the ``P3D`` renderer. + surface. The version of `line()` with four parameters draws the line in 2D. To + color a line, use the `Py5Graphics.stroke()` function. A line cannot be filled, + therefore the `Py5Graphics.fill()` function will not affect the color of a line. + 2D lines are drawn with a width of one pixel by default, but this can be changed + with the `Py5Graphics.stroke_weight()` function. The version with six parameters + allows the line to be placed anywhere within XYZ space. Drawing this shape in 3D + with the `z` parameter requires the `P3D` renderer. - This method is the same as ``line()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``line()``. + This method is the same as `line()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `line()`. """ pass @@ -8130,16 +8136,16 @@ def line(self, x1: float, y1: float, z1: float, ----- Draws a line (a direct path between two points) to the Py5Graphics drawing - surface. The version of ``line()`` with four parameters draws the line in 2D. - To color a line, use the ``Py5Graphics.stroke()`` function. A line cannot be - filled, therefore the ``Py5Graphics.fill()`` function will not affect the color - of a line. 2D lines are drawn with a width of one pixel by default, but this can - be changed with the ``Py5Graphics.stroke_weight()`` function. The version with - six parameters allows the line to be placed anywhere within XYZ space. Drawing - this shape in 3D with the ``z`` parameter requires the ``P3D`` renderer. + surface. The version of `line()` with four parameters draws the line in 2D. To + color a line, use the `Py5Graphics.stroke()` function. A line cannot be filled, + therefore the `Py5Graphics.fill()` function will not affect the color of a line. + 2D lines are drawn with a width of one pixel by default, but this can be changed + with the `Py5Graphics.stroke_weight()` function. The version with six parameters + allows the line to be placed anywhere within XYZ space. Drawing this shape in 3D + with the `z` parameter requires the `P3D` renderer. - This method is the same as ``line()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``line()``. + This method is the same as `line()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `line()`. """ pass @@ -8182,22 +8188,22 @@ def line(self, *args): ----- Draws a line (a direct path between two points) to the Py5Graphics drawing - surface. The version of ``line()`` with four parameters draws the line in 2D. - To color a line, use the ``Py5Graphics.stroke()`` function. A line cannot be - filled, therefore the ``Py5Graphics.fill()`` function will not affect the color - of a line. 2D lines are drawn with a width of one pixel by default, but this can - be changed with the ``Py5Graphics.stroke_weight()`` function. The version with - six parameters allows the line to be placed anywhere within XYZ space. Drawing - this shape in 3D with the ``z`` parameter requires the ``P3D`` renderer. + surface. The version of `line()` with four parameters draws the line in 2D. To + color a line, use the `Py5Graphics.stroke()` function. A line cannot be filled, + therefore the `Py5Graphics.fill()` function will not affect the color of a line. + 2D lines are drawn with a width of one pixel by default, but this can be changed + with the `Py5Graphics.stroke_weight()` function. The version with six parameters + allows the line to be placed anywhere within XYZ space. Drawing this shape in 3D + with the `z` parameter requires the `P3D` renderer. - This method is the same as ``line()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``line()``. + This method is the same as `line()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `line()`. """ return self._instance.line(*args) def load_pixels(self) -> None: """Loads the pixel data of the current Py5Graphics drawing surface into the - ``Py5Graphics.pixels[]`` array. + `Py5Graphics.pixels[]` array. Underlying Processing method: PGraphics.loadPixels @@ -8205,19 +8211,18 @@ def load_pixels(self) -> None: ----- Loads the pixel data of the current Py5Graphics drawing surface into the - ``Py5Graphics.pixels[]`` array. This function must always be called before - reading from or writing to ``Py5Graphics.pixels[]``. Subsequent changes to the - Py5Graphics drawing surface will not be reflected in ``Py5Graphics.pixels[]`` - until ``load_pixels()`` is called again. + `Py5Graphics.pixels[]` array. This function must always be called before reading + from or writing to `Py5Graphics.pixels[]`. Subsequent changes to the Py5Graphics + drawing surface will not be reflected in `Py5Graphics.pixels[]` until + `load_pixels()` is called again. - This method is the same as ``load_pixels()`` but linked to a ``Py5Graphics`` - object. + This method is the same as `load_pixels()` but linked to a `Py5Graphics` object. """ return self._instance.loadPixels() @overload def load_shader(self, frag_filename: str, /) -> Py5Shader: - """Loads a shader into a ``Py5Shader`` object. + """Loads a shader into a `Py5Shader` object. Underlying Processing method: PGraphics.loadShader @@ -8241,29 +8246,29 @@ def load_shader(self, frag_filename: str, /) -> Py5Shader: Notes ----- - Loads a shader into a ``Py5Shader`` object. The shader file must be located in - the Sketch's "data" directory to load correctly. Shaders are compatible with the - ``P2D`` and ``P3D`` renderers, but not with the default renderer. + Loads a shader into a `Py5Shader` object. The shader file must be located in the + Sketch's "data" directory to load correctly. Shaders are compatible with the + `P2D` and `P3D` renderers, but not with the default renderer. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. - This method is the same as ``load_shader()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``load_shader()``. + This method is the same as `load_shader()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `load_shader()`. """ pass @overload def load_shader(self, frag_filename: str, vert_filename: str, /) -> Py5Shader: - """Loads a shader into a ``Py5Shader`` object. + """Loads a shader into a `Py5Shader` object. Underlying Processing method: PGraphics.loadShader @@ -8287,28 +8292,28 @@ def load_shader(self, frag_filename: str, Notes ----- - Loads a shader into a ``Py5Shader`` object. The shader file must be located in - the Sketch's "data" directory to load correctly. Shaders are compatible with the - ``P2D`` and ``P3D`` renderers, but not with the default renderer. + Loads a shader into a `Py5Shader` object. The shader file must be located in the + Sketch's "data" directory to load correctly. Shaders are compatible with the + `P2D` and `P3D` renderers, but not with the default renderer. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. - This method is the same as ``load_shader()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``load_shader()``. + This method is the same as `load_shader()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `load_shader()`. """ pass @_load_py5shader def load_shader(self, *args): - """Loads a shader into a ``Py5Shader`` object. + """Loads a shader into a `Py5Shader` object. Underlying Processing method: PGraphics.loadShader @@ -8332,28 +8337,28 @@ def load_shader(self, *args): Notes ----- - Loads a shader into a ``Py5Shader`` object. The shader file must be located in - the Sketch's "data" directory to load correctly. Shaders are compatible with the - ``P2D`` and ``P3D`` renderers, but not with the default renderer. + Loads a shader into a `Py5Shader` object. The shader file must be located in the + Sketch's "data" directory to load correctly. Shaders are compatible with the + `P2D` and `P3D` renderers, but not with the default renderer. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. - This method is the same as ``load_shader()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``load_shader()``. + This method is the same as `load_shader()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `load_shader()`. """ return self._instance.loadShader(*args) @overload def load_shape(self, filename: str, /) -> Py5Shape: - """Loads geometry into a variable of type ``Py5Shape``. + """Loads geometry into a variable of type `Py5Shape`. Underlying Processing method: PGraphics.loadShape @@ -8377,30 +8382,29 @@ def load_shape(self, filename: str, /) -> Py5Shape: Notes ----- - Loads geometry into a variable of type ``Py5Shape``. SVG and OBJ files may be + Loads geometry into a variable of type `Py5Shape`. SVG and OBJ files may be loaded. To load correctly, the file must be located in the data directory of the - current Sketch. In most cases, ``load_shape()`` should be used inside - ``setup()`` because loading shapes inside ``draw()`` will reduce the speed of a - Sketch. + current Sketch. In most cases, `load_shape()` should be used inside `setup()` + because loading shapes inside `draw()` will reduce the speed of a Sketch. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause errors if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause errors if your code does not + check whether the value returned is `None`. - This method is the same as ``load_shape()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``load_shape()``. + This method is the same as `load_shape()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `load_shape()`. """ pass @overload def load_shape(self, filename: str, options: str, /) -> Py5Shape: - """Loads geometry into a variable of type ``Py5Shape``. + """Loads geometry into a variable of type `Py5Shape`. Underlying Processing method: PGraphics.loadShape @@ -8424,30 +8428,29 @@ def load_shape(self, filename: str, options: str, /) -> Py5Shape: Notes ----- - Loads geometry into a variable of type ``Py5Shape``. SVG and OBJ files may be + Loads geometry into a variable of type `Py5Shape`. SVG and OBJ files may be loaded. To load correctly, the file must be located in the data directory of the - current Sketch. In most cases, ``load_shape()`` should be used inside - ``setup()`` because loading shapes inside ``draw()`` will reduce the speed of a - Sketch. + current Sketch. In most cases, `load_shape()` should be used inside `setup()` + because loading shapes inside `draw()` will reduce the speed of a Sketch. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause errors if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause errors if your code does not + check whether the value returned is `None`. - This method is the same as ``load_shape()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``load_shape()``. + This method is the same as `load_shape()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `load_shape()`. """ pass @_load_py5shape def load_shape(self, *args): - """Loads geometry into a variable of type ``Py5Shape``. + """Loads geometry into a variable of type `Py5Shape`. Underlying Processing method: PGraphics.loadShape @@ -8471,24 +8474,23 @@ def load_shape(self, *args): Notes ----- - Loads geometry into a variable of type ``Py5Shape``. SVG and OBJ files may be + Loads geometry into a variable of type `Py5Shape`. SVG and OBJ files may be loaded. To load correctly, the file must be located in the data directory of the - current Sketch. In most cases, ``load_shape()`` should be used inside - ``setup()`` because loading shapes inside ``draw()`` will reduce the speed of a - Sketch. + current Sketch. In most cases, `load_shape()` should be used inside `setup()` + because loading shapes inside `draw()` will reduce the speed of a Sketch. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause errors if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause errors if your code does not + check whether the value returned is `None`. - This method is the same as ``load_shape()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``load_shape()``. + This method is the same as `load_shape()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `load_shape()`. """ return self._instance.loadShape(*args) @@ -8637,15 +8639,15 @@ def model_x(self, x: float, y: float, z: float, /) -> float: space relative to the location of the original point once the transformations are no longer in use. - To see an example for how this can be used, see ``model_x()``. In that example, - the ``model_x()``, ``model_y()``, and ``model_z()`` methods (which are analogous - to the ``model_x()``, ``Py5Graphics.model_y()``, and ``Py5Graphics.model_z()`` - methods) record the location of a box in space after being placed using a series - of translate and rotate commands. After ``pop_matrix()`` is called, those + To see an example for how this can be used, see `model_x()`. In that example, + the `model_x()`, `model_y()`, and `model_z()` methods (which are analogous to + the `model_x()`, `Py5Graphics.model_y()`, and `Py5Graphics.model_z()` methods) + record the location of a box in space after being placed using a series of + translate and rotate commands. After `pop_matrix()` is called, those transformations no longer apply, but the (x, y, z) coordinate returned by the model functions is used to place another box in the same location. - This method is the same as ``model_x()`` but linked to a ``Py5Graphics`` object. + This method is the same as `model_x()` but linked to a `Py5Graphics` object. """ return self._instance.modelX(x, y, z) @@ -8675,15 +8677,15 @@ def model_y(self, x: float, y: float, z: float, /) -> float: space relative to the location of the original point once the transformations are no longer in use. - To see an example for how this can be used, see ``model_y()``. In that example, - the ``model_x()``, ``model_y()``, and ``model_z()`` methods (which are analogous - to the ``Py5Graphics.model_x()``, ``model_y()``, and ``Py5Graphics.model_z()`` - methods) record the location of a box in space after being placed using a series - of translate and rotate commands. After ``pop_matrix()`` is called, those + To see an example for how this can be used, see `model_y()`. In that example, + the `model_x()`, `model_y()`, and `model_z()` methods (which are analogous to + the `Py5Graphics.model_x()`, `model_y()`, and `Py5Graphics.model_z()` methods) + record the location of a box in space after being placed using a series of + translate and rotate commands. After `pop_matrix()` is called, those transformations no longer apply, but the (x, y, z) coordinate returned by the model functions is used to place another box in the same location. - This method is the same as ``model_y()`` but linked to a ``Py5Graphics`` object. + This method is the same as `model_y()` but linked to a `Py5Graphics` object. """ return self._instance.modelY(x, y, z) @@ -8713,30 +8715,30 @@ def model_z(self, x: float, y: float, z: float, /) -> float: space relative to the location of the original point once the transformations are no longer in use. - To see an example for how this can be used, see ``model_y()``. In that example, - the ``model_x()``, ``model_y()``, and ``model_z()`` methods (which are analogous - to the ``Py5Graphics.model_x()``, ``Py5Graphics.model_y()``, and ``model_z()`` - methods) record the location of a box in space after being placed using a series - of translate and rotate commands. After ``pop_matrix()`` is called, those + To see an example for how this can be used, see `model_y()`. In that example, + the `model_x()`, `model_y()`, and `model_z()` methods (which are analogous to + the `Py5Graphics.model_x()`, `Py5Graphics.model_y()`, and `model_z()` methods) + record the location of a box in space after being placed using a series of + translate and rotate commands. After `pop_matrix()` is called, those transformations no longer apply, but the (x, y, z) coordinate returned by the model functions is used to place another box in the same location. - This method is the same as ``model_z()`` but linked to a ``Py5Graphics`` object. + This method is the same as `model_z()` but linked to a `Py5Graphics` object. """ return self._instance.modelZ(x, y, z) def no_clip(self) -> None: - """Disables the clipping previously started by the ``Py5Graphics.clip()`` function. + """Disables the clipping previously started by the `Py5Graphics.clip()` function. Underlying Processing method: PGraphics.noClip Notes ----- - Disables the clipping previously started by the ``Py5Graphics.clip()`` function. + Disables the clipping previously started by the `Py5Graphics.clip()` function. - This method is the same as ``no_clip()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``no_clip()``. + This method is the same as `no_clip()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `no_clip()`. """ return self._instance.noClip() @@ -8748,11 +8750,11 @@ def no_fill(self) -> None: Notes ----- - Disables filling geometry. If both ``Py5Graphics.no_stroke()`` and ``no_fill()`` - are called, nothing will be drawn to the screen. + Disables filling geometry. If both `Py5Graphics.no_stroke()` and `no_fill()` are + called, nothing will be drawn to the screen. - This method is the same as ``no_fill()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``no_fill()``. + This method is the same as `no_fill()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `no_fill()`. """ return self._instance.noFill() @@ -8765,12 +8767,12 @@ def no_lights(self) -> None: ----- Disable all lighting. Lighting is turned off by default and enabled with the - ``Py5Graphics.lights()`` function. This function can be used to disable lighting + `Py5Graphics.lights()` function. This function can be used to disable lighting so that 2D geometry (which does not require lighting) can be drawn after a set of lighted 3D geometry. - This method is the same as ``no_lights()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``no_lights()``. + This method is the same as `no_lights()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `no_lights()`. """ return self._instance.noLights() @@ -8785,13 +8787,13 @@ def no_smooth(self) -> None: Draws all geometry and fonts with jagged (aliased) edges and images with hard edges between the pixels when enlarged rather than interpolating pixels. Note - that ``Py5Graphics.smooth()`` is active by default, so it is necessary to call - ``no_smooth()`` to disable smoothing of geometry, fonts, and images. The - ``no_smooth()`` method can only be run once for a ``Py5Graphics`` object and it - must be called before ``Py5Graphics.begin_draw()``. + that `Py5Graphics.smooth()` is active by default, so it is necessary to call + `no_smooth()` to disable smoothing of geometry, fonts, and images. The + `no_smooth()` method can only be run once for a `Py5Graphics` object and it must + be called before `Py5Graphics.begin_draw()`. - This method is the same as ``no_smooth()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``no_smooth()``. + This method is the same as `no_smooth()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `no_smooth()`. """ return self._instance.noSmooth() @@ -8803,11 +8805,11 @@ def no_stroke(self) -> None: Notes ----- - Disables drawing the stroke (outline). If both ``no_stroke()`` and - ``Py5Graphics.no_fill()`` are called, nothing will be drawn to the screen. + Disables drawing the stroke (outline). If both `no_stroke()` and + `Py5Graphics.no_fill()` are called, nothing will be drawn to the screen. - This method is the same as ``no_stroke()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``no_stroke()``. + This method is the same as `no_stroke()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `no_stroke()`. """ return self._instance.noStroke() @@ -8823,8 +8825,8 @@ def no_tint(self) -> None: Removes the current fill value for displaying images and reverts to displaying images with their original hues. - This method is the same as ``no_tint()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``no_tint()``. + This method is the same as `no_tint()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `no_tint()`. """ return self._instance.noTint() @@ -8849,14 +8851,14 @@ def normal(self, nx: float, ny: float, nz: float, /) -> None: ----- Sets the current normal vector. Used for drawing three dimensional shapes and - surfaces, ``normal()`` specifies a vector perpendicular to a shape's surface + surfaces, `normal()` specifies a vector perpendicular to a shape's surface which, in turn, determines how lighting affects it. Py5 attempts to automatically assign normals to shapes, but since that's imperfect, this is a better option when you want more control. This function is identical to - ``gl_normal3f()`` in OpenGL. + `gl_normal3f()` in OpenGL. - This method is the same as ``normal()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``normal()``. + This method is the same as `normal()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `normal()`. """ return self._instance.normal(nx, ny, nz) @@ -8905,10 +8907,10 @@ def ortho(self) -> None: clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. - This method is the same as ``ortho()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``ortho()``. + This method is the same as `ortho()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `ortho()`. """ pass @@ -8958,10 +8960,10 @@ def ortho(self, left: float, right: float, clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. - This method is the same as ``ortho()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``ortho()``. + This method is the same as `ortho()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `ortho()`. """ pass @@ -9011,10 +9013,10 @@ def ortho(self, left: float, right: float, bottom: float, clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. - This method is the same as ``ortho()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``ortho()``. + This method is the same as `ortho()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `ortho()`. """ pass @@ -9062,10 +9064,10 @@ def ortho(self, *args): clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. - This method is the same as ``ortho()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``ortho()``. + This method is the same as `ortho()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `ortho()`. """ return self._instance.ortho(*args) @@ -9109,11 +9111,11 @@ def perspective(self) -> None: perspective of the world more accurately than orthographic projection. The version of perspective without parameters sets the default perspective and the version with four parameters allows the programmer to set the area precisely. - The default values are: ``perspective(PI/3.0, width/height, cameraZ/10.0, - cameraZ*10.0)`` where cameraZ is ``((height/2.0) / tan(PI*60.0/360.0))``. + The default values are: `perspective(PI/3.0, width/height, cameraZ/10.0, + cameraZ*10.0)` where cameraZ is `((height/2.0) / tan(PI*60.0/360.0))`. - This method is the same as ``perspective()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``perspective()``. + This method is the same as `perspective()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `perspective()`. """ pass @@ -9158,11 +9160,11 @@ def perspective(self, fovy: float, aspect: float, perspective of the world more accurately than orthographic projection. The version of perspective without parameters sets the default perspective and the version with four parameters allows the programmer to set the area precisely. - The default values are: ``perspective(PI/3.0, width/height, cameraZ/10.0, - cameraZ*10.0)`` where cameraZ is ``((height/2.0) / tan(PI*60.0/360.0))``. + The default values are: `perspective(PI/3.0, width/height, cameraZ/10.0, + cameraZ*10.0)` where cameraZ is `((height/2.0) / tan(PI*60.0/360.0))`. - This method is the same as ``perspective()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``perspective()``. + This method is the same as `perspective()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `perspective()`. """ pass @@ -9205,11 +9207,11 @@ def perspective(self, *args): perspective of the world more accurately than orthographic projection. The version of perspective without parameters sets the default perspective and the version with four parameters allows the programmer to set the area precisely. - The default values are: ``perspective(PI/3.0, width/height, cameraZ/10.0, - cameraZ*10.0)`` where cameraZ is ``((height/2.0) / tan(PI*60.0/360.0))``. + The default values are: `perspective(PI/3.0, width/height, cameraZ/10.0, + cameraZ*10.0)` where cameraZ is `((height/2.0) / tan(PI*60.0/360.0))`. - This method is the same as ``perspective()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``perspective()``. + This method is the same as `perspective()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `perspective()`. """ return self._instance.perspective(*args) @@ -9245,22 +9247,21 @@ def point(self, x: float, y: float, /) -> None: Draws a point, a coordinate in space at the dimension of one pixel. The first parameter is the horizontal value for the point, the second value is the vertical value for the point, and the optional third value is the depth value. - Drawing this shape in 3D with the ``z`` parameter requires the ``P3D`` renderer. + Drawing this shape in 3D with the `z` parameter requires the `P3D` renderer. - Use ``Py5Graphics.stroke()`` to set the color of a ``point()``. + Use `Py5Graphics.stroke()` to set the color of a `point()`. - Point appears round with the default ``stroke_cap(ROUND)`` and square with - ``stroke_cap(PROJECT)``. Points are invisible with ``stroke_cap(SQUARE)`` (no - cap). + Point appears round with the default `stroke_cap(ROUND)` and square with + `stroke_cap(PROJECT)`. Points are invisible with `stroke_cap(SQUARE)` (no cap). - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the Py5Graphics drawing surface, depending on the graphics settings of the computer. - Workarounds include setting the pixel using the ``Py5Graphics.pixels[]`` or - ``Py5Graphics.np_pixels[]`` arrays or drawing the point using either - ``Py5Graphics.circle()`` or ``Py5Graphics.square()``. + Workarounds include setting the pixel using the `Py5Graphics.pixels[]` or + `Py5Graphics.np_pixels[]` arrays or drawing the point using either + `Py5Graphics.circle()` or `Py5Graphics.square()`. - This method is the same as ``point()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``point()``. + This method is the same as `point()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `point()`. """ pass @@ -9296,22 +9297,21 @@ def point(self, x: float, y: float, z: float, /) -> None: Draws a point, a coordinate in space at the dimension of one pixel. The first parameter is the horizontal value for the point, the second value is the vertical value for the point, and the optional third value is the depth value. - Drawing this shape in 3D with the ``z`` parameter requires the ``P3D`` renderer. + Drawing this shape in 3D with the `z` parameter requires the `P3D` renderer. - Use ``Py5Graphics.stroke()`` to set the color of a ``point()``. + Use `Py5Graphics.stroke()` to set the color of a `point()`. - Point appears round with the default ``stroke_cap(ROUND)`` and square with - ``stroke_cap(PROJECT)``. Points are invisible with ``stroke_cap(SQUARE)`` (no - cap). + Point appears round with the default `stroke_cap(ROUND)` and square with + `stroke_cap(PROJECT)`. Points are invisible with `stroke_cap(SQUARE)` (no cap). - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the Py5Graphics drawing surface, depending on the graphics settings of the computer. - Workarounds include setting the pixel using the ``Py5Graphics.pixels[]`` or - ``Py5Graphics.np_pixels[]`` arrays or drawing the point using either - ``Py5Graphics.circle()`` or ``Py5Graphics.square()``. + Workarounds include setting the pixel using the `Py5Graphics.pixels[]` or + `Py5Graphics.np_pixels[]` arrays or drawing the point using either + `Py5Graphics.circle()` or `Py5Graphics.square()`. - This method is the same as ``point()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``point()``. + This method is the same as `point()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `point()`. """ pass @@ -9346,22 +9346,21 @@ def point(self, *args): Draws a point, a coordinate in space at the dimension of one pixel. The first parameter is the horizontal value for the point, the second value is the vertical value for the point, and the optional third value is the depth value. - Drawing this shape in 3D with the ``z`` parameter requires the ``P3D`` renderer. + Drawing this shape in 3D with the `z` parameter requires the `P3D` renderer. - Use ``Py5Graphics.stroke()`` to set the color of a ``point()``. + Use `Py5Graphics.stroke()` to set the color of a `point()`. - Point appears round with the default ``stroke_cap(ROUND)`` and square with - ``stroke_cap(PROJECT)``. Points are invisible with ``stroke_cap(SQUARE)`` (no - cap). + Point appears round with the default `stroke_cap(ROUND)` and square with + `stroke_cap(PROJECT)`. Points are invisible with `stroke_cap(SQUARE)` (no cap). - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the Py5Graphics drawing surface, depending on the graphics settings of the computer. - Workarounds include setting the pixel using the ``Py5Graphics.pixels[]`` or - ``Py5Graphics.np_pixels[]`` arrays or drawing the point using either - ``Py5Graphics.circle()`` or ``Py5Graphics.square()``. + Workarounds include setting the pixel using the `Py5Graphics.pixels[]` or + `Py5Graphics.np_pixels[]` arrays or drawing the point using either + `Py5Graphics.circle()` or `Py5Graphics.square()`. - This method is the same as ``point()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``point()``. + This method is the same as `point()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `point()`. """ return self._instance.point(*args) @@ -9395,50 +9394,50 @@ def point_light(self, v1: float, v2: float, v3: float, Notes ----- - Adds a point light. The ``v1``, ``v2``, and ``v3`` parameters are interpreted as - either RGB or HSB values, depending on the current color mode. The ``x``, ``y``, - and ``z`` parameters set the position of the light. + Adds a point light. The `v1`, `v2`, and `v3` parameters are interpreted as + either RGB or HSB values, depending on the current color mode. The `x`, `y`, and + `z` parameters set the position of the light. - This method is the same as ``point_light()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``point_light()``. + This method is the same as `point_light()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `point_light()`. """ return self._instance.pointLight(v1, v2, v3, x, y, z) def pop(self) -> None: - """The ``pop()`` function restores the previous drawing style settings and - transformations after ``Py5Graphics.push()`` has changed them. + """The `pop()` function restores the previous drawing style settings and + transformations after `Py5Graphics.push()` has changed them. Underlying Processing method: PGraphics.pop Notes ----- - The ``pop()`` function restores the previous drawing style settings and - transformations after ``Py5Graphics.push()`` has changed them. Note that these + The `pop()` function restores the previous drawing style settings and + transformations after `Py5Graphics.push()` has changed them. Note that these functions are always used together. They allow you to change the style and transformation settings and later return to what you had. When a new state is - started with ``Py5Graphics.push()``, it builds on the current style and - transform information. + started with `Py5Graphics.push()`, it builds on the current style and transform + information. - ``Py5Graphics.push()`` stores information related to the current transformation + `Py5Graphics.push()` stores information related to the current transformation state and style settings controlled by the following functions: - ``Py5Graphics.rotate()``, ``Py5Graphics.translate()``, ``Py5Graphics.scale()``, - ``Py5Graphics.fill()``, ``Py5Graphics.stroke()``, ``Py5Graphics.tint()``, - ``Py5Graphics.stroke_weight()``, ``Py5Graphics.stroke_cap()``, - ``Py5Graphics.stroke_join()``, ``Py5Graphics.image_mode()``, - ``Py5Graphics.rect_mode()``, ``Py5Graphics.ellipse_mode()``, - ``Py5Graphics.color_mode()``, ``Py5Graphics.text_align()``, - ``Py5Graphics.text_font()``, ``Py5Graphics.text_mode()``, - ``Py5Graphics.text_size()``, and ``Py5Graphics.text_leading()``. - - The ``Py5Graphics.push()`` and ``pop()`` functions can be used in place of - ``Py5Graphics.push_matrix()``, ``Py5Graphics.pop_matrix()``, - ``Py5Graphics.push_style()``, and ``Py5Graphics.pop_style()``. The difference is - that ``Py5Graphics.push()`` and ``pop()`` control both the transformations - (rotate, scale, translate) and the drawing styles at the same time. - - This method is the same as ``pop()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``pop()``. + `Py5Graphics.rotate()`, `Py5Graphics.translate()`, `Py5Graphics.scale()`, + `Py5Graphics.fill()`, `Py5Graphics.stroke()`, `Py5Graphics.tint()`, + `Py5Graphics.stroke_weight()`, `Py5Graphics.stroke_cap()`, + `Py5Graphics.stroke_join()`, `Py5Graphics.image_mode()`, + `Py5Graphics.rect_mode()`, `Py5Graphics.ellipse_mode()`, + `Py5Graphics.color_mode()`, `Py5Graphics.text_align()`, + `Py5Graphics.text_font()`, `Py5Graphics.text_mode()`, `Py5Graphics.text_size()`, + and `Py5Graphics.text_leading()`. + + The `Py5Graphics.push()` and `pop()` functions can be used in place of + `Py5Graphics.push_matrix()`, `Py5Graphics.pop_matrix()`, + `Py5Graphics.push_style()`, and `Py5Graphics.pop_style()`. The difference is + that `Py5Graphics.push()` and `pop()` control both the transformations (rotate, + scale, translate) and the drawing styles at the same time. + + This method is the same as `pop()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `pop()`. """ return self._instance.pop() @@ -9452,20 +9451,20 @@ def pop_matrix(self) -> None: Pops the current transformation matrix off the matrix stack. Understanding pushing and popping requires understanding the concept of a matrix stack. The - ``Py5Graphics.push_matrix()`` function saves the current coordinate system to - the stack and ``pop_matrix()`` restores the prior coordinate system. - ``Py5Graphics.push_matrix()`` and ``pop_matrix()`` are used in conjuction with - the other transformation functions and may be embedded to control the scope of - the transformations. + `Py5Graphics.push_matrix()` function saves the current coordinate system to the + stack and `pop_matrix()` restores the prior coordinate system. + `Py5Graphics.push_matrix()` and `pop_matrix()` are used in conjuction with the + other transformation functions and may be embedded to control the scope of the + transformations. - This method is the same as ``pop_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``pop_matrix()``. + This method is the same as `pop_matrix()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `pop_matrix()`. """ return self._instance.popMatrix() def pop_style(self) -> None: - """The ``Py5Graphics.push_style()`` function saves the current style settings and - ``pop_style()`` restores the prior settings; these functions are always used + """The `Py5Graphics.push_style()` function saves the current style settings and + `pop_style()` restores the prior settings; these functions are always used together. Underlying Processing method: PGraphics.popStyle @@ -9473,15 +9472,15 @@ def pop_style(self) -> None: Notes ----- - The ``Py5Graphics.push_style()`` function saves the current style settings and - ``pop_style()`` restores the prior settings; these functions are always used + The `Py5Graphics.push_style()` function saves the current style settings and + `pop_style()` restores the prior settings; these functions are always used together. They allow you to change the style settings and later return to what - you had. When a new style is started with ``Py5Graphics.push_style()``, it - builds on the current style information. The ``Py5Graphics.push_style()`` and - ``pop_style()`` method pairs can be nested to provide more control. + you had. When a new style is started with `Py5Graphics.push_style()`, it builds + on the current style information. The `Py5Graphics.push_style()` and + `pop_style()` method pairs can be nested to provide more control. - This method is the same as ``pop_style()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``pop_style()``. + This method is the same as `pop_style()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `pop_style()`. """ return self._instance.popStyle() @@ -9495,8 +9494,8 @@ def print_camera(self) -> None: Prints the current camera matrix to standard output. - This method is the same as ``print_camera()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``print_camera()``. + This method is the same as `print_camera()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `print_camera()`. """ return self._instance.printCamera() @@ -9510,8 +9509,8 @@ def print_matrix(self) -> None: Prints the current matrix to standard output. - This method is the same as ``print_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``print_matrix()``. + This method is the same as `print_matrix()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `print_matrix()`. """ return self._instance.printMatrix() @@ -9525,51 +9524,49 @@ def print_projection(self) -> None: Prints the current projection matrix to standard output. - This method is the same as ``print_projection()`` but linked to a - ``Py5Graphics`` object. To see example code for how it can be used, see - ``print_projection()``. + This method is the same as `print_projection()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `print_projection()`. """ return self._instance.printProjection() @_context_wrapper('pop') def push(self) -> None: - """The ``push()`` function saves the current drawing style settings and - transformations, while ``Py5Graphics.pop()`` restores these settings. + """The `push()` function saves the current drawing style settings and + transformations, while `Py5Graphics.pop()` restores these settings. Underlying Processing method: PGraphics.push Notes ----- - The ``push()`` function saves the current drawing style settings and - transformations, while ``Py5Graphics.pop()`` restores these settings. Note that + The `push()` function saves the current drawing style settings and + transformations, while `Py5Graphics.pop()` restores these settings. Note that these functions are always used together. They allow you to change the style and transformation settings and later return to what you had. When a new state is - started with ``push()``, it builds on the current style and transform - information. - - ``push()`` stores information related to the current transformation state and - style settings controlled by the following functions: ``Py5Graphics.rotate()``, - ``Py5Graphics.translate()``, ``Py5Graphics.scale()``, ``Py5Graphics.fill()``, - ``Py5Graphics.stroke()``, ``Py5Graphics.tint()``, - ``Py5Graphics.stroke_weight()``, ``Py5Graphics.stroke_cap()``, - ``Py5Graphics.stroke_join()``, ``Py5Graphics.image_mode()``, - ``Py5Graphics.rect_mode()``, ``Py5Graphics.ellipse_mode()``, - ``Py5Graphics.color_mode()``, ``Py5Graphics.text_align()``, - ``Py5Graphics.text_font()``, ``Py5Graphics.text_mode()``, - ``Py5Graphics.text_size()``, and ``Py5Graphics.text_leading()``. - - The ``push()`` and ``Py5Graphics.pop()`` functions can be used in place of - ``Py5Graphics.push_matrix()``, ``Py5Graphics.pop_matrix()``, - ``Py5Graphics.push_style()``, and ``Py5Graphics.pop_style()``. The difference is - that ``push()`` and ``Py5Graphics.pop()`` control both the transformations - (rotate, scale, translate) and the drawing styles at the same time. - - This method can be used as a context manager to ensure that - ``Py5Graphics.pop()`` always gets called, as shown in the example. - - This method is the same as ``push()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``push()``. + started with `push()`, it builds on the current style and transform information. + + `push()` stores information related to the current transformation state and + style settings controlled by the following functions: `Py5Graphics.rotate()`, + `Py5Graphics.translate()`, `Py5Graphics.scale()`, `Py5Graphics.fill()`, + `Py5Graphics.stroke()`, `Py5Graphics.tint()`, `Py5Graphics.stroke_weight()`, + `Py5Graphics.stroke_cap()`, `Py5Graphics.stroke_join()`, + `Py5Graphics.image_mode()`, `Py5Graphics.rect_mode()`, + `Py5Graphics.ellipse_mode()`, `Py5Graphics.color_mode()`, + `Py5Graphics.text_align()`, `Py5Graphics.text_font()`, + `Py5Graphics.text_mode()`, `Py5Graphics.text_size()`, and + `Py5Graphics.text_leading()`. + + The `push()` and `Py5Graphics.pop()` functions can be used in place of + `Py5Graphics.push_matrix()`, `Py5Graphics.pop_matrix()`, + `Py5Graphics.push_style()`, and `Py5Graphics.pop_style()`. The difference is + that `push()` and `Py5Graphics.pop()` control both the transformations (rotate, + scale, translate) and the drawing styles at the same time. + + This method can be used as a context manager to ensure that `Py5Graphics.pop()` + always gets called, as shown in the example. + + This method is the same as `push()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `push()`. """ return self._instance.push() @@ -9583,56 +9580,56 @@ def push_matrix(self) -> None: ----- Pushes the current transformation matrix onto the matrix stack. Understanding - ``push_matrix()`` and ``Py5Graphics.pop_matrix()`` requires understanding the - concept of a matrix stack. The ``push_matrix()`` function saves the current - coordinate system to the stack and ``Py5Graphics.pop_matrix()`` restores the - prior coordinate system. ``push_matrix()`` and ``Py5Graphics.pop_matrix()`` are - used in conjuction with the other transformation functions and may be embedded - to control the scope of the transformations. + `push_matrix()` and `Py5Graphics.pop_matrix()` requires understanding the + concept of a matrix stack. The `push_matrix()` function saves the current + coordinate system to the stack and `Py5Graphics.pop_matrix()` restores the prior + coordinate system. `push_matrix()` and `Py5Graphics.pop_matrix()` are used in + conjuction with the other transformation functions and may be embedded to + control the scope of the transformations. This method can be used as a context manager to ensure that - ``Py5Graphics.pop_matrix()`` always gets called, as shown in the example. + `Py5Graphics.pop_matrix()` always gets called, as shown in the example. - This method is the same as ``push_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``push_matrix()``. + This method is the same as `push_matrix()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `push_matrix()`. """ return self._instance.pushMatrix() @_context_wrapper('pop_style') def push_style(self) -> None: - """The ``push_style()`` function saves the current style settings and - ``Py5Graphics.pop_style()`` restores the prior settings. + """The `push_style()` function saves the current style settings and + `Py5Graphics.pop_style()` restores the prior settings. Underlying Processing method: PGraphics.pushStyle Notes ----- - The ``push_style()`` function saves the current style settings and - ``Py5Graphics.pop_style()`` restores the prior settings. Note that these - functions are always used together. They allow you to change the style settings - and later return to what you had. When a new style is started with - ``push_style()``, it builds on the current style information. The - ``push_style()`` and ``Py5Graphics.pop_style()`` method pairs can be nested to - provide more control. (See the second example for a demonstration.) + The `push_style()` function saves the current style settings and + `Py5Graphics.pop_style()` restores the prior settings. Note that these functions + are always used together. They allow you to change the style settings and later + return to what you had. When a new style is started with `push_style()`, it + builds on the current style information. The `push_style()` and + `Py5Graphics.pop_style()` method pairs can be nested to provide more control. + (See the second example for a demonstration.) The style information controlled by the following functions are included in the - style: ``Py5Graphics.fill()``, ``Py5Graphics.stroke()``, ``Py5Graphics.tint()``, - ``Py5Graphics.stroke_weight()``, ``Py5Graphics.stroke_cap()``, - ``Py5Graphics.stroke_join()``, ``Py5Graphics.image_mode()``, - ``Py5Graphics.rect_mode()``, ``Py5Graphics.ellipse_mode()``, - ``Py5Graphics.shape_mode()``, ``Py5Graphics.color_mode()``, - ``Py5Graphics.text_align()``, ``Py5Graphics.text_font()``, - ``Py5Graphics.text_mode()``, ``Py5Graphics.text_size()``, - ``Py5Graphics.text_leading()``, ``Py5Graphics.emissive()``, - ``Py5Graphics.specular()``, ``Py5Graphics.shininess()``, and - ``Py5Graphics.ambient()``. + style: `Py5Graphics.fill()`, `Py5Graphics.stroke()`, `Py5Graphics.tint()`, + `Py5Graphics.stroke_weight()`, `Py5Graphics.stroke_cap()`, + `Py5Graphics.stroke_join()`, `Py5Graphics.image_mode()`, + `Py5Graphics.rect_mode()`, `Py5Graphics.ellipse_mode()`, + `Py5Graphics.shape_mode()`, `Py5Graphics.color_mode()`, + `Py5Graphics.text_align()`, `Py5Graphics.text_font()`, + `Py5Graphics.text_mode()`, `Py5Graphics.text_size()`, + `Py5Graphics.text_leading()`, `Py5Graphics.emissive()`, + `Py5Graphics.specular()`, `Py5Graphics.shininess()`, and + `Py5Graphics.ambient()`. This method can be used as a context manager to ensure that - ``Py5Graphics.pop_style()`` always gets called, as shown in the example. + `Py5Graphics.pop_style()` always gets called, as shown in the example. - This method is the same as ``push_style()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``push_style()``. + This method is the same as `push_style()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `push_style()`. """ return self._instance.pushStyle() @@ -9677,8 +9674,8 @@ def quad(self, x1: float, y1: float, x2: float, y2: float, first pair of parameters (x1,y1) sets the first vertex and the subsequent pairs should proceed clockwise or counter-clockwise around the defined shape. - This method is the same as ``quad()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``quad()``. + This method is the same as `quad()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `quad()`. """ return self._instance.quad(x1, y1, x2, y2, x3, y3, x4, y4) @@ -9722,18 +9719,17 @@ def quadratic_vertex(self, cx: float, cy: float, ----- Specifies vertex coordinates for quadratic Bezier curves. Each call to - ``quadratic_vertex()`` defines the position of one control point and one anchor + `quadratic_vertex()` defines the position of one control point and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time - ``quadratic_vertex()`` is used within a ``Py5Graphics.begin_shape()`` call, it - must be prefaced with a call to ``Py5Graphics.vertex()`` to set the first anchor - point. This method must be used between ``Py5Graphics.begin_shape()`` and - ``Py5Graphics.end_shape()`` and only when there is no ``MODE`` parameter - specified to ``Py5Graphics.begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + `quadratic_vertex()` is used within a `Py5Graphics.begin_shape()` call, it must + be prefaced with a call to `Py5Graphics.vertex()` to set the first anchor point. + This method must be used between `Py5Graphics.begin_shape()` and + `Py5Graphics.end_shape()` and only when there is no `MODE` parameter specified + to `Py5Graphics.begin_shape()`. Using the 3D version requires rendering with + `P3D`. - This method is the same as ``quadratic_vertex()`` but linked to a - ``Py5Graphics`` object. To see example code for how it can be used, see - ``quadratic_vertex()``. + This method is the same as `quadratic_vertex()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `quadratic_vertex()`. """ pass @@ -9777,18 +9773,17 @@ def quadratic_vertex(self, cx: float, cy: float, cz: float, ----- Specifies vertex coordinates for quadratic Bezier curves. Each call to - ``quadratic_vertex()`` defines the position of one control point and one anchor + `quadratic_vertex()` defines the position of one control point and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time - ``quadratic_vertex()`` is used within a ``Py5Graphics.begin_shape()`` call, it - must be prefaced with a call to ``Py5Graphics.vertex()`` to set the first anchor - point. This method must be used between ``Py5Graphics.begin_shape()`` and - ``Py5Graphics.end_shape()`` and only when there is no ``MODE`` parameter - specified to ``Py5Graphics.begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + `quadratic_vertex()` is used within a `Py5Graphics.begin_shape()` call, it must + be prefaced with a call to `Py5Graphics.vertex()` to set the first anchor point. + This method must be used between `Py5Graphics.begin_shape()` and + `Py5Graphics.end_shape()` and only when there is no `MODE` parameter specified + to `Py5Graphics.begin_shape()`. Using the 3D version requires rendering with + `P3D`. - This method is the same as ``quadratic_vertex()`` but linked to a - ``Py5Graphics`` object. To see example code for how it can be used, see - ``quadratic_vertex()``. + This method is the same as `quadratic_vertex()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `quadratic_vertex()`. """ pass @@ -9830,18 +9825,17 @@ def quadratic_vertex(self, *args): ----- Specifies vertex coordinates for quadratic Bezier curves. Each call to - ``quadratic_vertex()`` defines the position of one control point and one anchor + `quadratic_vertex()` defines the position of one control point and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time - ``quadratic_vertex()`` is used within a ``Py5Graphics.begin_shape()`` call, it - must be prefaced with a call to ``Py5Graphics.vertex()`` to set the first anchor - point. This method must be used between ``Py5Graphics.begin_shape()`` and - ``Py5Graphics.end_shape()`` and only when there is no ``MODE`` parameter - specified to ``Py5Graphics.begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + `quadratic_vertex()` is used within a `Py5Graphics.begin_shape()` call, it must + be prefaced with a call to `Py5Graphics.vertex()` to set the first anchor point. + This method must be used between `Py5Graphics.begin_shape()` and + `Py5Graphics.end_shape()` and only when there is no `MODE` parameter specified + to `Py5Graphics.begin_shape()`. Using the 3D version requires rendering with + `P3D`. - This method is the same as ``quadratic_vertex()`` but linked to a - ``Py5Graphics`` object. To see example code for how it can be used, see - ``quadratic_vertex()``. + This method is the same as `quadratic_vertex()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `quadratic_vertex()`. """ return self._instance.quadraticVertex(*args) @@ -9897,7 +9891,7 @@ def rect(self, a: float, b: float, c: float, d: float, /) -> None: sided shape with every angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, - however, may be changed with the ``Py5Graphics.rect_mode()`` function. + however, may be changed with the `Py5Graphics.rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -9907,8 +9901,8 @@ def rect(self, a: float, b: float, c: float, d: float, /) -> None: separately, starting with the top-left corner and moving clockwise around the rectangle. - This method is the same as ``rect()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``rect()``. + This method is the same as `rect()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `rect()`. """ pass @@ -9965,7 +9959,7 @@ def rect(self, a: float, b: float, c: float, sided shape with every angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, - however, may be changed with the ``Py5Graphics.rect_mode()`` function. + however, may be changed with the `Py5Graphics.rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -9975,8 +9969,8 @@ def rect(self, a: float, b: float, c: float, separately, starting with the top-left corner and moving clockwise around the rectangle. - This method is the same as ``rect()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``rect()``. + This method is the same as `rect()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `rect()`. """ pass @@ -10033,7 +10027,7 @@ def rect(self, a: float, b: float, c: float, d: float, sided shape with every angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, - however, may be changed with the ``Py5Graphics.rect_mode()`` function. + however, may be changed with the `Py5Graphics.rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -10043,8 +10037,8 @@ def rect(self, a: float, b: float, c: float, d: float, separately, starting with the top-left corner and moving clockwise around the rectangle. - This method is the same as ``rect()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``rect()``. + This method is the same as `rect()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `rect()`. """ pass @@ -10099,7 +10093,7 @@ def rect(self, *args): sided shape with every angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, - however, may be changed with the ``Py5Graphics.rect_mode()`` function. + however, may be changed with the `Py5Graphics.rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -10109,14 +10103,14 @@ def rect(self, *args): separately, starting with the top-left corner and moving clockwise around the rectangle. - This method is the same as ``rect()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``rect()``. + This method is the same as `rect()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `rect()`. """ return self._instance.rect(*args) def rect_mode(self, mode: int, /) -> None: """Modifies the location from which rectangles are drawn by changing the way in - which parameters given to ``Py5Graphics.rect()`` are intepreted. + which parameters given to `Py5Graphics.rect()` are intepreted. Underlying Processing method: PGraphics.rectMode @@ -10130,36 +10124,36 @@ def rect_mode(self, mode: int, /) -> None: ----- Modifies the location from which rectangles are drawn by changing the way in - which parameters given to ``Py5Graphics.rect()`` are intepreted. + which parameters given to `Py5Graphics.rect()` are intepreted. - The default mode is ``rect_mode(CORNER)``, which interprets the first two - parameters of ``Py5Graphics.rect()`` as the upper-left corner of the shape, - while the third and fourth parameters are its width and height. + The default mode is `rect_mode(CORNER)`, which interprets the first two + parameters of `Py5Graphics.rect()` as the upper-left corner of the shape, while + the third and fourth parameters are its width and height. - ``rect_mode(CORNERS)`` interprets the first two parameters of - ``Py5Graphics.rect()`` as the location of one corner, and the third and fourth - parameters as the location of the opposite corner. + `rect_mode(CORNERS)` interprets the first two parameters of `Py5Graphics.rect()` + as the location of one corner, and the third and fourth parameters as the + location of the opposite corner. - ``rect_mode(CENTER)`` interprets the first two parameters of - ``Py5Graphics.rect()`` as the shape's center point, while the third and fourth - parameters are its width and height. + `rect_mode(CENTER)` interprets the first two parameters of `Py5Graphics.rect()` + as the shape's center point, while the third and fourth parameters are its width + and height. - ``rect_mode(RADIUS)`` also uses the first two parameters of - ``Py5Graphics.rect()`` as the shape's center point, but uses the third and - fourth parameters to specify half of the shapes's width and height. + `rect_mode(RADIUS)` also uses the first two parameters of `Py5Graphics.rect()` + as the shape's center point, but uses the third and fourth parameters to specify + half of the shapes's width and height. The parameter must be written in ALL CAPS because Python is a case-sensitive language. - This method is the same as ``rect_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``rect_mode()``. + This method is the same as `rect_mode()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `rect_mode()`. """ return self._instance.rectMode(mode) @_convert_hex_color() def red(self, rgb: int, /) -> float: """Extracts the red value from a color, scaled to match current - ``Py5Graphics.color_mode()``. + `Py5Graphics.color_mode()`. Underlying Processing method: PGraphics.red @@ -10173,17 +10167,17 @@ def red(self, rgb: int, /) -> float: ----- Extracts the red value from a color, scaled to match current - ``Py5Graphics.color_mode()``. + `Py5Graphics.color_mode()`. - The ``red()`` function is easy to use and understand, but it is slower than a - technique called bit shifting. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``red()`` but with greater speed by using the right - shift operator (``>>``) with a bit mask. For example, ``red(c)`` and ``c >> 16 & - 0xFF`` both extract the red value from a color variable ``c`` but the later is + The `red()` function is easy to use and understand, but it is slower than a + technique called bit shifting. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `red()` but with greater speed by using the right + shift operator (`>>`) with a bit mask. For example, `red(c)` and `c >> 16 & + 0xFF` both extract the red value from a color variable `c` but the later is faster. - This method is the same as ``red()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``red()``. + This method is the same as `red()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `red()`. """ return self._instance.red(rgb) @@ -10196,10 +10190,10 @@ def reset_matrix(self) -> None: ----- Replaces the current matrix with the identity matrix. The equivalent function in - OpenGL is ``gl_load_identity()``. + OpenGL is `gl_load_identity()`. - This method is the same as ``reset_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``reset_matrix()``. + This method is the same as `reset_matrix()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `reset_matrix()`. """ return self._instance.resetMatrix() @@ -10226,11 +10220,11 @@ def reset_shader(self) -> None: Notes ----- - Restores the default shaders. Code that runs after ``reset_shader()`` will not - be affected by previously defined shaders. + Restores the default shaders. Code that runs after `reset_shader()` will not be + affected by previously defined shaders. - This method is the same as ``reset_shader()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``reset_shader()``. + This method is the same as `reset_shader()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `reset_shader()`. """ pass @@ -10257,11 +10251,11 @@ def reset_shader(self, kind: int, /) -> None: Notes ----- - Restores the default shaders. Code that runs after ``reset_shader()`` will not - be affected by previously defined shaders. + Restores the default shaders. Code that runs after `reset_shader()` will not be + affected by previously defined shaders. - This method is the same as ``reset_shader()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``reset_shader()``. + This method is the same as `reset_shader()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `reset_shader()`. """ pass @@ -10287,17 +10281,17 @@ def reset_shader(self, *args): Notes ----- - Restores the default shaders. Code that runs after ``reset_shader()`` will not - be affected by previously defined shaders. + Restores the default shaders. Code that runs after `reset_shader()` will not be + affected by previously defined shaders. - This method is the same as ``reset_shader()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``reset_shader()``. + This method is the same as `reset_shader()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `reset_shader()`. """ return self._instance.resetShader(*args) @overload def rotate(self, angle: float, /) -> None: - """Rotates the amount specified by the ``angle`` parameter. + """Rotates the amount specified by the `angle` parameter. Underlying Processing method: PGraphics.rotate @@ -10327,30 +10321,30 @@ def rotate(self, angle: float, /) -> None: Notes ----- - Rotates the amount specified by the ``angle`` parameter. Angles must be - specified in radians (values from ``0`` to ``TWO_PI``), or they can be converted - from degrees to radians with the ``radians()`` function. + Rotates the amount specified by the `angle` parameter. Angles must be specified + in radians (values from `0` to `TWO_PI`), or they can be converted from degrees + to radians with the `radians()` function. The coordinates are always rotated around their relative position to the origin. Positive numbers rotate objects in a clockwise direction and negative numbers rotate in the couterclockwise direction. Transformations apply to everything that happens afterward, and subsequent calls to the function compound the - effect. For example, calling ``rotate(PI/2.0)`` once and then calling - ``rotate(PI/2.0)`` a second time is the same as a single ``rotate(PI)``. All - tranformations are reset when ``draw()`` begins again. + effect. For example, calling `rotate(PI/2.0)` once and then calling + `rotate(PI/2.0)` a second time is the same as a single `rotate(PI)`. All + tranformations are reset when `draw()` begins again. - Technically, ``rotate()`` multiplies the current transformation matrix by a + Technically, `rotate()` multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by - ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()``. + `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()`. - This method is the same as ``rotate()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``rotate()``. + This method is the same as `rotate()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `rotate()`. """ pass @overload def rotate(self, angle: float, x: float, y: float, z: float, /) -> None: - """Rotates the amount specified by the ``angle`` parameter. + """Rotates the amount specified by the `angle` parameter. Underlying Processing method: PGraphics.rotate @@ -10380,29 +10374,29 @@ def rotate(self, angle: float, x: float, y: float, z: float, /) -> None: Notes ----- - Rotates the amount specified by the ``angle`` parameter. Angles must be - specified in radians (values from ``0`` to ``TWO_PI``), or they can be converted - from degrees to radians with the ``radians()`` function. + Rotates the amount specified by the `angle` parameter. Angles must be specified + in radians (values from `0` to `TWO_PI`), or they can be converted from degrees + to radians with the `radians()` function. The coordinates are always rotated around their relative position to the origin. Positive numbers rotate objects in a clockwise direction and negative numbers rotate in the couterclockwise direction. Transformations apply to everything that happens afterward, and subsequent calls to the function compound the - effect. For example, calling ``rotate(PI/2.0)`` once and then calling - ``rotate(PI/2.0)`` a second time is the same as a single ``rotate(PI)``. All - tranformations are reset when ``draw()`` begins again. + effect. For example, calling `rotate(PI/2.0)` once and then calling + `rotate(PI/2.0)` a second time is the same as a single `rotate(PI)`. All + tranformations are reset when `draw()` begins again. - Technically, ``rotate()`` multiplies the current transformation matrix by a + Technically, `rotate()` multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by - ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()``. + `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()`. - This method is the same as ``rotate()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``rotate()``. + This method is the same as `rotate()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `rotate()`. """ pass def rotate(self, *args): - """Rotates the amount specified by the ``angle`` parameter. + """Rotates the amount specified by the `angle` parameter. Underlying Processing method: PGraphics.rotate @@ -10432,29 +10426,29 @@ def rotate(self, *args): Notes ----- - Rotates the amount specified by the ``angle`` parameter. Angles must be - specified in radians (values from ``0`` to ``TWO_PI``), or they can be converted - from degrees to radians with the ``radians()`` function. + Rotates the amount specified by the `angle` parameter. Angles must be specified + in radians (values from `0` to `TWO_PI`), or they can be converted from degrees + to radians with the `radians()` function. The coordinates are always rotated around their relative position to the origin. Positive numbers rotate objects in a clockwise direction and negative numbers rotate in the couterclockwise direction. Transformations apply to everything that happens afterward, and subsequent calls to the function compound the - effect. For example, calling ``rotate(PI/2.0)`` once and then calling - ``rotate(PI/2.0)`` a second time is the same as a single ``rotate(PI)``. All - tranformations are reset when ``draw()`` begins again. + effect. For example, calling `rotate(PI/2.0)` once and then calling + `rotate(PI/2.0)` a second time is the same as a single `rotate(PI)`. All + tranformations are reset when `draw()` begins again. - Technically, ``rotate()`` multiplies the current transformation matrix by a + Technically, `rotate()` multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by - ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()``. + `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()`. - This method is the same as ``rotate()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``rotate()``. + This method is the same as `rotate()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `rotate()`. """ return self._instance.rotate(*args) def rotate_x(self, angle: float, /) -> None: - """Rotates around the x-axis the amount specified by the ``angle`` parameter. + """Rotates around the x-axis the amount specified by the `angle` parameter. Underlying Processing method: PGraphics.rotateX @@ -10467,25 +10461,25 @@ def rotate_x(self, angle: float, /) -> None: Notes ----- - Rotates around the x-axis the amount specified by the ``angle`` parameter. - Angles should be specified in radians (values from ``0`` to ``TWO_PI``) or - converted from degrees to radians with the ``radians()`` function. Coordinates - are always rotated around their relative position to the origin. Positive - numbers rotate in a clockwise direction and negative numbers rotate in a - counterclockwise direction. Transformations apply to everything that happens - after and subsequent calls to the function accumulates the effect. For example, - calling ``rotate_x(PI/2)`` and then ``rotate_x(PI/2)`` is the same as - ``rotate_x(PI)``. If ``rotate_x()`` is run within the ``draw()``, the - transformation is reset when the loop begins again. This function requires using - ``P3D`` as a third parameter to ``size()`` as shown in the example. + Rotates around the x-axis the amount specified by the `angle` parameter. Angles + should be specified in radians (values from `0` to `TWO_PI`) or converted from + degrees to radians with the `radians()` function. Coordinates are always rotated + around their relative position to the origin. Positive numbers rotate in a + clockwise direction and negative numbers rotate in a counterclockwise direction. + Transformations apply to everything that happens after and subsequent calls to + the function accumulates the effect. For example, calling `rotate_x(PI/2)` and + then `rotate_x(PI/2)` is the same as `rotate_x(PI)`. If `rotate_x()` is run + within the `draw()`, the transformation is reset when the loop begins again. + This function requires using `P3D` as a third parameter to `size()` as shown in + the example. - This method is the same as ``rotate_x()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``rotate_x()``. + This method is the same as `rotate_x()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `rotate_x()`. """ return self._instance.rotateX(angle) def rotate_y(self, angle: float, /) -> None: - """Rotates around the y-axis the amount specified by the ``angle`` parameter. + """Rotates around the y-axis the amount specified by the `angle` parameter. Underlying Processing method: PGraphics.rotateY @@ -10498,25 +10492,25 @@ def rotate_y(self, angle: float, /) -> None: Notes ----- - Rotates around the y-axis the amount specified by the ``angle`` parameter. - Angles should be specified in radians (values from ``0`` to ``TWO_PI``) or - converted from degrees to radians with the ``radians()`` function. Coordinates - are always rotated around their relative position to the origin. Positive - numbers rotate in a clockwise direction and negative numbers rotate in a - counterclockwise direction. Transformations apply to everything that happens - after and subsequent calls to the function accumulates the effect. For example, - calling ``rotate_y(PI/2)`` and then ``rotate_y(PI/2)`` is the same as - ``rotate_y(PI)``. If ``rotate_y()`` is run within the ``draw()``, the - transformation is reset when the loop begins again. This function requires using - ``P3D`` as a third parameter to ``size()`` as shown in the example. + Rotates around the y-axis the amount specified by the `angle` parameter. Angles + should be specified in radians (values from `0` to `TWO_PI`) or converted from + degrees to radians with the `radians()` function. Coordinates are always rotated + around their relative position to the origin. Positive numbers rotate in a + clockwise direction and negative numbers rotate in a counterclockwise direction. + Transformations apply to everything that happens after and subsequent calls to + the function accumulates the effect. For example, calling `rotate_y(PI/2)` and + then `rotate_y(PI/2)` is the same as `rotate_y(PI)`. If `rotate_y()` is run + within the `draw()`, the transformation is reset when the loop begins again. + This function requires using `P3D` as a third parameter to `size()` as shown in + the example. - This method is the same as ``rotate_y()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``rotate_y()``. + This method is the same as `rotate_y()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `rotate_y()`. """ return self._instance.rotateY(angle) def rotate_z(self, angle: float, /) -> None: - """Rotates around the z-axis the amount specified by the ``angle`` parameter. + """Rotates around the z-axis the amount specified by the `angle` parameter. Underlying Processing method: PGraphics.rotateZ @@ -10529,20 +10523,20 @@ def rotate_z(self, angle: float, /) -> None: Notes ----- - Rotates around the z-axis the amount specified by the ``angle`` parameter. - Angles should be specified in radians (values from ``0`` to ``TWO_PI``) or - converted from degrees to radians with the ``radians()`` function. Coordinates - are always rotated around their relative position to the origin. Positive - numbers rotate in a clockwise direction and negative numbers rotate in a - counterclockwise direction. Transformations apply to everything that happens - after and subsequent calls to the function accumulates the effect. For example, - calling ``rotate_z(PI/2)`` and then ``rotate_z(PI/2)`` is the same as - ``rotate_z(PI)``. If ``rotate_z()`` is run within the ``draw()``, the - transformation is reset when the loop begins again. This function requires using - ``P3D`` as a third parameter to ``size()`` as shown in the example. + Rotates around the z-axis the amount specified by the `angle` parameter. Angles + should be specified in radians (values from `0` to `TWO_PI`) or converted from + degrees to radians with the `radians()` function. Coordinates are always rotated + around their relative position to the origin. Positive numbers rotate in a + clockwise direction and negative numbers rotate in a counterclockwise direction. + Transformations apply to everything that happens after and subsequent calls to + the function accumulates the effect. For example, calling `rotate_z(PI/2)` and + then `rotate_z(PI/2)` is the same as `rotate_z(PI)`. If `rotate_z()` is run + within the `draw()`, the transformation is reset when the loop begins again. + This function requires using `P3D` as a third parameter to `size()` as shown in + the example. - This method is the same as ``rotate_z()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``rotate_z()``. + This method is the same as `rotate_z()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `rotate_z()`. """ return self._instance.rotateZ(angle) @@ -10563,8 +10557,8 @@ def saturation(self, rgb: int, /) -> float: Extracts the saturation value from a color. - This method is the same as ``saturation()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``saturation()``. + This method is the same as `saturation()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `saturation()`. """ return self._instance.saturation(rgb) @@ -10605,16 +10599,16 @@ def scale(self, s: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. Using this function with the ``z`` - parameter requires using ``P3D`` as the renderer. This function can be further - controlled with ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. Using this function with the `z` + parameter requires using `P3D` as the renderer. This function can be further + controlled with `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()`. - This method is the same as ``scale()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``scale()``. + This method is the same as `scale()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `scale()`. """ pass @@ -10655,16 +10649,16 @@ def scale(self, x: float, y: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. Using this function with the ``z`` - parameter requires using ``P3D`` as the renderer. This function can be further - controlled with ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. Using this function with the `z` + parameter requires using `P3D` as the renderer. This function can be further + controlled with `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()`. - This method is the same as ``scale()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``scale()``. + This method is the same as `scale()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `scale()`. """ pass @@ -10705,16 +10699,16 @@ def scale(self, x: float, y: float, z: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. Using this function with the ``z`` - parameter requires using ``P3D`` as the renderer. This function can be further - controlled with ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. Using this function with the `z` + parameter requires using `P3D` as the renderer. This function can be further + controlled with `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()`. - This method is the same as ``scale()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``scale()``. + This method is the same as `scale()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `scale()`. """ pass @@ -10754,16 +10748,16 @@ def scale(self, *args): Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. Using this function with the ``z`` - parameter requires using ``P3D`` as the renderer. This function can be further - controlled with ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. Using this function with the `z` + parameter requires using `P3D` as the renderer. This function can be further + controlled with `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()`. - This method is the same as ``scale()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``scale()``. + This method is the same as `scale()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `scale()`. """ return self._instance.scale(*args) @@ -10800,8 +10794,8 @@ def screen_x(self, x: float, y: float, /) -> float: Takes a three-dimensional X, Y, Z position and returns the X value for where it will appear on a (two-dimensional) screen. - This method is the same as ``screen_x()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``screen_x()``. + This method is the same as `screen_x()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `screen_x()`. """ pass @@ -10838,8 +10832,8 @@ def screen_x(self, x: float, y: float, z: float, /) -> float: Takes a three-dimensional X, Y, Z position and returns the X value for where it will appear on a (two-dimensional) screen. - This method is the same as ``screen_x()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``screen_x()``. + This method is the same as `screen_x()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `screen_x()`. """ pass @@ -10875,8 +10869,8 @@ def screen_x(self, *args): Takes a three-dimensional X, Y, Z position and returns the X value for where it will appear on a (two-dimensional) screen. - This method is the same as ``screen_x()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``screen_x()``. + This method is the same as `screen_x()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `screen_x()`. """ return self._instance.screenX(*args) @@ -10913,8 +10907,8 @@ def screen_y(self, x: float, y: float, /) -> float: Takes a three-dimensional X, Y, Z position and returns the Y value for where it will appear on a (two-dimensional) screen. - This method is the same as ``screen_y()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``screen_y()``. + This method is the same as `screen_y()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `screen_y()`. """ pass @@ -10951,8 +10945,8 @@ def screen_y(self, x: float, y: float, z: float, /) -> float: Takes a three-dimensional X, Y, Z position and returns the Y value for where it will appear on a (two-dimensional) screen. - This method is the same as ``screen_y()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``screen_y()``. + This method is the same as `screen_y()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `screen_y()`. """ pass @@ -10988,8 +10982,8 @@ def screen_y(self, *args): Takes a three-dimensional X, Y, Z position and returns the Y value for where it will appear on a (two-dimensional) screen. - This method is the same as ``screen_y()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``screen_y()``. + This method is the same as `screen_y()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `screen_y()`. """ return self._instance.screenY(*args) @@ -11017,14 +11011,172 @@ def screen_z(self, x: float, y: float, z: float, /) -> float: Takes a three-dimensional X, Y, Z position and returns the Z value for where it will appear on a (two-dimensional) screen. - This method is the same as ``screen_z()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``screen_z()``. + This method is the same as `screen_z()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `screen_z()`. """ return self._instance.screenZ(x, y, z) + @overload + def set_pixels(self, x: int, y: int, c: int, /) -> None: + """Changes the color of any pixel or writes an image directly into the Py5Graphics + object. + + Underlying Processing method: PGraphics.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Py5Graphics object + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the Py5Graphics + object. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `Py5Graphics.image_mode()`. + + Setting the color of a single pixel with `set_pixels(x, y)` is easy, but not as + fast as putting the data directly into `Py5Graphics.pixels[]`. The equivalent + statement to `set_pixels(x, y, 0)` using `Py5Graphics.pixels[]` is + `pixels[y*py5.width+x] = 0`. See the reference for `Py5Graphics.pixels[]` for + more information. + + This method is the same as `set_pixels()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `set_pixels()`. + """ + pass + + @overload + def set_pixels(self, x: int, y: int, img: Py5Image, /) -> None: + """Changes the color of any pixel or writes an image directly into the Py5Graphics + object. + + Underlying Processing method: PGraphics.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Py5Graphics object + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the Py5Graphics + object. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `Py5Graphics.image_mode()`. + + Setting the color of a single pixel with `set_pixels(x, y)` is easy, but not as + fast as putting the data directly into `Py5Graphics.pixels[]`. The equivalent + statement to `set_pixels(x, y, 0)` using `Py5Graphics.pixels[]` is + `pixels[y*py5.width+x] = 0`. See the reference for `Py5Graphics.pixels[]` for + more information. + + This method is the same as `set_pixels()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `set_pixels()`. + """ + pass + + def set_pixels(self, *args): + """Changes the color of any pixel or writes an image directly into the Py5Graphics + object. + + Underlying Processing method: PGraphics.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Py5Graphics object + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the Py5Graphics + object. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `Py5Graphics.image_mode()`. + + Setting the color of a single pixel with `set_pixels(x, y)` is easy, but not as + fast as putting the data directly into `Py5Graphics.pixels[]`. The equivalent + statement to `set_pixels(x, y, 0)` using `Py5Graphics.pixels[]` is + `pixels[y*py5.width+x] = 0`. See the reference for `Py5Graphics.pixels[]` for + more information. + + This method is the same as `set_pixels()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `set_pixels()`. + """ + return self._instance.set(*args) + @overload def set_matrix(self, source: npt.NDArray[np.floating], /) -> None: - """Set the current matrix to the one specified through the parameter ``source``. + """Set the current matrix to the one specified through the parameter `source`. Underlying Processing method: PGraphics.setMatrix @@ -11037,19 +11189,19 @@ def set_matrix(self, source: npt.NDArray[np.floating], /) -> None: Notes ----- - Set the current matrix to the one specified through the parameter ``source``. - Inside the Processing code it will call ``Py5Graphics.reset_matrix()`` followed - by ``Py5Graphics.apply_matrix()``. This will be very slow because - ``Py5Graphics.apply_matrix()`` will try to calculate the inverse of the - transform, so avoid it whenever possible. + Set the current matrix to the one specified through the parameter `source`. + Inside the Processing code it will call `Py5Graphics.reset_matrix()` followed by + `Py5Graphics.apply_matrix()`. This will be very slow because + `Py5Graphics.apply_matrix()` will try to calculate the inverse of the transform, + so avoid it whenever possible. - This method is the same as ``set_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``set_matrix()``. + This method is the same as `set_matrix()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `set_matrix()`. """ pass def set_matrix(self, *args): - """Set the current matrix to the one specified through the parameter ``source``. + """Set the current matrix to the one specified through the parameter `source`. Underlying Processing method: PGraphics.setMatrix @@ -11062,14 +11214,14 @@ def set_matrix(self, *args): Notes ----- - Set the current matrix to the one specified through the parameter ``source``. - Inside the Processing code it will call ``Py5Graphics.reset_matrix()`` followed - by ``Py5Graphics.apply_matrix()``. This will be very slow because - ``Py5Graphics.apply_matrix()`` will try to calculate the inverse of the - transform, so avoid it whenever possible. + Set the current matrix to the one specified through the parameter `source`. + Inside the Processing code it will call `Py5Graphics.reset_matrix()` followed by + `Py5Graphics.apply_matrix()`. This will be very slow because + `Py5Graphics.apply_matrix()` will try to calculate the inverse of the transform, + so avoid it whenever possible. - This method is the same as ``set_matrix()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``set_matrix()``. + This method is the same as `set_matrix()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `set_matrix()`. """ return self._instance.setMatrix(*args) @@ -11099,11 +11251,11 @@ def shader(self, shader: Py5Shader, /) -> None: Notes ----- - Applies the shader specified by the parameters. It's compatible with the ``P2D`` - and ``P3D`` renderers, but not with the default renderer. + Applies the shader specified by the parameters. It's compatible with the `P2D` + and `P3D` renderers, but not with the default renderer. - This method is the same as ``shader()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``shader()``. + This method is the same as `shader()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `shader()`. """ pass @@ -11133,11 +11285,11 @@ def shader(self, shader: Py5Shader, kind: int, /) -> None: Notes ----- - Applies the shader specified by the parameters. It's compatible with the ``P2D`` - and ``P3D`` renderers, but not with the default renderer. + Applies the shader specified by the parameters. It's compatible with the `P2D` + and `P3D` renderers, but not with the default renderer. - This method is the same as ``shader()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``shader()``. + This method is the same as `shader()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `shader()`. """ pass @@ -11166,11 +11318,11 @@ def shader(self, *args): Notes ----- - Applies the shader specified by the parameters. It's compatible with the ``P2D`` - and ``P3D`` renderers, but not with the default renderer. + Applies the shader specified by the parameters. It's compatible with the `P2D` + and `P3D` renderers, but not with the default renderer. - This method is the same as ``shader()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``shader()``. + This method is the same as `shader()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `shader()`. """ return self._instance.shader(*args) @@ -11218,14 +11370,14 @@ def shape(self, shape: Py5Shape, /) -> None: Draws shapes to the Py5Graphics drawing surface. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and - custom-created shapes. The ``shape`` parameter specifies the shape to display - and the coordinate parameters define the location of the shape from its upper- - left corner. The shape is displayed at its original size unless the ``c`` and - ``d`` parameters specify a different size. The ``Py5Graphics.shape_mode()`` - function can be used to change the way these parameters are interpreted. + custom-created shapes. The `shape` parameter specifies the shape to display and + the coordinate parameters define the location of the shape from its upper-left + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `Py5Graphics.shape_mode()` function can + be used to change the way these parameters are interpreted. - This method is the same as ``shape()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``shape()``. + This method is the same as `shape()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `shape()`. """ pass @@ -11273,14 +11425,14 @@ def shape(self, shape: Py5Shape, x: float, y: float, /) -> None: Draws shapes to the Py5Graphics drawing surface. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and - custom-created shapes. The ``shape`` parameter specifies the shape to display - and the coordinate parameters define the location of the shape from its upper- - left corner. The shape is displayed at its original size unless the ``c`` and - ``d`` parameters specify a different size. The ``Py5Graphics.shape_mode()`` - function can be used to change the way these parameters are interpreted. + custom-created shapes. The `shape` parameter specifies the shape to display and + the coordinate parameters define the location of the shape from its upper-left + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `Py5Graphics.shape_mode()` function can + be used to change the way these parameters are interpreted. - This method is the same as ``shape()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``shape()``. + This method is the same as `shape()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `shape()`. """ pass @@ -11329,14 +11481,14 @@ def shape(self, shape: Py5Shape, a: float, Draws shapes to the Py5Graphics drawing surface. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and - custom-created shapes. The ``shape`` parameter specifies the shape to display - and the coordinate parameters define the location of the shape from its upper- - left corner. The shape is displayed at its original size unless the ``c`` and - ``d`` parameters specify a different size. The ``Py5Graphics.shape_mode()`` - function can be used to change the way these parameters are interpreted. + custom-created shapes. The `shape` parameter specifies the shape to display and + the coordinate parameters define the location of the shape from its upper-left + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `Py5Graphics.shape_mode()` function can + be used to change the way these parameters are interpreted. - This method is the same as ``shape()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``shape()``. + This method is the same as `shape()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `shape()`. """ pass @@ -11383,14 +11535,14 @@ def shape(self, *args): Draws shapes to the Py5Graphics drawing surface. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and - custom-created shapes. The ``shape`` parameter specifies the shape to display - and the coordinate parameters define the location of the shape from its upper- - left corner. The shape is displayed at its original size unless the ``c`` and - ``d`` parameters specify a different size. The ``Py5Graphics.shape_mode()`` - function can be used to change the way these parameters are interpreted. + custom-created shapes. The `shape` parameter specifies the shape to display and + the coordinate parameters define the location of the shape from its upper-left + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `Py5Graphics.shape_mode()` function can + be used to change the way these parameters are interpreted. - This method is the same as ``shape()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``shape()``. + This method is the same as `shape()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `shape()`. """ return self._instance.shape(*args) @@ -11409,24 +11561,23 @@ def shape_mode(self, mode: int, /) -> None: ----- Modifies the location from which shapes draw. The default mode is - ``shape_mode(CORNER)``, which specifies the location to be the upper left corner - of the shape and uses the third and fourth parameters of ``Py5Graphics.shape()`` - to specify the width and height. The syntax ``shape_mode(CORNERS)`` uses the - first and second parameters of ``Py5Graphics.shape()`` to set the location of - one corner and uses the third and fourth parameters to set the opposite corner. - The syntax ``shape_mode(CENTER)`` draws the shape from its center point and uses - the third and forth parameters of ``Py5Graphics.shape()`` to specify the width - and height. The parameter must be written in ALL CAPS because Python is a case - sensitive language. - - This method is the same as ``shape_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``shape_mode()``. + `shape_mode(CORNER)`, which specifies the location to be the upper left corner + of the shape and uses the third and fourth parameters of `Py5Graphics.shape()` + to specify the width and height. The syntax `shape_mode(CORNERS)` uses the first + and second parameters of `Py5Graphics.shape()` to set the location of one corner + and uses the third and fourth parameters to set the opposite corner. The syntax + `shape_mode(CENTER)` draws the shape from its center point and uses the third + and forth parameters of `Py5Graphics.shape()` to specify the width and height. + The parameter must be written in ALL CAPS because Python is a case sensitive + language. + + This method is the same as `shape_mode()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `shape_mode()`. """ return self._instance.shapeMode(mode) def shear_x(self, angle: float, /) -> None: - """Shears a shape around the x-axis the amount specified by the ``angle`` - parameter. + """Shears a shape around the x-axis the amount specified by the `angle` parameter. Underlying Processing method: PGraphics.shearX @@ -11439,27 +11590,25 @@ def shear_x(self, angle: float, /) -> None: Notes ----- - Shears a shape around the x-axis the amount specified by the ``angle`` - parameter. Angles should be specified in radians (values from ``0`` to - ``TWO_PI``) or converted to radians with the ``radians()`` function. Objects are - always sheared around their relative position to the origin and positive numbers - shear objects in a clockwise direction. Transformations apply to everything that - happens after and subsequent calls to the function accumulates the effect. For - example, calling ``shear_x(PI/2)`` and then ``shear_x(PI/2)`` is the same as - ``shear_x(PI)``. + Shears a shape around the x-axis the amount specified by the `angle` parameter. + Angles should be specified in radians (values from `0` to `TWO_PI`) or converted + to radians with the `radians()` function. Objects are always sheared around + their relative position to the origin and positive numbers shear objects in a + clockwise direction. Transformations apply to everything that happens after and + subsequent calls to the function accumulates the effect. For example, calling + `shear_x(PI/2)` and then `shear_x(PI/2)` is the same as `shear_x(PI)`. - Technically, ``shear_x()`` multiplies the current transformation matrix by a + Technically, `shear_x()` multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the - ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()`` functions. + `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()` functions. - This method is the same as ``shear_x()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``shear_x()``. + This method is the same as `shear_x()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `shear_x()`. """ return self._instance.shearX(angle) def shear_y(self, angle: float, /) -> None: - """Shears a shape around the y-axis the amount specified by the ``angle`` - parameter. + """Shears a shape around the y-axis the amount specified by the `angle` parameter. Underlying Processing method: PGraphics.shearY @@ -11472,21 +11621,20 @@ def shear_y(self, angle: float, /) -> None: Notes ----- - Shears a shape around the y-axis the amount specified by the ``angle`` - parameter. Angles should be specified in radians (values from ``0`` to - ``TWO_PI``) or converted to radians with the ``radians()`` function. Objects are - always sheared around their relative position to the origin and positive numbers - shear objects in a clockwise direction. Transformations apply to everything that - happens after and subsequent calls to the function accumulates the effect. For - example, calling ``shear_y(PI/2)`` and then ``shear_y(PI/2)`` is the same as - ``shear_y(PI)``. + Shears a shape around the y-axis the amount specified by the `angle` parameter. + Angles should be specified in radians (values from `0` to `TWO_PI`) or converted + to radians with the `radians()` function. Objects are always sheared around + their relative position to the origin and positive numbers shear objects in a + clockwise direction. Transformations apply to everything that happens after and + subsequent calls to the function accumulates the effect. For example, calling + `shear_y(PI/2)` and then `shear_y(PI/2)` is the same as `shear_y(PI)`. - Technically, ``shear_y()`` multiplies the current transformation matrix by a + Technically, `shear_y()` multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the - ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()`` functions. + `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()` functions. - This method is the same as ``shear_y()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``shear_y()``. + This method is the same as `shear_y()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `shear_y()`. """ return self._instance.shearY(angle) @@ -11505,11 +11653,11 @@ def shininess(self, shine: float, /) -> None: ----- Sets the amount of gloss in the surface of shapes. Use in combination with - ``Py5Graphics.ambient()``, ``Py5Graphics.specular()``, and - ``Py5Graphics.emissive()`` to set the material properties of shapes. + `Py5Graphics.ambient()`, `Py5Graphics.specular()`, and `Py5Graphics.emissive()` + to set the material properties of shapes. - This method is the same as ``shininess()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``shininess()``. + This method is the same as `shininess()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `shininess()`. """ return self._instance.shininess(shine) @@ -11537,25 +11685,25 @@ def smooth(self) -> None: ----- Draws all geometry with smooth (anti-aliased) edges. This behavior is the - default, so ``smooth()`` only needs to be used when a program needs to set the - smoothing in a different way. The ``level`` parameter increases the amount of + default, so `smooth()` only needs to be used when a program needs to set the + smoothing in a different way. The `level` parameter increases the amount of smoothness. This is the level of over sampling applied to the graphics buffer. - With the ``P2D`` and ``P3D`` renderers, ``smooth(2)`` is the default, this is - called "2x anti-aliasing." The code ``smooth(4)`` is used for 4x anti-aliasing - and ``smooth(8)`` is specified for "8x anti-aliasing." The maximum anti-aliasing - level is determined by the hardware of the machine that is running the software, - so ``smooth(4)`` and ``smooth(8)`` will not work with every computer. + With the `P2D` and `P3D` renderers, `smooth(2)` is the default, this is called + "2x anti-aliasing." The code `smooth(4)` is used for 4x anti-aliasing and + `smooth(8)` is specified for "8x anti-aliasing." The maximum anti-aliasing level + is determined by the hardware of the machine that is running the software, so + `smooth(4)` and `smooth(8)` will not work with every computer. - The default renderer uses ``smooth(3)`` by default. This is bicubic smoothing. - The other option for the default renderer is ``smooth(2)``, which is bilinear + The default renderer uses `smooth(3)` by default. This is bicubic smoothing. The + other option for the default renderer is `smooth(2)`, which is bilinear smoothing. - The ``smooth()`` method can only be run once for a ``Py5Graphics`` object and it - must be called right after the object is created with ``create_graphics()`` and - before ``Py5Graphics.begin_draw()``. + The `smooth()` method can only be run once for a `Py5Graphics` object and it + must be called right after the object is created with `create_graphics()` and + before `Py5Graphics.begin_draw()`. - This method is the same as ``smooth()`` but linked to a ``Py5Graphics`` object. + This method is the same as `smooth()` but linked to a `Py5Graphics` object. """ pass @@ -11583,25 +11731,25 @@ def smooth(self, quality: int, /) -> None: ----- Draws all geometry with smooth (anti-aliased) edges. This behavior is the - default, so ``smooth()`` only needs to be used when a program needs to set the - smoothing in a different way. The ``level`` parameter increases the amount of + default, so `smooth()` only needs to be used when a program needs to set the + smoothing in a different way. The `level` parameter increases the amount of smoothness. This is the level of over sampling applied to the graphics buffer. - With the ``P2D`` and ``P3D`` renderers, ``smooth(2)`` is the default, this is - called "2x anti-aliasing." The code ``smooth(4)`` is used for 4x anti-aliasing - and ``smooth(8)`` is specified for "8x anti-aliasing." The maximum anti-aliasing - level is determined by the hardware of the machine that is running the software, - so ``smooth(4)`` and ``smooth(8)`` will not work with every computer. + With the `P2D` and `P3D` renderers, `smooth(2)` is the default, this is called + "2x anti-aliasing." The code `smooth(4)` is used for 4x anti-aliasing and + `smooth(8)` is specified for "8x anti-aliasing." The maximum anti-aliasing level + is determined by the hardware of the machine that is running the software, so + `smooth(4)` and `smooth(8)` will not work with every computer. - The default renderer uses ``smooth(3)`` by default. This is bicubic smoothing. - The other option for the default renderer is ``smooth(2)``, which is bilinear + The default renderer uses `smooth(3)` by default. This is bicubic smoothing. The + other option for the default renderer is `smooth(2)`, which is bilinear smoothing. - The ``smooth()`` method can only be run once for a ``Py5Graphics`` object and it - must be called right after the object is created with ``create_graphics()`` and - before ``Py5Graphics.begin_draw()``. + The `smooth()` method can only be run once for a `Py5Graphics` object and it + must be called right after the object is created with `create_graphics()` and + before `Py5Graphics.begin_draw()`. - This method is the same as ``smooth()`` but linked to a ``Py5Graphics`` object. + This method is the same as `smooth()` but linked to a `Py5Graphics` object. """ pass @@ -11628,25 +11776,25 @@ def smooth(self, *args): ----- Draws all geometry with smooth (anti-aliased) edges. This behavior is the - default, so ``smooth()`` only needs to be used when a program needs to set the - smoothing in a different way. The ``level`` parameter increases the amount of + default, so `smooth()` only needs to be used when a program needs to set the + smoothing in a different way. The `level` parameter increases the amount of smoothness. This is the level of over sampling applied to the graphics buffer. - With the ``P2D`` and ``P3D`` renderers, ``smooth(2)`` is the default, this is - called "2x anti-aliasing." The code ``smooth(4)`` is used for 4x anti-aliasing - and ``smooth(8)`` is specified for "8x anti-aliasing." The maximum anti-aliasing - level is determined by the hardware of the machine that is running the software, - so ``smooth(4)`` and ``smooth(8)`` will not work with every computer. + With the `P2D` and `P3D` renderers, `smooth(2)` is the default, this is called + "2x anti-aliasing." The code `smooth(4)` is used for 4x anti-aliasing and + `smooth(8)` is specified for "8x anti-aliasing." The maximum anti-aliasing level + is determined by the hardware of the machine that is running the software, so + `smooth(4)` and `smooth(8)` will not work with every computer. - The default renderer uses ``smooth(3)`` by default. This is bicubic smoothing. - The other option for the default renderer is ``smooth(2)``, which is bilinear + The default renderer uses `smooth(3)` by default. This is bicubic smoothing. The + other option for the default renderer is `smooth(2)`, which is bilinear smoothing. - The ``smooth()`` method can only be run once for a ``Py5Graphics`` object and it - must be called right after the object is created with ``create_graphics()`` and - before ``Py5Graphics.begin_draw()``. + The `smooth()` method can only be run once for a `Py5Graphics` object and it + must be called right after the object is created with `create_graphics()` and + before `Py5Graphics.begin_draw()`. - This method is the same as ``smooth()`` but linked to a ``Py5Graphics`` object. + This method is the same as `smooth()` but linked to a `Py5Graphics` object. """ return self._instance.smooth(*args) @@ -11691,11 +11839,11 @@ def specular(self, gray: float, /) -> None: Py5Graphics drawing surface, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a diffuse light). Use in combination with - ``Py5Graphics.emissive()``, ``Py5Graphics.ambient()``, and - ``Py5Graphics.shininess()`` to set the material properties of shapes. + `Py5Graphics.emissive()`, `Py5Graphics.ambient()`, and `Py5Graphics.shininess()` + to set the material properties of shapes. - This method is the same as ``specular()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``specular()``. + This method is the same as `specular()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `specular()`. """ pass @@ -11740,11 +11888,11 @@ def specular(self, v1: float, v2: float, v3: float, /) -> None: Py5Graphics drawing surface, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a diffuse light). Use in combination with - ``Py5Graphics.emissive()``, ``Py5Graphics.ambient()``, and - ``Py5Graphics.shininess()`` to set the material properties of shapes. + `Py5Graphics.emissive()`, `Py5Graphics.ambient()`, and `Py5Graphics.shininess()` + to set the material properties of shapes. - This method is the same as ``specular()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``specular()``. + This method is the same as `specular()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `specular()`. """ pass @@ -11789,11 +11937,11 @@ def specular(self, rgb: int, /) -> None: Py5Graphics drawing surface, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a diffuse light). Use in combination with - ``Py5Graphics.emissive()``, ``Py5Graphics.ambient()``, and - ``Py5Graphics.shininess()`` to set the material properties of shapes. + `Py5Graphics.emissive()`, `Py5Graphics.ambient()`, and `Py5Graphics.shininess()` + to set the material properties of shapes. - This method is the same as ``specular()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``specular()``. + This method is the same as `specular()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `specular()`. """ pass @@ -11838,11 +11986,11 @@ def specular(self, *args): Py5Graphics drawing surface, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a diffuse light). Use in combination with - ``Py5Graphics.emissive()``, ``Py5Graphics.ambient()``, and - ``Py5Graphics.shininess()`` to set the material properties of shapes. + `Py5Graphics.emissive()`, `Py5Graphics.ambient()`, and `Py5Graphics.shininess()` + to set the material properties of shapes. - This method is the same as ``specular()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``specular()``. + This method is the same as `specular()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `specular()`. """ return self._instance.specular(*args) @@ -11862,8 +12010,8 @@ def sphere(self, r: float, /) -> None: A sphere is a hollow ball made from tessellated triangles. - This method is the same as ``sphere()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``sphere()``. + This method is the same as `sphere()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `sphere()`. """ return self._instance.sphere(r) @@ -11899,18 +12047,18 @@ def sphere_detail(self, res: int, /) -> None: Controls the detail used to render a sphere by adjusting the number of vertices of the sphere mesh. The default resolution is 30, which creates a fairly - detailed sphere definition with vertices every ``360/30 = 12`` degrees. If - you're going to render a great number of spheres per frame, it is advised to - reduce the level of detail using this function. The setting stays active until - ``sphere_detail()`` is called again with a new parameter and so should *not* be - called prior to every ``Py5Graphics.sphere()`` statement, unless you wish to + detailed sphere definition with vertices every `360/30 = 12` degrees. If you're + going to render a great number of spheres per frame, it is advised to reduce the + level of detail using this function. The setting stays active until + `sphere_detail()` is called again with a new parameter and so should *not* be + called prior to every `Py5Graphics.sphere()` statement, unless you wish to render spheres with different settings, e.g. using less detail for smaller spheres or ones further away from the camera. To control the detail of the horizontal and vertical resolution independently, use the version of the functions with two parameters. - This method is the same as ``sphere_detail()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``sphere_detail()``. + This method is the same as `sphere_detail()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `sphere_detail()`. """ pass @@ -11946,18 +12094,18 @@ def sphere_detail(self, ures: int, vres: int, /) -> None: Controls the detail used to render a sphere by adjusting the number of vertices of the sphere mesh. The default resolution is 30, which creates a fairly - detailed sphere definition with vertices every ``360/30 = 12`` degrees. If - you're going to render a great number of spheres per frame, it is advised to - reduce the level of detail using this function. The setting stays active until - ``sphere_detail()`` is called again with a new parameter and so should *not* be - called prior to every ``Py5Graphics.sphere()`` statement, unless you wish to + detailed sphere definition with vertices every `360/30 = 12` degrees. If you're + going to render a great number of spheres per frame, it is advised to reduce the + level of detail using this function. The setting stays active until + `sphere_detail()` is called again with a new parameter and so should *not* be + called prior to every `Py5Graphics.sphere()` statement, unless you wish to render spheres with different settings, e.g. using less detail for smaller spheres or ones further away from the camera. To control the detail of the horizontal and vertical resolution independently, use the version of the functions with two parameters. - This method is the same as ``sphere_detail()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``sphere_detail()``. + This method is the same as `sphere_detail()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `sphere_detail()`. """ pass @@ -11992,18 +12140,18 @@ def sphere_detail(self, *args): Controls the detail used to render a sphere by adjusting the number of vertices of the sphere mesh. The default resolution is 30, which creates a fairly - detailed sphere definition with vertices every ``360/30 = 12`` degrees. If - you're going to render a great number of spheres per frame, it is advised to - reduce the level of detail using this function. The setting stays active until - ``sphere_detail()`` is called again with a new parameter and so should *not* be - called prior to every ``Py5Graphics.sphere()`` statement, unless you wish to + detailed sphere definition with vertices every `360/30 = 12` degrees. If you're + going to render a great number of spheres per frame, it is advised to reduce the + level of detail using this function. The setting stays active until + `sphere_detail()` is called again with a new parameter and so should *not* be + called prior to every `Py5Graphics.sphere()` statement, unless you wish to render spheres with different settings, e.g. using less detail for smaller spheres or ones further away from the camera. To control the detail of the horizontal and vertical resolution independently, use the version of the functions with two parameters. - This method is the same as ``sphere_detail()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``sphere_detail()``. + This method is the same as `sphere_detail()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `sphere_detail()`. """ return self._instance.sphereDetail(*args) @@ -12064,15 +12212,15 @@ def spot_light( Notes ----- - Adds a spot light. The ``v1``, ``v2``, and ``v3`` parameters are interpreted as - either RGB or HSB values, depending on the current color mode. The ``x``, ``y``, - and ``z`` parameters specify the position of the light and ``nx``, ``ny``, - ``nz`` specify the direction of light. The ``angle`` parameter affects angle of - the spotlight cone, while ``concentration`` sets the bias of light focusing - toward the center of that cone. + Adds a spot light. The `v1`, `v2`, and `v3` parameters are interpreted as either + RGB or HSB values, depending on the current color mode. The `x`, `y`, and `z` + parameters specify the position of the light and `nx`, `ny`, `nz` specify the + direction of light. The `angle` parameter affects angle of the spotlight cone, + while `concentration` sets the bias of light focusing toward the center of that + cone. - This method is the same as ``spot_light()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``spot_light()``. + This method is the same as `spot_light()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `spot_light()`. """ return self._instance.spotLight( v1, v2, v3, x, y, z, nx, ny, nz, angle, concentration) @@ -12101,10 +12249,10 @@ def square(self, x: float, y: float, extent: float, /) -> None: shape with every angle at ninety degrees and each side is the same length. By default, the first two parameters set the location of the upper-left corner, the third sets the width and height. The way these parameters are interpreted, - however, may be changed with the ``Py5Graphics.rect_mode()`` function. + however, may be changed with the `Py5Graphics.rect_mode()` function. - This method is the same as ``square()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``square()``. + This method is the same as `square()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `square()`. """ return self._instance.square(x, y, extent) @@ -12152,34 +12300,34 @@ def stroke(self, gray: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``Py5Graphics.color_mode()``. The default color space is RGB, with each value in + `Py5Graphics.color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``Py5Graphics.hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `Py5Graphics.hint()` documentation for more details. - This method is the same as ``stroke()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``stroke()``. + This method is the same as `stroke()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `stroke()`. """ pass @@ -12227,34 +12375,34 @@ def stroke(self, gray: float, alpha: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``Py5Graphics.color_mode()``. The default color space is RGB, with each value in + `Py5Graphics.color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``Py5Graphics.hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `Py5Graphics.hint()` documentation for more details. - This method is the same as ``stroke()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``stroke()``. + This method is the same as `stroke()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `stroke()`. """ pass @@ -12302,34 +12450,34 @@ def stroke(self, v1: float, v2: float, v3: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``Py5Graphics.color_mode()``. The default color space is RGB, with each value in + `Py5Graphics.color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``Py5Graphics.hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `Py5Graphics.hint()` documentation for more details. - This method is the same as ``stroke()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``stroke()``. + This method is the same as `stroke()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `stroke()`. """ pass @@ -12377,34 +12525,34 @@ def stroke(self, v1: float, v2: float, v3: float, alpha: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``Py5Graphics.color_mode()``. The default color space is RGB, with each value in + `Py5Graphics.color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``Py5Graphics.hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `Py5Graphics.hint()` documentation for more details. - This method is the same as ``stroke()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``stroke()``. + This method is the same as `stroke()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `stroke()`. """ pass @@ -12452,34 +12600,34 @@ def stroke(self, rgb: int, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``Py5Graphics.color_mode()``. The default color space is RGB, with each value in + `Py5Graphics.color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``Py5Graphics.hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `Py5Graphics.hint()` documentation for more details. - This method is the same as ``stroke()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``stroke()``. + This method is the same as `stroke()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `stroke()`. """ pass @@ -12527,34 +12675,34 @@ def stroke(self, rgb: int, alpha: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``Py5Graphics.color_mode()``. The default color space is RGB, with each value in + `Py5Graphics.color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``Py5Graphics.hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `Py5Graphics.hint()` documentation for more details. - This method is the same as ``stroke()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``stroke()``. + This method is the same as `stroke()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `stroke()`. """ pass @@ -12602,34 +12750,34 @@ def stroke(self, *args): Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``Py5Graphics.color_mode()``. The default color space is RGB, with each value in + `Py5Graphics.color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``Py5Graphics.hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `Py5Graphics.hint()` documentation for more details. - This method is the same as ``stroke()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``stroke()``. + This method is the same as `stroke()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `stroke()`. """ return self._instance.stroke(*args) @@ -12649,13 +12797,13 @@ def stroke_cap(self, cap: int, /) -> None: Sets the style for rendering line endings. These ends are either squared, extended, or rounded, each of which specified with the corresponding parameters: - ``SQUARE``, ``PROJECT``, and ``ROUND``. The default cap is ``ROUND``. + `SQUARE`, `PROJECT`, and `ROUND`. The default cap is `ROUND`. - To make ``Py5Graphics.point()`` appear square, use ``stroke_cap(PROJECT)``. - Using ``stroke_cap(SQUARE)`` (no cap) causes points to become invisible. + To make `Py5Graphics.point()` appear square, use `stroke_cap(PROJECT)`. Using + `stroke_cap(SQUARE)` (no cap) causes points to become invisible. - This method is the same as ``stroke_cap()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``stroke_cap()``. + This method is the same as `stroke_cap()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `stroke_cap()`. """ return self._instance.strokeCap(cap) @@ -12675,10 +12823,10 @@ def stroke_join(self, join: int, /) -> None: Sets the style of the joints which connect line segments. These joints are either mitered, beveled, or rounded and specified with the corresponding - parameters ``MITER``, ``BEVEL``, and ``ROUND``. The default joint is ``MITER``. + parameters `MITER`, `BEVEL`, and `ROUND`. The default joint is `MITER`. - This method is the same as ``stroke_join()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``stroke_join()``. + This method is the same as `stroke_join()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `stroke_join()`. """ return self._instance.strokeJoin(join) @@ -12700,14 +12848,14 @@ def stroke_weight(self, weight: float, /) -> None: Sets the width of the stroke used for lines, points, and the border around shapes. All widths are set in units of pixels. - Using ``Py5Graphics.point()`` with ``strokeWeight(1)`` or smaller may draw - nothing to the Py5Graphics drawing surface, depending on the graphics settings - of the computer. Workarounds include setting the pixel using the - ``Py5Graphics.pixels[]`` or ``Py5Graphics.np_pixels[]`` arrays or drawing the - point using either ``Py5Graphics.circle()`` or ``Py5Graphics.square()``. + Using `Py5Graphics.point()` with `strokeWeight(1)` or smaller may draw nothing + to the Py5Graphics drawing surface, depending on the graphics settings of the + computer. Workarounds include setting the pixel using the `Py5Graphics.pixels[]` + or `Py5Graphics.np_pixels[]` arrays or drawing the point using either + `Py5Graphics.circle()` or `Py5Graphics.square()`. - This method is the same as ``stroke_weight()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``stroke_weight()``. + This method is the same as `stroke_weight()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `stroke_weight()`. """ return self._instance.strokeWeight(weight) @@ -12785,23 +12933,23 @@ def text(self, c: chr, x: float, y: float, /) -> None: Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -12879,23 +13027,23 @@ def text(self, c: chr, x: float, y: float, z: float, /) -> None: Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -12974,23 +13122,23 @@ def text(self, chars: list[chr], start: int, Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -13069,23 +13217,23 @@ def text(self, chars: list[chr], start: int, Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -13163,23 +13311,23 @@ def text(self, num: float, x: float, y: float, /) -> None: Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -13257,23 +13405,23 @@ def text(self, num: float, x: float, y: float, z: float, /) -> None: Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -13351,23 +13499,23 @@ def text(self, num: int, x: float, y: float, /) -> None: Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -13445,23 +13593,23 @@ def text(self, num: int, x: float, y: float, z: float, /) -> None: Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -13539,23 +13687,23 @@ def text(self, str: str, x: float, y: float, /) -> None: Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -13633,23 +13781,23 @@ def text(self, str: str, x: float, y: float, z: float, /) -> None: Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -13728,23 +13876,23 @@ def text(self, str: str, x1: float, y1: float, Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ pass @@ -13822,23 +13970,23 @@ def text(self, *args): Draws text to the Py5Graphics drawing surface. Displays the information specified in the first parameter on the drawing surface in the position specified by the additional parameters. A default font will be used unless a - font is set with the ``Py5Graphics.text_font()`` function and a default size - will be used unless a font is set with ``Py5Graphics.text_size()``. Change the - color of the text with the ``Py5Graphics.fill()`` function. The text displays in - relation to the ``Py5Graphics.text_align()`` function, which gives the option to - draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``Py5Graphics.rect_mode()`` setting. Text that + font is set with the `Py5Graphics.text_font()` function and a default size will + be used unless a font is set with `Py5Graphics.text_size()`. Change the color of + the text with the `Py5Graphics.fill()` function. The text displays in relation + to the `Py5Graphics.text_align()` function, which gives the option to draw to + the left, right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `Py5Graphics.rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``Py5Graphics.text_font()``. In that case, a generic sans-serif font will be - used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `Py5Graphics.text_font()`. In that case, a generic sans-serif font will be used + instead. - This method is the same as ``text()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``text()``. + This method is the same as `text()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `text()`. """ return self._instance.text(*args) @@ -13868,32 +14016,31 @@ def text_align(self, align_x: int, /) -> None: Notes ----- - Sets the current alignment for drawing text. The parameters ``LEFT``, - ``CENTER``, and ``RIGHT`` set the display characteristics of the letters in - relation to the values for the ``x`` and ``y`` parameters of the - ``Py5Graphics.text()`` function. + Sets the current alignment for drawing text. The parameters `LEFT`, `CENTER`, + and `RIGHT` set the display characteristics of the letters in relation to the + values for the `x` and `y` parameters of the `Py5Graphics.text()` function. An optional second parameter can be used to vertically align the text. - ``BASELINE`` is the default, and the vertical alignment will be reset to - ``BASELINE`` if the second parameter is not used. The ``TOP`` and ``CENTER`` - parameters are straightforward. The ``BOTTOM`` parameter offsets the line based - on the current ``Py5Graphics.text_descent()``. For multiple lines, the final - line will be aligned to the bottom, with the previous lines appearing above it. - - When using ``Py5Graphics.text()`` with width and height parameters, ``BASELINE`` - is ignored, and treated as ``TOP``. (Otherwise, text would by default draw - outside the box, since ``BASELINE`` is the default setting. ``BASELINE`` is not - a useful drawing mode for text drawn in a rectangle.) - - The vertical alignment is based on the value of ``Py5Graphics.text_ascent()``, + `BASELINE` is the default, and the vertical alignment will be reset to + `BASELINE` if the second parameter is not used. The `TOP` and `CENTER` + parameters are straightforward. The `BOTTOM` parameter offsets the line based on + the current `Py5Graphics.text_descent()`. For multiple lines, the final line + will be aligned to the bottom, with the previous lines appearing above it. + + When using `Py5Graphics.text()` with width and height parameters, `BASELINE` is + ignored, and treated as `TOP`. (Otherwise, text would by default draw outside + the box, since `BASELINE` is the default setting. `BASELINE` is not a useful + drawing mode for text drawn in a rectangle.) + + The vertical alignment is based on the value of `Py5Graphics.text_ascent()`, which many fonts do not specify correctly. It may be necessary to use a hack and offset by a few pixels by hand so that the offset looks correct. To do this as - less of a hack, use some percentage of ``Py5Graphics.text_ascent()`` or - ``Py5Graphics.text_descent()`` so that the hack works even if you change the - size of the font. + less of a hack, use some percentage of `Py5Graphics.text_ascent()` or + `Py5Graphics.text_descent()` so that the hack works even if you change the size + of the font. - This method is the same as ``text_align()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_align()``. + This method is the same as `text_align()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_align()`. """ pass @@ -13923,32 +14070,31 @@ def text_align(self, align_x: int, align_y: int, /) -> None: Notes ----- - Sets the current alignment for drawing text. The parameters ``LEFT``, - ``CENTER``, and ``RIGHT`` set the display characteristics of the letters in - relation to the values for the ``x`` and ``y`` parameters of the - ``Py5Graphics.text()`` function. + Sets the current alignment for drawing text. The parameters `LEFT`, `CENTER`, + and `RIGHT` set the display characteristics of the letters in relation to the + values for the `x` and `y` parameters of the `Py5Graphics.text()` function. An optional second parameter can be used to vertically align the text. - ``BASELINE`` is the default, and the vertical alignment will be reset to - ``BASELINE`` if the second parameter is not used. The ``TOP`` and ``CENTER`` - parameters are straightforward. The ``BOTTOM`` parameter offsets the line based - on the current ``Py5Graphics.text_descent()``. For multiple lines, the final - line will be aligned to the bottom, with the previous lines appearing above it. - - When using ``Py5Graphics.text()`` with width and height parameters, ``BASELINE`` - is ignored, and treated as ``TOP``. (Otherwise, text would by default draw - outside the box, since ``BASELINE`` is the default setting. ``BASELINE`` is not - a useful drawing mode for text drawn in a rectangle.) - - The vertical alignment is based on the value of ``Py5Graphics.text_ascent()``, + `BASELINE` is the default, and the vertical alignment will be reset to + `BASELINE` if the second parameter is not used. The `TOP` and `CENTER` + parameters are straightforward. The `BOTTOM` parameter offsets the line based on + the current `Py5Graphics.text_descent()`. For multiple lines, the final line + will be aligned to the bottom, with the previous lines appearing above it. + + When using `Py5Graphics.text()` with width and height parameters, `BASELINE` is + ignored, and treated as `TOP`. (Otherwise, text would by default draw outside + the box, since `BASELINE` is the default setting. `BASELINE` is not a useful + drawing mode for text drawn in a rectangle.) + + The vertical alignment is based on the value of `Py5Graphics.text_ascent()`, which many fonts do not specify correctly. It may be necessary to use a hack and offset by a few pixels by hand so that the offset looks correct. To do this as - less of a hack, use some percentage of ``Py5Graphics.text_ascent()`` or - ``Py5Graphics.text_descent()`` so that the hack works even if you change the - size of the font. + less of a hack, use some percentage of `Py5Graphics.text_ascent()` or + `Py5Graphics.text_descent()` so that the hack works even if you change the size + of the font. - This method is the same as ``text_align()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_align()``. + This method is the same as `text_align()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_align()`. """ pass @@ -13977,32 +14123,31 @@ def text_align(self, *args): Notes ----- - Sets the current alignment for drawing text. The parameters ``LEFT``, - ``CENTER``, and ``RIGHT`` set the display characteristics of the letters in - relation to the values for the ``x`` and ``y`` parameters of the - ``Py5Graphics.text()`` function. + Sets the current alignment for drawing text. The parameters `LEFT`, `CENTER`, + and `RIGHT` set the display characteristics of the letters in relation to the + values for the `x` and `y` parameters of the `Py5Graphics.text()` function. An optional second parameter can be used to vertically align the text. - ``BASELINE`` is the default, and the vertical alignment will be reset to - ``BASELINE`` if the second parameter is not used. The ``TOP`` and ``CENTER`` - parameters are straightforward. The ``BOTTOM`` parameter offsets the line based - on the current ``Py5Graphics.text_descent()``. For multiple lines, the final - line will be aligned to the bottom, with the previous lines appearing above it. - - When using ``Py5Graphics.text()`` with width and height parameters, ``BASELINE`` - is ignored, and treated as ``TOP``. (Otherwise, text would by default draw - outside the box, since ``BASELINE`` is the default setting. ``BASELINE`` is not - a useful drawing mode for text drawn in a rectangle.) - - The vertical alignment is based on the value of ``Py5Graphics.text_ascent()``, + `BASELINE` is the default, and the vertical alignment will be reset to + `BASELINE` if the second parameter is not used. The `TOP` and `CENTER` + parameters are straightforward. The `BOTTOM` parameter offsets the line based on + the current `Py5Graphics.text_descent()`. For multiple lines, the final line + will be aligned to the bottom, with the previous lines appearing above it. + + When using `Py5Graphics.text()` with width and height parameters, `BASELINE` is + ignored, and treated as `TOP`. (Otherwise, text would by default draw outside + the box, since `BASELINE` is the default setting. `BASELINE` is not a useful + drawing mode for text drawn in a rectangle.) + + The vertical alignment is based on the value of `Py5Graphics.text_ascent()`, which many fonts do not specify correctly. It may be necessary to use a hack and offset by a few pixels by hand so that the offset looks correct. To do this as - less of a hack, use some percentage of ``Py5Graphics.text_ascent()`` or - ``Py5Graphics.text_descent()`` so that the hack works even if you change the - size of the font. + less of a hack, use some percentage of `Py5Graphics.text_ascent()` or + `Py5Graphics.text_descent()` so that the hack works even if you change the size + of the font. - This method is the same as ``text_align()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_align()``. + This method is the same as `text_align()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_align()`. """ return self._instance.textAlign(*args) @@ -14017,8 +14162,8 @@ def text_ascent(self) -> float: Returns ascent of the current font at its current size. This information is useful for determining the height of the font above the baseline. - This method is the same as ``text_ascent()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_ascent()``. + This method is the same as `text_ascent()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_ascent()`. """ return self._instance.textAscent() @@ -14033,15 +14178,14 @@ def text_descent(self) -> float: Returns descent of the current font at its current size. This information is useful for determining the height of the font below the baseline. - This method is the same as ``text_descent()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_descent()``. + This method is the same as `text_descent()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `text_descent()`. """ return self._instance.textDescent() @overload def text_font(self, which: Py5Font, /) -> None: - """Sets the current font that will be drawn with the ``Py5Graphics.text()`` - function. + """Sets the current font that will be drawn with the `Py5Graphics.text()` function. Underlying Processing method: PGraphics.textFont @@ -14065,28 +14209,27 @@ def text_font(self, which: Py5Font, /) -> None: Notes ----- - Sets the current font that will be drawn with the ``Py5Graphics.text()`` - function. Fonts must be created for py5 with ``create_font()`` or loaded with - ``load_font()`` before they can be used. The font set through ``text_font()`` - will be used in all subsequent calls to the ``Py5Graphics.text()`` function. If - no ``size`` parameter is specified, the font size defaults to the original size - (the size in which it was created with ``create_font_file()``) overriding any - previous calls to ``text_font()`` or ``Py5Graphics.text_size()``. + Sets the current font that will be drawn with the `Py5Graphics.text()` function. + Fonts must be created for py5 with `create_font()` or loaded with `load_font()` + before they can be used. The font set through `text_font()` will be used in all + subsequent calls to the `Py5Graphics.text()` function. If no `size` parameter is + specified, the font size defaults to the original size (the size in which it was + created with `create_font_file()`) overriding any previous calls to + `text_font()` or `Py5Graphics.text_size()`. - When fonts are rendered as an image texture (as is the case with the ``P2D`` and - ``P3D`` renderers as well as with ``load_font()`` and vlw files), you should - create fonts at the sizes that will be used most commonly. Using ``text_font()`` - without the size parameter will result in the cleanest type. + When fonts are rendered as an image texture (as is the case with the `P2D` and + `P3D` renderers as well as with `load_font()` and vlw files), you should create + fonts at the sizes that will be used most commonly. Using `text_font()` without + the size parameter will result in the cleanest type. - This method is the same as ``text_font()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_font()``. + This method is the same as `text_font()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_font()`. """ pass @overload def text_font(self, which: Py5Font, size: float, /) -> None: - """Sets the current font that will be drawn with the ``Py5Graphics.text()`` - function. + """Sets the current font that will be drawn with the `Py5Graphics.text()` function. Underlying Processing method: PGraphics.textFont @@ -14110,27 +14253,26 @@ def text_font(self, which: Py5Font, size: float, /) -> None: Notes ----- - Sets the current font that will be drawn with the ``Py5Graphics.text()`` - function. Fonts must be created for py5 with ``create_font()`` or loaded with - ``load_font()`` before they can be used. The font set through ``text_font()`` - will be used in all subsequent calls to the ``Py5Graphics.text()`` function. If - no ``size`` parameter is specified, the font size defaults to the original size - (the size in which it was created with ``create_font_file()``) overriding any - previous calls to ``text_font()`` or ``Py5Graphics.text_size()``. + Sets the current font that will be drawn with the `Py5Graphics.text()` function. + Fonts must be created for py5 with `create_font()` or loaded with `load_font()` + before they can be used. The font set through `text_font()` will be used in all + subsequent calls to the `Py5Graphics.text()` function. If no `size` parameter is + specified, the font size defaults to the original size (the size in which it was + created with `create_font_file()`) overriding any previous calls to + `text_font()` or `Py5Graphics.text_size()`. - When fonts are rendered as an image texture (as is the case with the ``P2D`` and - ``P3D`` renderers as well as with ``load_font()`` and vlw files), you should - create fonts at the sizes that will be used most commonly. Using ``text_font()`` - without the size parameter will result in the cleanest type. + When fonts are rendered as an image texture (as is the case with the `P2D` and + `P3D` renderers as well as with `load_font()` and vlw files), you should create + fonts at the sizes that will be used most commonly. Using `text_font()` without + the size parameter will result in the cleanest type. - This method is the same as ``text_font()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_font()``. + This method is the same as `text_font()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_font()`. """ pass def text_font(self, *args): - """Sets the current font that will be drawn with the ``Py5Graphics.text()`` - function. + """Sets the current font that will be drawn with the `Py5Graphics.text()` function. Underlying Processing method: PGraphics.textFont @@ -14154,21 +14296,21 @@ def text_font(self, *args): Notes ----- - Sets the current font that will be drawn with the ``Py5Graphics.text()`` - function. Fonts must be created for py5 with ``create_font()`` or loaded with - ``load_font()`` before they can be used. The font set through ``text_font()`` - will be used in all subsequent calls to the ``Py5Graphics.text()`` function. If - no ``size`` parameter is specified, the font size defaults to the original size - (the size in which it was created with ``create_font_file()``) overriding any - previous calls to ``text_font()`` or ``Py5Graphics.text_size()``. + Sets the current font that will be drawn with the `Py5Graphics.text()` function. + Fonts must be created for py5 with `create_font()` or loaded with `load_font()` + before they can be used. The font set through `text_font()` will be used in all + subsequent calls to the `Py5Graphics.text()` function. If no `size` parameter is + specified, the font size defaults to the original size (the size in which it was + created with `create_font_file()`) overriding any previous calls to + `text_font()` or `Py5Graphics.text_size()`. - When fonts are rendered as an image texture (as is the case with the ``P2D`` and - ``P3D`` renderers as well as with ``load_font()`` and vlw files), you should - create fonts at the sizes that will be used most commonly. Using ``text_font()`` - without the size parameter will result in the cleanest type. + When fonts are rendered as an image texture (as is the case with the `P2D` and + `P3D` renderers as well as with `load_font()` and vlw files), you should create + fonts at the sizes that will be used most commonly. Using `text_font()` without + the size parameter will result in the cleanest type. - This method is the same as ``text_font()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_font()``. + This method is the same as `text_font()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_font()`. """ return self._instance.textFont(*args) @@ -14187,14 +14329,14 @@ def text_leading(self, leading: float, /) -> None: ----- Sets the spacing between lines of text in units of pixels. This setting will be - used in all subsequent calls to the ``Py5Graphics.text()`` function. Note, - however, that the leading is reset by ``Py5Graphics.text_size()``. For example, - if the leading is set to 20 with ``text_leading(20)``, then if ``text_size(48)`` - is run at a later point, the leading will be reset to the default for the text - size of 48. + used in all subsequent calls to the `Py5Graphics.text()` function. Note, + however, that the leading is reset by `Py5Graphics.text_size()`. For example, if + the leading is set to 20 with `text_leading(20)`, then if `text_size(48)` is run + at a later point, the leading will be reset to the default for the text size of + 48. - This method is the same as ``text_leading()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_leading()``. + This method is the same as `text_leading()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `text_leading()`. """ return self._instance.textLeading(leading) @@ -14214,22 +14356,22 @@ def text_mode(self, mode: int, /) -> None: ----- Sets the way text draws to the Py5Graphics drawing surface, either as texture - maps or as vector geometry. The default ``text_mode(MODEL)``, uses textures to - render the fonts. The ``text_mode(SHAPE)`` mode draws text using the glyph + maps or as vector geometry. The default `text_mode(MODEL)`, uses textures to + render the fonts. The `text_mode(SHAPE)` mode draws text using the glyph outlines of individual characters rather than as textures. This mode is only - supported with the ``PDF`` and ``P3D`` renderer settings. With the ``PDF`` - renderer, you must call ``text_mode(SHAPE)`` before any other drawing occurs. If - the outlines are not available, then ``text_mode(SHAPE)`` will be ignored and - ``text_mode(MODEL)`` will be used instead. + supported with the `PDF` and `P3D` renderer settings. With the `PDF` renderer, + you must call `text_mode(SHAPE)` before any other drawing occurs. If the + outlines are not available, then `text_mode(SHAPE)` will be ignored and + `text_mode(MODEL)` will be used instead. - The ``text_mode(SHAPE)`` option in ``P3D`` can be combined with - ``Py5Graphics.begin_raw()`` to write vector-accurate text to 2D and 3D output - files, for instance ``DXF`` or ``PDF``. The ``SHAPE`` mode is not currently - optimized for ``P3D``, so if recording shape data, use ``text_mode(MODEL)`` - until you're ready to capture the geometry with ``Py5Graphics.begin_raw()``. + The `text_mode(SHAPE)` option in `P3D` can be combined with + `Py5Graphics.begin_raw()` to write vector-accurate text to 2D and 3D output + files, for instance `DXF` or `PDF`. The `SHAPE` mode is not currently optimized + for `P3D`, so if recording shape data, use `text_mode(MODEL)` until you're ready + to capture the geometry with `Py5Graphics.begin_raw()`. - This method is the same as ``text_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_mode()``. + This method is the same as `text_mode()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_mode()`. """ return self._instance.textMode(mode) @@ -14248,10 +14390,10 @@ def text_size(self, size: float, /) -> None: ----- Sets the current font size. This size will be used in all subsequent calls to - the ``Py5Graphics.text()`` function. Font size is measured in units of pixels. + the `Py5Graphics.text()` function. Font size is measured in units of pixels. - This method is the same as ``text_size()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_size()``. + This method is the same as `text_size()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_size()`. """ return self._instance.textSize(size) @@ -14293,8 +14435,8 @@ def text_width(self, c: chr, /) -> float: Calculates and returns the width of any character or text string. - This method is the same as ``text_width()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_width()``. + This method is the same as `text_width()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_width()`. """ pass @@ -14337,8 +14479,8 @@ def text_width(self, chars: list[chr], Calculates and returns the width of any character or text string. - This method is the same as ``text_width()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_width()``. + This method is the same as `text_width()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_width()`. """ pass @@ -14380,8 +14522,8 @@ def text_width(self, str: str, /) -> float: Calculates and returns the width of any character or text string. - This method is the same as ``text_width()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_width()``. + This method is the same as `text_width()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_width()`. """ pass @@ -14423,8 +14565,8 @@ def text_width(self, *args): Calculates and returns the width of any character or text string. - This method is the same as ``text_width()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``text_width()``. + This method is the same as `text_width()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `text_width()`. """ return self._instance.textWidth(*args) @@ -14442,17 +14584,17 @@ def texture(self, image: Py5Image, /) -> None: Notes ----- - Sets a texture to be applied to vertex points. The ``texture()`` method must be - called between ``Py5Graphics.begin_shape()`` and ``Py5Graphics.end_shape()`` and - before any calls to ``Py5Graphics.vertex()``. This method only works with the - ``P2D`` and ``P3D`` renderers. + Sets a texture to be applied to vertex points. The `texture()` method must be + called between `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` and + before any calls to `Py5Graphics.vertex()`. This method only works with the + `P2D` and `P3D` renderers. When textures are in use, the fill color is ignored. Instead, use - ``Py5Graphics.tint()`` to specify the color of the texture as it is applied to - the shape. + `Py5Graphics.tint()` to specify the color of the texture as it is applied to the + shape. - This method is the same as ``texture()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``texture()``. + This method is the same as `texture()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `texture()`. """ return self._instance.texture(image) @@ -14470,17 +14612,17 @@ def texture_mode(self, mode: int, /) -> None: Notes ----- - Sets the coordinate space for texture mapping. The default mode is ``IMAGE``, - which refers to the actual pixel coordinates of the image. ``NORMAL`` refers to - a normalized space of values ranging from 0 to 1. This function only works with - the ``P2D`` and ``P3D`` renderers. + Sets the coordinate space for texture mapping. The default mode is `IMAGE`, + which refers to the actual pixel coordinates of the image. `NORMAL` refers to a + normalized space of values ranging from 0 to 1. This function only works with + the `P2D` and `P3D` renderers. - With ``IMAGE``, if an image is 100 x 200 pixels, mapping the image onto the - entire size of a quad would require the points (0,0) (100,0) (100,200) (0,200). - The same mapping in ``NORMAL`` is (0,0) (1,0) (1,1) (0,1). + With `IMAGE`, if an image is 100 x 200 pixels, mapping the image onto the entire + size of a quad would require the points (0,0) (100,0) (100,200) (0,200). The + same mapping in `NORMAL` is (0,0) (1,0) (1,1) (0,1). - This method is the same as ``texture_mode()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``texture_mode()``. + This method is the same as `texture_mode()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `texture_mode()`. """ return self._instance.textureMode(mode) @@ -14499,11 +14641,11 @@ def texture_wrap(self, wrap: int, /) -> None: ----- Defines if textures repeat or draw once within a texture map. The two parameters - are ``CLAMP`` (the default behavior) and ``REPEAT``. This function only works - with the ``P2D`` and ``P3D`` renderers. + are `CLAMP` (the default behavior) and `REPEAT`. This function only works with + the `P2D` and `P3D` renderers. - This method is the same as ``texture_wrap()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``texture_wrap()``. + This method is the same as `texture_wrap()` but linked to a `Py5Graphics` + object. To see example code for how it can be used, see `texture_wrap()`. """ return self._instance.textureWrap(wrap) @@ -14553,33 +14695,33 @@ def tint(self, gray: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``Py5Graphics.color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `Py5Graphics.color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. - This method is the same as ``tint()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``tint()``. + This method is the same as `tint()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `tint()`. """ pass @@ -14629,33 +14771,33 @@ def tint(self, gray: float, alpha: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``Py5Graphics.color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `Py5Graphics.color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. - This method is the same as ``tint()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``tint()``. + This method is the same as `tint()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `tint()`. """ pass @@ -14705,33 +14847,33 @@ def tint(self, v1: float, v2: float, v3: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``Py5Graphics.color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `Py5Graphics.color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. - This method is the same as ``tint()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``tint()``. + This method is the same as `tint()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `tint()`. """ pass @@ -14781,33 +14923,33 @@ def tint(self, v1: float, v2: float, v3: float, alpha: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``Py5Graphics.color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `Py5Graphics.color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. - This method is the same as ``tint()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``tint()``. + This method is the same as `tint()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `tint()`. """ pass @@ -14857,33 +14999,33 @@ def tint(self, rgb: int, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``Py5Graphics.color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `Py5Graphics.color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. - This method is the same as ``tint()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``tint()``. + This method is the same as `tint()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `tint()`. """ pass @@ -14933,33 +15075,33 @@ def tint(self, rgb: int, alpha: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``Py5Graphics.color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `Py5Graphics.color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. - This method is the same as ``tint()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``tint()``. + This method is the same as `tint()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `tint()`. """ pass @@ -15009,33 +15151,33 @@ def tint(self, *args): colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``Py5Graphics.color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `Py5Graphics.color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``Py5Graphics.color_mode()``. The default maximum + maximum value as specified by `Py5Graphics.color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. - This method is the same as ``tint()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``tint()``. + This method is the same as `tint()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `tint()`. """ return self._instance.tint(*args) @@ -15069,19 +15211,19 @@ def translate(self, x: float, y: float, /) -> None: ----- Specifies an amount to displace objects within the Py5Graphics drawing surface. - The ``x`` parameter specifies left/right translation, the ``y`` parameter - specifies up/down translation, and the ``z`` parameter specifies translations - toward/away from the screen. Using this function with the ``z`` parameter - requires using the ``P3D`` renderer. + The `x` parameter specifies left/right translation, the `y` parameter specifies + up/down translation, and the `z` parameter specifies translations toward/away + from the screen. Using this function with the `z` parameter requires using the + `P3D` renderer. Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. This function can be further controlled by using - ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()``. + `translate(50, 0)` and then `translate(20, 0)` is the same as `translate(70, + 0)`. This function can be further controlled by using + `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()`. - This method is the same as ``translate()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``translate()``. + This method is the same as `translate()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `translate()`. """ pass @@ -15115,19 +15257,19 @@ def translate(self, x: float, y: float, z: float, /) -> None: ----- Specifies an amount to displace objects within the Py5Graphics drawing surface. - The ``x`` parameter specifies left/right translation, the ``y`` parameter - specifies up/down translation, and the ``z`` parameter specifies translations - toward/away from the screen. Using this function with the ``z`` parameter - requires using the ``P3D`` renderer. + The `x` parameter specifies left/right translation, the `y` parameter specifies + up/down translation, and the `z` parameter specifies translations toward/away + from the screen. Using this function with the `z` parameter requires using the + `P3D` renderer. Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. This function can be further controlled by using - ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()``. + `translate(50, 0)` and then `translate(20, 0)` is the same as `translate(70, + 0)`. This function can be further controlled by using + `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()`. - This method is the same as ``translate()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``translate()``. + This method is the same as `translate()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `translate()`. """ pass @@ -15160,19 +15302,19 @@ def translate(self, *args): ----- Specifies an amount to displace objects within the Py5Graphics drawing surface. - The ``x`` parameter specifies left/right translation, the ``y`` parameter - specifies up/down translation, and the ``z`` parameter specifies translations - toward/away from the screen. Using this function with the ``z`` parameter - requires using the ``P3D`` renderer. + The `x` parameter specifies left/right translation, the `y` parameter specifies + up/down translation, and the `z` parameter specifies translations toward/away + from the screen. Using this function with the `z` parameter requires using the + `P3D` renderer. Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. This function can be further controlled by using - ``Py5Graphics.push_matrix()`` and ``Py5Graphics.pop_matrix()``. + `translate(50, 0)` and then `translate(20, 0)` is the same as `translate(70, + 0)`. This function can be further controlled by using + `Py5Graphics.push_matrix()` and `Py5Graphics.pop_matrix()`. - This method is the same as ``translate()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``translate()``. + This method is the same as `translate()` but linked to a `Py5Graphics` object. + To see example code for how it can be used, see `translate()`. """ return self._instance.translate(*args) @@ -15210,15 +15352,15 @@ def triangle(self, x1: float, y1: float, x2: float, arguments specify the first point, the middle two arguments specify the second point, and the last two arguments specify the third point. - This method is the same as ``triangle()`` but linked to a ``Py5Graphics`` - object. To see example code for how it can be used, see ``triangle()``. + This method is the same as `triangle()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `triangle()`. """ return self._instance.triangle(x1, y1, x2, y2, x3, y3) @overload def update_pixels(self) -> None: """Updates the Py5Graphics drawing surface with the data in the - ``Py5Graphics.pixels[]`` array. + `Py5Graphics.pixels[]` array. Underlying Processing method: PGraphics.updatePixels @@ -15249,15 +15391,15 @@ def update_pixels(self) -> None: ----- Updates the Py5Graphics drawing surface with the data in the - ``Py5Graphics.pixels[]`` array. Use in conjunction with - ``Py5Graphics.load_pixels()``. If you're only reading pixels from the array, - there's no need to call ``update_pixels()`` — updating is only necessary to - apply changes. + `Py5Graphics.pixels[]` array. Use in conjunction with + `Py5Graphics.load_pixels()`. If you're only reading pixels from the array, + there's no need to call `update_pixels()` — updating is only necessary to apply + changes. - Use the ``update_pixels(x, y, w, h)`` syntax to update only a subset of the - pixel array. This can be faster if only some of the pixels have been changed. + Use the `update_pixels(x, y, w, h)` syntax to update only a subset of the pixel + array. This can be faster if only some of the pixels have been changed. - This method is the same as ``update_pixels()`` but linked to a ``Py5Graphics`` + This method is the same as `update_pixels()` but linked to a `Py5Graphics` object. """ pass @@ -15265,7 +15407,7 @@ def update_pixels(self) -> None: @overload def update_pixels(self, x: int, y: int, w: int, h: int, /) -> None: """Updates the Py5Graphics drawing surface with the data in the - ``Py5Graphics.pixels[]`` array. + `Py5Graphics.pixels[]` array. Underlying Processing method: PGraphics.updatePixels @@ -15296,22 +15438,22 @@ def update_pixels(self, x: int, y: int, w: int, h: int, /) -> None: ----- Updates the Py5Graphics drawing surface with the data in the - ``Py5Graphics.pixels[]`` array. Use in conjunction with - ``Py5Graphics.load_pixels()``. If you're only reading pixels from the array, - there's no need to call ``update_pixels()`` — updating is only necessary to - apply changes. + `Py5Graphics.pixels[]` array. Use in conjunction with + `Py5Graphics.load_pixels()`. If you're only reading pixels from the array, + there's no need to call `update_pixels()` — updating is only necessary to apply + changes. - Use the ``update_pixels(x, y, w, h)`` syntax to update only a subset of the - pixel array. This can be faster if only some of the pixels have been changed. + Use the `update_pixels(x, y, w, h)` syntax to update only a subset of the pixel + array. This can be faster if only some of the pixels have been changed. - This method is the same as ``update_pixels()`` but linked to a ``Py5Graphics`` + This method is the same as `update_pixels()` but linked to a `Py5Graphics` object. """ pass def update_pixels(self, *args): """Updates the Py5Graphics drawing surface with the data in the - ``Py5Graphics.pixels[]`` array. + `Py5Graphics.pixels[]` array. Underlying Processing method: PGraphics.updatePixels @@ -15342,15 +15484,15 @@ def update_pixels(self, *args): ----- Updates the Py5Graphics drawing surface with the data in the - ``Py5Graphics.pixels[]`` array. Use in conjunction with - ``Py5Graphics.load_pixels()``. If you're only reading pixels from the array, - there's no need to call ``update_pixels()`` — updating is only necessary to - apply changes. + `Py5Graphics.pixels[]` array. Use in conjunction with + `Py5Graphics.load_pixels()`. If you're only reading pixels from the array, + there's no need to call `update_pixels()` — updating is only necessary to apply + changes. - Use the ``update_pixels(x, y, w, h)`` syntax to update only a subset of the - pixel array. This can be faster if only some of the pixels have been changed. + Use the `update_pixels(x, y, w, h)` syntax to update only a subset of the pixel + array. This can be faster if only some of the pixels have been changed. - This method is the same as ``update_pixels()`` but linked to a ``Py5Graphics`` + This method is the same as `update_pixels()` but linked to a `Py5Graphics` object. """ return self._instance.updatePixels(*args) @@ -15397,21 +15539,21 @@ def vertex(self, x: float, y: float, /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``Py5Graphics.begin_shape()`` and ``Py5Graphics.end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer. This method is also used to map a texture onto geometry. The - ``Py5Graphics.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Graphics.texture_mode()`` method. + `Py5Graphics.texture()` function declares the texture to apply to the geometry + and the `u` and `v` coordinates define the mapping of this texture to the form. + By default, the coordinates used for `u` and `v` are specified in relation to + the image's size in pixels, but this relation can be changed with the + `Py5Graphics.texture_mode()` method. - This method is the same as ``vertex()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``vertex()``. + This method is the same as `vertex()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `vertex()`. """ pass @@ -15457,21 +15599,21 @@ def vertex(self, x: float, y: float, z: float, /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``Py5Graphics.begin_shape()`` and ``Py5Graphics.end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer. This method is also used to map a texture onto geometry. The - ``Py5Graphics.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Graphics.texture_mode()`` method. + `Py5Graphics.texture()` function declares the texture to apply to the geometry + and the `u` and `v` coordinates define the mapping of this texture to the form. + By default, the coordinates used for `u` and `v` are specified in relation to + the image's size in pixels, but this relation can be changed with the + `Py5Graphics.texture_mode()` method. - This method is the same as ``vertex()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``vertex()``. + This method is the same as `vertex()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `vertex()`. """ pass @@ -15517,21 +15659,21 @@ def vertex(self, x: float, y: float, u: float, v: float, /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``Py5Graphics.begin_shape()`` and ``Py5Graphics.end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer. This method is also used to map a texture onto geometry. The - ``Py5Graphics.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Graphics.texture_mode()`` method. + `Py5Graphics.texture()` function declares the texture to apply to the geometry + and the `u` and `v` coordinates define the mapping of this texture to the form. + By default, the coordinates used for `u` and `v` are specified in relation to + the image's size in pixels, but this relation can be changed with the + `Py5Graphics.texture_mode()` method. - This method is the same as ``vertex()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``vertex()``. + This method is the same as `vertex()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `vertex()`. """ pass @@ -15578,21 +15720,21 @@ def vertex(self, x: float, y: float, z: float, ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``Py5Graphics.begin_shape()`` and ``Py5Graphics.end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer. This method is also used to map a texture onto geometry. The - ``Py5Graphics.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Graphics.texture_mode()`` method. + `Py5Graphics.texture()` function declares the texture to apply to the geometry + and the `u` and `v` coordinates define the mapping of this texture to the form. + By default, the coordinates used for `u` and `v` are specified in relation to + the image's size in pixels, but this relation can be changed with the + `Py5Graphics.texture_mode()` method. - This method is the same as ``vertex()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``vertex()``. + This method is the same as `vertex()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `vertex()`. """ pass @@ -15638,21 +15780,21 @@ def vertex(self, v: npt.NDArray[np.floating], /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``Py5Graphics.begin_shape()`` and ``Py5Graphics.end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer. This method is also used to map a texture onto geometry. The - ``Py5Graphics.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Graphics.texture_mode()`` method. + `Py5Graphics.texture()` function declares the texture to apply to the geometry + and the `u` and `v` coordinates define the mapping of this texture to the form. + By default, the coordinates used for `u` and `v` are specified in relation to + the image's size in pixels, but this relation can be changed with the + `Py5Graphics.texture_mode()` method. - This method is the same as ``vertex()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``vertex()``. + This method is the same as `vertex()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `vertex()`. """ pass @@ -15697,21 +15839,21 @@ def vertex(self, *args): ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``Py5Graphics.begin_shape()`` and ``Py5Graphics.end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `Py5Graphics.begin_shape()` and `Py5Graphics.end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer. This method is also used to map a texture onto geometry. The - ``Py5Graphics.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Graphics.texture_mode()`` method. + `Py5Graphics.texture()` function declares the texture to apply to the geometry + and the `u` and `v` coordinates define the mapping of this texture to the form. + By default, the coordinates used for `u` and `v` are specified in relation to + the image's size in pixels, but this relation can be changed with the + `Py5Graphics.texture_mode()` method. - This method is the same as ``vertex()`` but linked to a ``Py5Graphics`` object. - To see example code for how it can be used, see ``vertex()``. + This method is the same as `vertex()` but linked to a `Py5Graphics` object. To + see example code for how it can be used, see `vertex()`. """ return self._instance.vertex(*args) @@ -15725,8 +15867,8 @@ def next_page(self, *, _renderer_name=None, _clsname=None) -> None: ----- Move to the next page in a PDF document. This method is only available when - using a ``PDF`` ``Py5Graphics`` object. Using this method with any other - graphics renderer will result in an error. + using a `PDF` `Py5Graphics` object. Using this method with any other graphics + renderer will result in an error. """ try: _JClass = JClass(_clsname) diff --git a/py5/image.py b/py5/image.py index 39fc56a..ecae742 100644 --- a/py5/image.py +++ b/py5/image.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -25,6 +25,7 @@ from .base import Py5Base from .mixins import PixelPy5ImageMixin +from . import spelling def _return_py5image(f): @@ -46,23 +47,22 @@ class Py5Image(PixelPy5ImageMixin, Py5Base): Notes ----- - Datatype for storing images. Py5 can load ``.gif``, ``.jpg``, ``.tga``, and - ``.png`` images using the ``load_image()`` function. Py5 can also convert common - Python image objects using the ``convert_image()`` function. Images may be - displayed in 2D and 3D space. The ``Py5Image`` class contains fields for the - ``Py5Image.width`` and ``Py5Image.height`` of the image, as well as arrays - called ``Py5Image.pixels[]`` and ``Py5Image.np_pixels[]`` that contain the - values for every pixel in the image. The methods described below allow easy - access to the image's pixels and alpha channel and simplify the process of - compositing. - - Before using the ``Py5Image.pixels[]`` array, be sure to use the - ``Py5Image.load_pixels()`` method on the image to make sure that the pixel data - is properly loaded. Similarly, be sure to use the ``Py5Image.load_np_pixels()`` - method on the image before using the ``Py5Image.np_pixels[]`` array. - - To create a new image, use the ``create_image()`` function. Do not use the - syntax ``Py5Image()``. + Datatype for storing images. Py5 can load `.gif`, `.jpg`, `.tga`, and `.png` + images using the `load_image()` function. Py5 can also convert common Python + image objects using the `convert_image()` function. Images may be displayed in + 2D and 3D space. The `Py5Image` class contains fields for the `Py5Image.width` + and `Py5Image.height` of the image, as well as arrays called `Py5Image.pixels[]` + and `Py5Image.np_pixels[]` that contain the values for every pixel in the image. + The methods described below allow easy access to the image's pixels and alpha + channel and simplify the process of compositing. + + Before using the `Py5Image.pixels[]` array, be sure to use the + `Py5Image.load_pixels()` method on the image to make sure that the pixel data is + properly loaded. Similarly, be sure to use the `Py5Image.load_np_pixels()` + method on the image before using the `Py5Image.np_pixels[]` array. + + To create a new image, use the `create_image()` function. Do not use the syntax + `Py5Image()`. """ _py5_object_cache = weakref.WeakSet() @@ -83,6 +83,16 @@ def __init__(self, pimage): self._instance = pimage super().__init__(instance=pimage) + def __str__(self) -> str: + return f"Py5Image(width=" + str(self._get_width()) + \ + ", height=" + str(self._get_height()) + ")" + + def __repr__(self) -> str: + return self.__str__() + + def __getattr__(self, name): + raise AttributeError(spelling.error_msg('Py5Image', name, self)) + ADD = 2 ALPHA = 4 ALPHA_MASK = -16777216 @@ -146,7 +156,7 @@ def _get_pixel_density(self) -> int: ----- Pixel density of the Py5Image object. This will always be equal to 1, even if - the Sketch used ``pixel_density()`` to set the pixel density to a value greater + the Sketch used `pixel_density()` to set the pixel density to a value greater than 1. """ return self._instance.pixelDensity @@ -160,7 +170,7 @@ def _get_pixel_density(self) -> int: ----- Pixel density of the Py5Image object. This will always be equal to 1, even if - the Sketch used ``pixel_density()`` to set the pixel density to a value greater + the Sketch used `pixel_density()` to set the pixel density to a value greater than 1.""") def _get_pixel_height(self) -> int: @@ -172,8 +182,8 @@ def _get_pixel_height(self) -> int: ----- Height of the Py5Image object in pixels. This will be the same as - ``Py5Image.height``, even if the Sketch used ``pixel_density()`` to set the - pixel density to a value greater than 1. + `Py5Image.height`, even if the Sketch used `pixel_density()` to set the pixel + density to a value greater than 1. """ return self._instance.pixelHeight pixel_height: int = property( @@ -186,8 +196,8 @@ def _get_pixel_height(self) -> int: ----- Height of the Py5Image object in pixels. This will be the same as - ``Py5Image.height``, even if the Sketch used ``pixel_density()`` to set the - pixel density to a value greater than 1.""") + `Py5Image.height`, even if the Sketch used `pixel_density()` to set the pixel + density to a value greater than 1.""") def _get_pixel_width(self) -> int: """Width of the Py5Image object in pixels. @@ -198,7 +208,7 @@ def _get_pixel_width(self) -> int: ----- Width of the Py5Image object in pixels. This will be the same as - ``Py5Image.width``, even if the Sketch used ``pixel_density()`` to set the pixel + `Py5Image.width`, even if the Sketch used `pixel_density()` to set the pixel density to a value greater than 1. """ return self._instance.pixelWidth @@ -212,7 +222,7 @@ def _get_pixel_width(self) -> int: ----- Width of the Py5Image object in pixels. This will be the same as - ``Py5Image.width``, even if the Sketch used ``pixel_density()`` to set the pixel + `Py5Image.width`, even if the Sketch used `pixel_density()` to set the pixel density to a value greater than 1.""") def _get_width(self) -> int: @@ -240,7 +250,7 @@ def _get_width(self) -> int: @overload def blend(self, sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, mode: int, /) -> None: - """Blends a region of pixels into the image specified by the ``img`` parameter. + """Blends a region of pixels into the image specified by the `img` parameter. Underlying Processing method: PImage.blend @@ -288,16 +298,16 @@ def blend(self, sx: int, sy: int, sw: int, sh: int, dx: int, Notes ----- - Blends a region of pixels into the image specified by the ``img`` parameter. - These copies utilize full alpha channel support and a choice of the following - modes to blend the colors of source pixels (A) with the ones of pixels in the - destination image (B): + Blends a region of pixels into the image specified by the `img` parameter. These + copies utilize full alpha channel support and a choice of the following modes to + blend the colors of source pixels (A) with the ones of pixels in the destination + image (B): - * BLEND: linear interpolation of colours: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest colour succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest colour succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colours: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest colour succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest colour succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -314,17 +324,17 @@ def blend(self, sx: int, sy: int, sw: int, sh: int, dx: int, All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the display window is used as the source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the display window is used as the source image. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @overload def blend(self, src: Py5Image, sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, mode: int, /) -> None: - """Blends a region of pixels into the image specified by the ``img`` parameter. + """Blends a region of pixels into the image specified by the `img` parameter. Underlying Processing method: PImage.blend @@ -372,16 +382,16 @@ def blend(self, src: Py5Image, sx: int, sy: int, sw: int, sh: int, Notes ----- - Blends a region of pixels into the image specified by the ``img`` parameter. - These copies utilize full alpha channel support and a choice of the following - modes to blend the colors of source pixels (A) with the ones of pixels in the - destination image (B): + Blends a region of pixels into the image specified by the `img` parameter. These + copies utilize full alpha channel support and a choice of the following modes to + blend the colors of source pixels (A) with the ones of pixels in the destination + image (B): - * BLEND: linear interpolation of colours: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest colour succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest colour succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colours: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest colour succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest colour succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -398,15 +408,15 @@ def blend(self, src: Py5Image, sx: int, sy: int, sw: int, sh: int, All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the display window is used as the source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the display window is used as the source image. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass def blend(self, *args): - """Blends a region of pixels into the image specified by the ``img`` parameter. + """Blends a region of pixels into the image specified by the `img` parameter. Underlying Processing method: PImage.blend @@ -454,16 +464,16 @@ def blend(self, *args): Notes ----- - Blends a region of pixels into the image specified by the ``img`` parameter. - These copies utilize full alpha channel support and a choice of the following - modes to blend the colors of source pixels (A) with the ones of pixels in the - destination image (B): + Blends a region of pixels into the image specified by the `img` parameter. These + copies utilize full alpha channel support and a choice of the following modes to + blend the colors of source pixels (A) with the ones of pixels in the destination + image (B): - * BLEND: linear interpolation of colours: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest colour succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest colour succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colours: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest colour succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest colour succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -480,10 +490,10 @@ def blend(self, *args): All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the display window is used as the source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the display window is used as the source image. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ return self._instance.blend(*args) @@ -541,7 +551,7 @@ def copy(self) -> Py5Image: process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @@ -600,7 +610,7 @@ def copy(self, sx: int, sy: int, sw: int, sh: int, process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @@ -659,7 +669,7 @@ def copy(self, src: Py5Image, sx: int, sy: int, sw: int, process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @@ -716,7 +726,7 @@ def copy(self, *args): process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ return self._instance.copy(*args) @@ -864,7 +874,7 @@ def apply_filter(self, *args): return self._instance.filter(*args) @overload - def get(self) -> Py5Image: + def get_pixels(self) -> Py5Image: """Reads the color of any pixel or grabs a section of an image. Underlying Processing method: PImage.get @@ -874,9 +884,9 @@ def get(self) -> Py5Image: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -897,27 +907,27 @@ def get(self) -> Py5Image: ----- Reads the color of any pixel or grabs a section of an image. If no parameters - are specified, the entire image is returned. Use the ``x`` and ``y`` parameters - to get the value of one pixel. Get a section of the image by specifying - additional ``w`` and ``h`` parameters. When getting an image, the ``x`` and - ``y`` parameters define the coordinates for the upper-left corner of the - returned image, regardless of the current ``image_mode()``. + are specified, the entire image is returned. Use the `x` and `y` parameters to + get the value of one pixel. Get a section of the image by specifying additional + `w` and `h` parameters. When getting an image, the `x` and `y` parameters define + the coordinates for the upper-left corner of the returned image, regardless of + the current `image_mode()`. If the pixel requested is outside of the image, black is returned. The numbers - returned are scaled according to the current color ranges, but only ``RGB`` - values are returned by this function. For example, even though you may have - drawn a shape with ``color_mode(HSB)``, the numbers returned will be in ``RGB`` - format. - - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``Py5Image.pixels[]``. The equivalent - statement to ``get(x, y)`` using ``Py5Image.pixels[]`` is ``pixels[y*width+x]``. - See the reference for ``Py5Image.pixels[]`` for more information. + returned are scaled according to the current color ranges, but only `RGB` values + are returned by this function. For example, even though you may have drawn a + shape with `color_mode(HSB)`, the numbers returned will be in `RGB` format. + + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `Py5Image.pixels[]`. The equivalent + statement to `get_pixels(x, y)` using `Py5Image.pixels[]` is + `pixels[y*width+x]`. See the reference for `Py5Image.pixels[]` for more + information. """ pass @overload - def get(self, x: int, y: int, /) -> int: + def get_pixels(self, x: int, y: int, /) -> int: """Reads the color of any pixel or grabs a section of an image. Underlying Processing method: PImage.get @@ -927,9 +937,9 @@ def get(self, x: int, y: int, /) -> int: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -950,27 +960,27 @@ def get(self, x: int, y: int, /) -> int: ----- Reads the color of any pixel or grabs a section of an image. If no parameters - are specified, the entire image is returned. Use the ``x`` and ``y`` parameters - to get the value of one pixel. Get a section of the image by specifying - additional ``w`` and ``h`` parameters. When getting an image, the ``x`` and - ``y`` parameters define the coordinates for the upper-left corner of the - returned image, regardless of the current ``image_mode()``. + are specified, the entire image is returned. Use the `x` and `y` parameters to + get the value of one pixel. Get a section of the image by specifying additional + `w` and `h` parameters. When getting an image, the `x` and `y` parameters define + the coordinates for the upper-left corner of the returned image, regardless of + the current `image_mode()`. If the pixel requested is outside of the image, black is returned. The numbers - returned are scaled according to the current color ranges, but only ``RGB`` - values are returned by this function. For example, even though you may have - drawn a shape with ``color_mode(HSB)``, the numbers returned will be in ``RGB`` - format. - - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``Py5Image.pixels[]``. The equivalent - statement to ``get(x, y)`` using ``Py5Image.pixels[]`` is ``pixels[y*width+x]``. - See the reference for ``Py5Image.pixels[]`` for more information. + returned are scaled according to the current color ranges, but only `RGB` values + are returned by this function. For example, even though you may have drawn a + shape with `color_mode(HSB)`, the numbers returned will be in `RGB` format. + + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `Py5Image.pixels[]`. The equivalent + statement to `get_pixels(x, y)` using `Py5Image.pixels[]` is + `pixels[y*width+x]`. See the reference for `Py5Image.pixels[]` for more + information. """ pass @overload - def get(self, x: int, y: int, w: int, h: int, /) -> Py5Image: + def get_pixels(self, x: int, y: int, w: int, h: int, /) -> Py5Image: """Reads the color of any pixel or grabs a section of an image. Underlying Processing method: PImage.get @@ -980,9 +990,9 @@ def get(self, x: int, y: int, w: int, h: int, /) -> Py5Image: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -1003,26 +1013,26 @@ def get(self, x: int, y: int, w: int, h: int, /) -> Py5Image: ----- Reads the color of any pixel or grabs a section of an image. If no parameters - are specified, the entire image is returned. Use the ``x`` and ``y`` parameters - to get the value of one pixel. Get a section of the image by specifying - additional ``w`` and ``h`` parameters. When getting an image, the ``x`` and - ``y`` parameters define the coordinates for the upper-left corner of the - returned image, regardless of the current ``image_mode()``. + are specified, the entire image is returned. Use the `x` and `y` parameters to + get the value of one pixel. Get a section of the image by specifying additional + `w` and `h` parameters. When getting an image, the `x` and `y` parameters define + the coordinates for the upper-left corner of the returned image, regardless of + the current `image_mode()`. If the pixel requested is outside of the image, black is returned. The numbers - returned are scaled according to the current color ranges, but only ``RGB`` - values are returned by this function. For example, even though you may have - drawn a shape with ``color_mode(HSB)``, the numbers returned will be in ``RGB`` - format. - - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``Py5Image.pixels[]``. The equivalent - statement to ``get(x, y)`` using ``Py5Image.pixels[]`` is ``pixels[y*width+x]``. - See the reference for ``Py5Image.pixels[]`` for more information. + returned are scaled according to the current color ranges, but only `RGB` values + are returned by this function. For example, even though you may have drawn a + shape with `color_mode(HSB)`, the numbers returned will be in `RGB` format. + + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `Py5Image.pixels[]`. The equivalent + statement to `get_pixels(x, y)` using `Py5Image.pixels[]` is + `pixels[y*width+x]`. See the reference for `Py5Image.pixels[]` for more + information. """ pass - def get(self, *args): + def get_pixels(self, *args): """Reads the color of any pixel or grabs a section of an image. Underlying Processing method: PImage.get @@ -1032,9 +1042,9 @@ def get(self, *args): You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -1055,36 +1065,36 @@ def get(self, *args): ----- Reads the color of any pixel or grabs a section of an image. If no parameters - are specified, the entire image is returned. Use the ``x`` and ``y`` parameters - to get the value of one pixel. Get a section of the image by specifying - additional ``w`` and ``h`` parameters. When getting an image, the ``x`` and - ``y`` parameters define the coordinates for the upper-left corner of the - returned image, regardless of the current ``image_mode()``. + are specified, the entire image is returned. Use the `x` and `y` parameters to + get the value of one pixel. Get a section of the image by specifying additional + `w` and `h` parameters. When getting an image, the `x` and `y` parameters define + the coordinates for the upper-left corner of the returned image, regardless of + the current `image_mode()`. If the pixel requested is outside of the image, black is returned. The numbers - returned are scaled according to the current color ranges, but only ``RGB`` - values are returned by this function. For example, even though you may have - drawn a shape with ``color_mode(HSB)``, the numbers returned will be in ``RGB`` - format. - - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``Py5Image.pixels[]``. The equivalent - statement to ``get(x, y)`` using ``Py5Image.pixels[]`` is ``pixels[y*width+x]``. - See the reference for ``Py5Image.pixels[]`` for more information. + returned are scaled according to the current color ranges, but only `RGB` values + are returned by this function. For example, even though you may have drawn a + shape with `color_mode(HSB)`, the numbers returned will be in `RGB` format. + + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `Py5Image.pixels[]`. The equivalent + statement to `get_pixels(x, y)` using `Py5Image.pixels[]` is + `pixels[y*width+x]`. See the reference for `Py5Image.pixels[]` for more + information. """ return self._instance.get(*args) def load_pixels(self) -> None: - """Loads the pixel data for the image into its ``Py5Image.pixels[]`` array. + """Loads the pixel data for the image into its `Py5Image.pixels[]` array. Underlying Processing method: PImage.loadPixels Notes ----- - Loads the pixel data for the image into its ``Py5Image.pixels[]`` array. This + Loads the pixel data for the image into its `Py5Image.pixels[]` array. This function must always be called before reading from or writing to - ``Py5Image.pixels[]``. + `Py5Image.pixels[]`. """ return self._instance.loadPixels() @@ -1207,9 +1217,158 @@ def mask(self, *args): """ return self._instance.mask(*args) + @overload + def set_pixels(self, x: int, y: int, c: int, /) -> None: + """Changes the color of any pixel or writes an image directly into the Py5Image + object. + + Underlying Processing method: PImage.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Py5Image object + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the Py5Image + object. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `image_mode()`. + + Setting the color of a single pixel with `set_pixels(x, y)` is easy, but not as + fast as putting the data directly into `Py5Image.pixels[]`. The equivalent + statement to `set_pixels(x, y, 0)` using `Py5Image.pixels[]` is + `pixels[y*py5.width+x] = 0`. See the reference for `Py5Image.pixels[]` for more + information. + """ + pass + + @overload + def set_pixels(self, x: int, y: int, img: Py5Image, /) -> None: + """Changes the color of any pixel or writes an image directly into the Py5Image + object. + + Underlying Processing method: PImage.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Py5Image object + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the Py5Image + object. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `image_mode()`. + + Setting the color of a single pixel with `set_pixels(x, y)` is easy, but not as + fast as putting the data directly into `Py5Image.pixels[]`. The equivalent + statement to `set_pixels(x, y, 0)` using `Py5Image.pixels[]` is + `pixels[y*py5.width+x] = 0`. See the reference for `Py5Image.pixels[]` for more + information. + """ + pass + + def set_pixels(self, *args): + """Changes the color of any pixel or writes an image directly into the Py5Image + object. + + Underlying Processing method: PImage.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Py5Image object + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the Py5Image + object. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `image_mode()`. + + Setting the color of a single pixel with `set_pixels(x, y)` is easy, but not as + fast as putting the data directly into `Py5Image.pixels[]`. The equivalent + statement to `set_pixels(x, y, 0)` using `Py5Image.pixels[]` is + `pixels[y*py5.width+x] = 0`. See the reference for `Py5Image.pixels[]` for more + information. + """ + return self._instance.set(*args) + @overload def update_pixels(self) -> None: - """Updates the image with the data in its ``Py5Image.pixels[]`` array. + """Updates the image with the data in its `Py5Image.pixels[]` array. Underlying Processing method: PImage.updatePixels @@ -1239,15 +1398,15 @@ def update_pixels(self) -> None: Notes ----- - Updates the image with the data in its ``Py5Image.pixels[]`` array. Use in - conjunction with ``Py5Image.load_pixels()``. If you're only reading pixels from - the array, there's no need to call ``update_pixels()``. + Updates the image with the data in its `Py5Image.pixels[]` array. Use in + conjunction with `Py5Image.load_pixels()`. If you're only reading pixels from + the array, there's no need to call `update_pixels()`. """ pass @overload def update_pixels(self, x: int, y: int, w: int, h: int, /) -> None: - """Updates the image with the data in its ``Py5Image.pixels[]`` array. + """Updates the image with the data in its `Py5Image.pixels[]` array. Underlying Processing method: PImage.updatePixels @@ -1277,14 +1436,14 @@ def update_pixels(self, x: int, y: int, w: int, h: int, /) -> None: Notes ----- - Updates the image with the data in its ``Py5Image.pixels[]`` array. Use in - conjunction with ``Py5Image.load_pixels()``. If you're only reading pixels from - the array, there's no need to call ``update_pixels()``. + Updates the image with the data in its `Py5Image.pixels[]` array. Use in + conjunction with `Py5Image.load_pixels()`. If you're only reading pixels from + the array, there's no need to call `update_pixels()`. """ pass def update_pixels(self, *args): - """Updates the image with the data in its ``Py5Image.pixels[]`` array. + """Updates the image with the data in its `Py5Image.pixels[]` array. Underlying Processing method: PImage.updatePixels @@ -1314,8 +1473,8 @@ def update_pixels(self, *args): Notes ----- - Updates the image with the data in its ``Py5Image.pixels[]`` array. Use in - conjunction with ``Py5Image.load_pixels()``. If you're only reading pixels from - the array, there's no need to call ``update_pixels()``. + Updates the image with the data in its `Py5Image.pixels[]` array. Use in + conjunction with `Py5Image.load_pixels()`. If you're only reading pixels from + the array, there's no need to call `update_pixels()`. """ return self._instance.updatePixels(*args) diff --git a/py5/image_conversion.py b/py5/image_conversion.py index ee718cf..97c0838 100644 --- a/py5/image_conversion.py +++ b/py5/image_conversion.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -52,7 +52,7 @@ def _convert(obj): def register_image_conversion( precondition: Callable, convert_function: Callable) -> None: - """Register new image conversion functionality to be used by ``convert_image()``. + """Register new image conversion functionality to be used by `convert_image()`. Parameters ---------- @@ -66,18 +66,18 @@ def register_image_conversion( Notes ----- - Register new image conversion functionality to be used by ``convert_image()``. + Register new image conversion functionality to be used by `convert_image()`. This will allow users to extend py5's capabilities and compatability within the Python ecosystem. - The ``precondition`` parameter must be function that accepts an object as a - parameter and returns ``True`` if and only if the ``convert_function`` can + The `precondition` parameter must be function that accepts an object as a + parameter and returns `True` if and only if the `convert_function` can successfully convert the object. - The ``convert_function`` parameter must be a function that accepts an object as - a parameter and returns either a filename that can be read by ``load_image()``, - a ``py5.NumpyImageArray`` object, or a ``Py5Image`` object. View py5's source - code for detailed information about ``py5.NumpyImageArray`` objects.""" + The `convert_function` parameter must be a function that accepts an object as a + parameter and returns either a filename that can be read by `load_image()`, a + `py5.NumpyImageArray` object, or a `Py5Image` object. View py5's source code for + detailed information about `py5.NumpyImageArray` objects.""" pimage_functions.append((precondition, convert_function)) diff --git a/py5/jars/core.jar b/py5/jars/core.jar index 6e5f32d24b6d8b70d04fe5be3315af4a1658252e..d0919a65e8cbc0e217ab64b96248166b0d5ee95d 100644 GIT binary patch delta 589238 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 j0LB4 zp{_z=?R`mU)oCi5EupUXVwu075X;kX0O;cm@_GdJ3z^D^yf$LAvh%#W zQ4e1*1FOJTPfnk}Uq}t7}$jLaQ0eBW zdRi?!ob*X!m2y{*LU0Q5Bynwhr;a=#nZCjQE0$omyWHJgz1J5(LY8NN~y- z^j%D9v%qcHe07knCMP4V+~`9Weq{IT(8sqpZbo9v+wgaT?u6T-*RpjuhSRi!JECqb z`3>S(i!9u;#EfO|(pj=o<;JMh>vGl{6^@k~BUse0 z1sxH*(@jAzP2IJ@vt;dyJjkIh*jtkx|K02=;JB$@i!^rn_hJa)Bneko>t&)eHX z%0Cfx&tjH;|KpyZQ5}BCt`^GijCpobL~(QM{oD-LG6y^xdr2F5NgI3f8+!8_dyN}< zjT?J?m$xpOE`nAC@Rx$C-XK77nF7Wy=)F&}FOqApi62lZ@=(wS5D;*15FjQ*4Xq&0 zxzk2P2#Bw#$}n`m&xec5l@-?ur=;xAuuv*AJ}R_lNxfomR_v+niryNc(0dIoA)M2K;i4dU! z8}G1>+?l2aBzRnBXh&3 z|Dof-;^zi#^B{cjumPnSeq`uWMn{XJgsRPt2Q4=MjRAB2`ekTsOaZ#IcN5kM2(5OG z02o?M^IP0nZz=>{QJmr*6Lh#Y+S)PndG*jSzRVPU5r=5S^JCcEw$5^udz#G~Ph zlkti@r&BS?EE=qKZ%z4*rs2c1nF%F!;g50Dctez=ayrep7UKeWV?@eV%H$UaO##?3 zL$qyXJ6oK4#w~LYXYuGVAQ&?rjMa1u;;6>EZP5U6xi&Pqlsg9_0n8(JLQeJ7W z<=oGGl><7U*f!q`n!2^W>&j0)s$;5I$f}pjuVGJ;<}_AdhuzU4P)e!ah!RgOk?sVc z?*7xw7Pb)MbA+R%81ItBcF%MKkUlEOM9DgLv2w>%k@whNHx2lo~*_&EiWu-L-ACG*;a=1Qk$q68LH=8rw>fnQu8rE~zkyH+M>CF203HQr**nroARg#kD?D4(Ev}>hd2feO}$J^k3c* zyE_qa^?7L_`#v@`LiwRGtmHIoOhu8LvWgRWuiUP(o*J2O9JDiwsYK(x3G6NrZ(uq2 zK}A$aIB+UxMHtE1JG zToKT)Ygy5-NpqZ5)S)~Cq<`Tssq61@@yt|v?Suk~sc9rnRaRB!m;~@qy^o<fd{vBXd}_lGSV`P(g|hsPgRsTRh0}SM#$I^rQAyW z*BmIJP_IRoiN&NNx26`|3`{VVnlph{)#8h8_Ph%fh}4pdb|kQ(5_yT7lh2OD6Dry^rnb1xh8g5u{Qh++*cIM;TbOiU2YTXeI2ARe)m$(6} z*Y@WZW5!>-L$smFuRebr)xq)dZJA(<%?)#j{1>h#)oxN=oHR$#NP}6#=Q5C?SY%zM zY7;hOA%l`;sHdT91gv9I;wt&QHK!swL904}a5r(BR_G)eQY235@)ixx`<*7TW*0l{ z!jL+0Y!XA5E2E%p4vDikbR?bvHQ$3$v}f6f>Q4QGDdPxpvQ?`fdx$?IL?kB%Yiy2i zrte)Fjjlxtjsv89TE)c#>^r>U7fI*Wu&58cuoKhC+=hH010wQrVuuqN7PD9b;&8?`nBI_^!68lAAE@1^U94LBqZtf`Az>0^c;wUf^R)v+y#6DM4c zfB3px&2wOF0dM-dqM{a=+2V!GGw9k8g>ZnQ9(AAZ- zTG|w#e=DcyT(GtbA2nj+aN=K2Jv7p-rto%-o7idxqiS;knyTn07N+`{z3yP29>o1NXaKfS<}5;TU-k@5CA zt3PoU`BQQ+g|+yYosi279XtontS~R+vpR%-%q~gXbhgKE*NUitZFMxr&sU14hh`fe@`jc#F9!}%O64kQLC|PcTA_Xf z%5|uuxb_4&(uJMp89HjpA*#eWQD8ZeVUcu>#0C8B{_#Pip1mq~2mMB>jv<9n&R0m# zz+@o_6nCCEZ%X-C(s;?K+RF6pMnJdb$G;fpN4C0LrR2FS*3BfgL4j^agx7h4*k>9F z`9~w@$5%E)G5pi}mxgg^bp)K$l!Jz@QtD|Jt}50j+J=GWZPet4@h+F_0XHU&U@*zj zLjjf$KdO^W_yLR8BXa~C70*_aWVax0U{I2{2Y07;Nmq;my;`z*$_b9#vx?Y`bm(8c zc4q%p)=GA@y1}fdELGYF!HF^gBC2jlK*KJU?5Qb@KYeLjKks;K{FZT!)U2)?_j%Dr zOIP5?kH3SS#Znaa6Q{ZI&R9@v2vJsSg((v`gp|kO7_I|wmT}>mPUr%Wj-k{9!0bHQ zR_!)HNL-ie@l7Zz8$Sm)3R&jzw242d^m@PS$E~Tg$qAl+K+myz2}UX8w*%(wARMm5|OzQ)e)azaQl!ZVC9rfW){Vd${VB_v0U z(IDiEqv3`n#HM0Rpm*_3(Ht$}0n;;aH3};3?(8zlW9?l3n$XJOBqhQd* zs&uEhNUX*PPl3O|s~TkWt9Q`u?}=!1SY|^qQl+A-`t`+S^w%^KM^q*1!1cDa6}&w^ zCayS5AS@RO#^%OsN8?)7amny32**ws)67JI8^E58E~A#5oRaVgSIj%rZlsxVR@T14 za;0Tlw2Q??{W++la`usI_cocDr%E}_9>99YE8cjb?RJX#bZj8^xQ(d2Hrfq5v+P zJTdcn=UPLq&nR>zc8#fH%=T>B*?}d!bqcZ^x}R+L7#u1wzpaMh#ya zYimmLC<%hFGnw6xp&~t90DY|~Cffx7cgAOU`kPG!wD}~4{4>u8_`?h1#KO3^Fr~ea zWgJbx$&+aQl@~veGZeD#u#TfC<^p{3ZS-4JRU-x63v-d6$N>Uinmjf-<(i6Q%CoOd zymgC%VD3ch=_f4V*-UrLHzRnOEB;|caw2z#bz z*Z~k!27C!2s<##b(TlE~p;AK43!-pA*H8C+ull?_1g63PiUO@#Y8}7r0D*jLRP=-t zrUZk5NC_;B(Zmy;tKU`}N z1X2LWm5)Sf+5xt?GpW6O!jTjeRR(Q80A|KHg%-`u;mF2e8ykX#pKLuSWQeAw$Bv{(Q19h`)n zxYrM~2NYr1Ct7hb z!w&P}etdza{-GEv<0aR-OHZ`vH;cjyoggi16HO(hm^+Q90U^Bt2IFDsFGP9FGDY{v zMOC7jbP~Gc++YmD*duNFZ-X~Lpik++(>$`FnZr|mLj3Jhxc}3xP8YA>ezuP)fk(2i!Zc(NWA%>o*IvD)|Id)r2L39TaLhl z+o)^81&=3D?Ey14>8Z;muieygR$ZbhnZ`T`sV|t#;18=AXi-a#3cWEgOE5W;6OrT$9P0%;fGVvzXA!_W3wD`UVOVBuD+ZKO8^gezA;%QtRr=Iwi{O!gkLm-cU z*1732u8Xd&x#=&Pru(L_98HepjA@6qoamfz`Pr14TWdAnAX(rHz&@-EdK-Sp)gniF zBw?@qeDqs!}uQ~o*j0FiG@Md4n-bg$l|*0QsN~v?Cf)i z;!^ZVjv_6`@kL>oqKeq^t^_`=RRW zY#vIy##lvzC@dv~8@_4&V)1n5L=fFY-0TR0F#87=+z+%DrXdvD!n(Hkze(wd_ziT| zs8oD$-!Z=gpUKYXv*D)1C1)B@WbkdK^0-q((Ucpn806C?j9A@gBQw`G%25W4$a z%DTJ*3#ULq#w+V$DP^S6L3gEgGytHoXqG#ZNb*0PsUn467KXf5&_O- zpjon4i3lnNg)L}G8k^4QeA-TCG$7w&9_7h@^Prago?M4Dr635KJe~C9=)Q$<8>vc7 zHBg_inP7Y!`IVg=MY6sUQ|W$DJ_QLxuow2>O+An~JP%r(p8)%o1x-cgg2Af3>{m1q zRC3f2j6h&>WORKvx2*m#eM%)Y_`0xQ0i-&`?-EFNT}UK~Q`rtUa2o0M4CxerI;8)2 z{$bXSY3#9fK!P6L;%_Tv6X>Y`m~~=pPihQVIFSfhz8^X|uGG|Z>_?PlI;9K_;PP+V}ara^IXeD{Vl};6G9WC~-eD%=;3h>9juY ze}vq5wZEqPur3Zy1_b_rdnFrE4>e92*HYzD@!#_A?G0cM3-a&n2ZP5o)RGHY-Jrhf zgqaC)_jVV=BNpa|`A5@0a6Ah>5e2;E6DnBlm}Zc0no7Mu#9GMowZar(ukEE3WW57X z{wQ`;pGi7tI)^A+@X{(@*Z{vI{!Ao7{~B1~Jl0mIS1qUso~MuiHw#Ci zuv+ygl(E*G5N8k*zuPb&aQkW7fK+j2^{(>N$Ds%82|S6{})EK z+{|S&ezQKN5SUoXj-5$41U;nMfx9z5EblUiw@{;sAraNh4oO`+sSeAw5>~XL`lr|52%X``QAwFKE`6)(E;CK>Qb&=xYyY^cQ5(>x>ih*Z0;z2zB}^X0<;D za@zb1s)~X{eGFOpV}9384ZR-$;b&@3aljDZzf4argz)ze9dHOsAOZ{{^5F2$s}u+0 zuO&uT-L@xA0g9aBT>49fDYjNj)^93(Y71I_p`=f`@qSGNU(aWCcb@FxvYCCK=(aAm z-%V^0T>QTtvi$Z!fUbD>cGQ2tm?SZS|Ey&&p99F{s~y!w3|^%f8qau%=?57T_7+AkLVI;PV|C&t4+TxXt&EumdbIvMQBLv@mXY-+$CL_mJyFF|IWjCvULPs_J*&`Xw*)8{z?q4$C zTY5Y(onCsdmIm~vV)Dv=+v3^Lt&sHearng-XjAIB6Bc?^8h(QRrgluHE{{1Bsj+kb z8$!s*O1Fc(rIOx9MUV-b9}YJWze53Y+}%O@_YQTgddo!gJBR|#EHX(9Zh)G;v7 zee)tl&y5=wIG(HtStD#THlF+|kc3for|<`BH$HLodD?;7IAYAe@q`p+XuXrblgoU2 z;2|cLF@4gl^vGdyTN75xkNp?x*)rMBX`6ISNo|Ms#2Mkp+-o(UDpC>2FA&?l!zKck z(7e=g;#3zB3M1z{bsayr#HU<8-GVLDLWKRiwm}iRlO-2LZCuqem1?wifA&TWl z#DWH=9@|S^nbFujMOGW;$Yoi+J?K%X#=<|@R!iuJms4r2S3y0S;SBG0E~b>TwVCOU z0rl=?pi_meMzDc!LRc$$XRm!w(vPMdl`W%!c8swIp6+{`b+EF5(itg zKhmbk)Um38`+ci=qqW3N%^Y7d|P=e|LWL$xUM-_q^xundk7G+;N!i;d3Hpkq;W(9OV-f8 zTugSZl7OTpjD_W-%u!`W()wJ*!TOMvWs$jtxh6dkvC#@ng)@C&82GS-IAu*j*!#5w zw6@vPuww0~c7V_?hfdiKS;9wF(??<;rz5^=dxR}Ht9(I<@Xhavru`(Yc!4>ELGFh= z5*6!+Gitbln^Y1M=lB8#T@$E1k{D&&v1M2O3##}e(JK3gOpq+Ji+!ZHT0|IBmOOCN zafjnqK^SP5Togk$qSX9lloQ%NA3E#NlGR9a=VeT_VfWr`unp zG;Yix3%o>+G$8MRk!hp-GotE5xl;V>MI=h3?-NI`2VcHQn~mV8)cXOd0nG?n3vL!(x0R0Z+JgHYhRpH)@ufC5f$=N|mn46z-~ z^QyKjG?l4ebyVM2{mlvT?5!&^{J-17sT){<9WQiw-=y%`F>IPEj$*0qmDsR^FT z8B{ln0Xjec4+K^ed1%j!ah~fAEUK}z5B{XfM#F4$f&Fb*7-ax4s$$RpT9UA@{jbgT zVNH;{1qmHPJ?4Z1p2yCR^hxVd6zkojIX16VreSPME1L$66bq_aG)>^3t}NH&Jd~&5 z_SwCH3*!%d#8ZAGGAaeHNYE){c_Et{s(yZ%RB#{}(Qp(ov;IR!qd1cmkkMy=q7bDD z!{3+?>{XvZs(h3R=PkAWgJ_j z+kdRhsI92(=c}HZyzCwFh3eC=72Mj0Qyv0eC@IqLls=gus}sb7}=N* zEf##0LEKZaVG%B8d`NLl+AnTgvf%-0mj7G^|1vAfh0vI=PGYGV1*XH7nBdc6EbM`^ zK-8eK85gBPaT$MbI#c2g+qJ>`y~Jw2p`H)WIUH~$gRG4L2fn1GqZmeryl7+gIquVQ z(_=F;Mr9}_H*hP5$?A=w53bQ`CpUT&CO)F7SM_KOLPrkS6>IfVMwHljaweSci?OjwcH z>3#D-FWJPf-5m?Tpb$=%O{--%iH?KMGtj%Pm)ygPkbxHe0-;g5BKX9%xV zytJ5^dkU_OUpKUcPK6J8UqK_@vT&4w9!QG)c=c-<$L)MaNbxuQQdSZU%xvO(ROe|uAWz)DsT1q?)RYbKrg;i(ESLoi`_O)hXpZiF<0 z{^Q%l1%A3(y|A&)`4{NJ5aKSt!W5#x1O*^g!w$2fR5--9Rt432RGGfKqPZ_*3y;T2 z;6^9?K;5tv_LDK`B032%jeuy0*T#!CM~(QM?5V`~o0l3*mOAj5IQlpsn8+Sx_8*4) zLjWvFB)0u94Vri#{(ll+S&#KaMA;DrM8Ruf;=p}s@VvcENxEWR`|Y=$Xsxd#v~w=l zPs9+RZ<)aSlCsgO%d=F6d{N}pZap&^5MOvW<<+1XKr_y367Dy z2Xji7F<#g7$ibs^PpJUt_`Eh{IYti;SFaLgT+QxzZ6BcHUw1A>M9MYP6JrXUd!@l~ zSs)r6Q!sZubmHLAtc)Jq<)F?fV~s?17qmo_JF|fvLeii+E`3$_nhC@t4#6J1^Uvgn zEHo-EQU!;w=vjG#V89Z{gwNyWD50XoC)urUwncw)G4)d2tg&k(UmMQ1b7Y0M}8y zV#=iGiI7q5HPB@x`-9O>)NoOrrLz}yF{Dzs%S7Sy&SU2g3=+6;diDET(N9cP)o=_s zIQxb)bL8D_mu6~$16>%M?N}zAkNa7j^>}bNAxBbNjR%Z-*l@%S|4i#?LFt{TForcV z9`)boG1~yQGY}j|fF8#pu;{~jz}#IUMq9WM@?-pny&mbw$31>iFWc-CIA^_s^7Muu zkwhungizJ1#*qVaAp=!ddrp$DVn(H6Q%?EV5~FSrkH6{wNz9BZw!LRuPH3+4J26N5 zZej>9>IBoJrdvixSs~7RoZzk62aRK7T&{`rgoHgmV-D8I7xS@4-<{E$fi$!~4^#8z z?${&(pp%WNqK}+CvIki=NuUlcyxL_Wk%<6yqbJadA3%W7SFcWDpa$ zuU&g<` zEutKaVqdV~2cL1tzkczJkQAu=L#!NRa>{r?(IX8QFnaYwO#b@iJCuj}gQUOrh1rk# zGpKe5?FD(`lRmaD4_KJWf|aglPOor8FYVX2{yV57az-0P-SUrmFp`qLU7Jk<;gU(? zBDKbEiAHpeF!l2PTJ%7sI2E@S=t~y1i^mtV%}~0vlns|QvMsXmCZ6Rqc6sYj0wpaL zwH4(T`Rif+l`ZBy6_=|dHonLn}l;zi2>glQQYWv^$}9D0o`vGj^u`Oo>VRn zhl23@hRQ9$$xfK!!b1|F-xEFdfD~l?jjJjv9H+2Hv9`=wDd+fdEhxjI+G`ik)E*W? z76Sw|wxhuCH2oE3lwgYy4$OYn?}1>=9PRo?ry{;#^|~n{Q>4waSQa!v7mFc@P)qTf zL!LTM0^M`gbVHymZu85k)~G|)zh;Jp5zux)PNhA}Oe zy?2KjVg0;w4B1Em^zCCWKls!6o;x&qW$=N-IxtjU>OJuwXD8?2&VC;pO|<%636^-scs5jeh5(^U{*+w#+#s% zn}#}(@K7nq&YhrADhbBI8UuAP=`>d}u{U0&1rF-NK{sjEo4`u?p>0y5Rb|}r-LbH8 z2gsRZ9=I8^`Wch|jS>>fGL&*BjFOTYX=pKUF-04l+p0*Divr7a98_3{MwP!uHIx&o z3pX|DS7|95)aA@7aa+|1TN=o8wG*o8Th;knqGIi^h}LM=?UxX@G>u@=JurDAwKmlT zdDd_zhmAS6$8^#`BX(@#XC7`!*QrgwOwzLxHImN4x77v*x8eMsMAUp`S69RTE!r!+ zgK5486+ri?yo*-xf@PLNkZKb_+AsCRms*H~`OrRSg!j^%Dd83(2eX_xjVep_in(J> zDoGCD*reqY2mm7Il-NY zvnr;|*_Qk`bs3DH&iFNorzMpbO;XOZ?IJtC0^39M^HUq5mm1NMC)PM@pgI+*&2$%O zy*F;;)!NuKdN*WICyl(jf+731FA%qtgLY}`@UO`a#!2bJJyUmC!a&FRVZK2YOSS8Z3YeI1COx?tO6DaPymUY?kRk+3|-l!jD;ftJk3D3T9KWnF1xK<<5C_pmx1kS#(WYvOGxMmPy;meYF zNnzEJ_B{z`{6jePB*VT@Icrxd(f9{?>WPRrD)ATxbY9#)RP7K#*|fy?wnm~ z(b{&Dg)YdV6JzShgB`fRH*4ovu(lm(;fs@bxn&O|JyVVXgKs}F^hmW+wJg=)D2!?9CSDqId9Pkj-c?(Zlm?QODWCHiu@XTl9 zmTQ~e3}%ZN7Ccu;6v4b+CCjJ@@Zl7OgZBcm%V@P^h9HU{S4xx8a@muxPCP+P*;pCB zC%V)_*nkZ~VirmoBQRv}=07BfF77mZEcTH!{SFr5!GSY{q1)_hn3DfB#Tm$Wwo%P* zT`qvw@dP_)75Du%0k>%`_m{$Y(yXX2{F}9+Xz3GS%yMq{?K%RpvM*k#ZLM(b6D=mt zrWTO#L`grl9dzH+x(9w~mbzY2%nSp;4 z}xGdl}`Pg9&0(H7(Y1Z_}desJs z=yyAIs~ka;y{&yZ+y*68#uMe@#!3WiBq0>E%VR`oe>)ZNoSr}WPjkElp@RI#D5knJ zgqc?q5EfKVo~y(>9ozk%U#02l8Cat!7XXFN0i$?>CF_)DoYE>7P^%#FxG~I`E!*LG zm5v-e?mFTzDeiG0UUEC>xt#d}IuK{gc~7sAy~EsUty_k#yAD6*(Ce6Kb6^t49+m5S zA=8P6RmMFux5y1&Bo~sTH3U~*#613BN+_$CU;<|?@~%a%z>loH$h4s4cpkbql3IrM z%&a#fAtfWLxM-JkHE43+g(z8Mldg{h2TGw@CLM(5WvTX$hP@>s8+?v0{s6OHkNfQ+ z1WEgneKWD^tKU?&hn{XZOudxb%_ZUU!22atMI zl^9O->I%I>+aBPI-K%hIFVPCUB~8v9bkW&Y;|L196e>BtWYu{7OY_=>Yg=5Ne*QVz zn3Jk8z&mP*ZfhSC+p*=HW09xysT&hZ`C`vF9g(N%C?69O`W~i_JFW8()0OrSyW-Z#WB*qB zvpRw%@ob80V7`DVEgso=mmXP7C6Y4iP6 zYbnN`KVxEFHbCAvn(u|G%EbhBrdst9pc!>+ivu#fO_m zmSDo=GFAPbH?yY@!BBx(MRP~vPk(>jcdfj>?g37r^TyTMH#-lxyn*)I2?l{Us#8~Q zTYS-uJWn7gT>vk`kOddjJ3OigE6(ec)ymWM9Gm#4z_sV4bnSRb_=c4oxq3caY6sAyNGUmZ{qvfvsP-yzpb<+ zrddpnIpbV!MB~5*{c(~vhrS0s@#KIstI{0?9nA2o_#w1~#uQ&5$9n*)8!8~e@efZ3WJt(q+idc*3q7bvxMluhpAPQk3>44oXC zv5q(EA4e%4sEn$VArr~Q25SrkYmWwN#6Qt>E0RjN@G#d z%0>IlFpC=s+w@AO-As(- z?0h}KQS33;@_lY(*rLNL@O$e0VKgESPk3w=~!6GV;n7d@VCm!6#mo8*QeN#@l3uE_8A{xAdL;^7|gE(L|g%n+auWa`VZHg5HHqq}F zi#9?@aBGJQY@uVe)3741bNQLTz^2n68$<2^N|^M(qq%S>;_wB#kHfQHU69ay!f){% zv6|Utag{^(i8o#Zn8#6D09=wu1G?(;wa;tsqF3`>1hu|)OQ#2l00o4%|_ zU<=vAs3V%jpxc|#-41h?q_C)1J04Q!#6-#{nkLTgq*ujomQt4ysHQ*-vzJV!7tjy< zlQB(oDR2&Jz}~3lvY;aX@tb$DXtocGYCaK=9>Em}^H@!)3bMebT(f*dJEz`-*9$xS zRK%44Mlyp!`#GnvX(ZaExM;-;i&PGA)lCxXwI+xCMzv_8V$2KCHyGGbqg_GwgG0kI z&MEaWn|9eu6(EE`(_x$2Wak7gtb0d-w1{Vr>`>b3m9Hu2Wv)$ykhMl7qh15VQlo(Z zvR&LB=55Y%&f!J8H;p-8avp|u?{F^R-DvwR*v#gjfrFd12yfchF}_+@!_rdGio3D6 z5kqwLkuGGkSs`emRykwZsR`Ox@!`_v)zarkr9YouC03YibC6Rt=WwO} zOr`%wr2uM8$uGe!)Bfa6(|Nv7Pq}oL|8ED%rQdnT@h5r6RmROr$Ld%ykm&za`YPom zs=V-p^(6gTX*qiXo_2j+JBI4cDQqL`)rk2Q`|tmjQY7{@xQqf=zep=qd~?axHNGRV zE_=kwblGKG@%1h5T2;Dpt$pXLpkO0h5|OG~G;#tGQOyGkTx&o4TaP5=nm>aghJrvz zL9pY835%<=gR+9qSp>)tFH-lcze1v z`J;7Z8UxmK?7b$fpz?ef{ioXa%Ud8B!314%vDgm_9)n=~mL$o~x&qe+6x|LuyR%$` z7;S}}8!4CWc`|EW8fngK@^J^=UELt*H;aPmnx^KImhOftP~hEV%y8>2S9h?*@N>M) zKd_t_peV|L@I>aN6EpYl75$Sqq|&=9q-UleVu6o<9UDs2>%Tq{ zf+z*c+z=rlg6Wfq@Ukf_paFG`A?^8aH2H;x3DK+eyz`S0jbEUjSLT?>Y|b1@_nh1T z#ogXtGwwmzqXAW+53*WYFjL?b*L^xeQcK`=1HPEbmNV?@8M|R4EQsSMS-8|HbJAac z;~B|Vifa*fi-;;eYt^me>+ZChX2%AOnE{T1pPPrrX=Td+w?IPnEj<*6PJ z`%nF!Q)37V@;o;b5>EpWj|+lJF}}{bhe+nN$9GK{2+CIvz$mbl0N%e<(y4g#Kq_G* zA$}yGoKaF|Kr8L1wUdo1&t3UQ0`_V`><2wxJq@bfLW8pay1@~dwKE{)MU1{zPl+#Z zZ1wE+Nu(B*cU$LB_tlSMw9tRF@WYA$Mc8vEcy{F(74cpG{T6=1oY*$iyQ=(7i*2Vd zTW`cAzqXQ-77-Y%N}klzV>yrWUXl7^oy1?0vAi9k?d1SAvB(b@o6?qb1AFWvNB~Uf4*F0+={iR zx_ISQ$so;J;FJ%I2_)h5*ES~Yt`*0Rgp5f@!XO~1>)-eLs~5p=gKj3Hx@$Vz^LKoU zw{Aew8{3&905id|IhPxh#_y-A#dCvZ^-qRSP?2i2Df`Q z*f$=;Cj{IpP2Lrewnujd3+HU_PjLXVgD?{Lo*n2$HI=*I;{Vt;cjrazf!-2X= z)0PpRA-Om~2*Ha9&3a#5EK@??iU@ma3F}J-df2V`-8OjSduCFEFDkSny-J4~k+zt; zt#i;w+L9wxI=x&UOB|I}tsL@IncAoYBz`t_l=^bL1 zkDQ;A-hZg>A9E*bpUeURsqT+zCRL3SlAEIXq#~1Rp#_X`lWUO=eoSzj=)p>)-%A6& zQ~jsXIwd;ZNtjjQPP(OXWnE(qUxcg!@!WtgBXM)pLJ^zS;hWbe_WvOAlYpo?MwB|c zx{^nc9dO{qv-EcAN;YJ`QZf7>v2B$$p8u9K5SwUInFKfO31TW_7;?HR<(+dNwzwY1uiz^RRa zL~9>n%Ow4M_5y0usUg%=Al`(G43EX};b-m^_aOOL{_Cr}7?Hdvk-RXGyg*7W4Bj`( zg4vmn?a#H@9U+*omwTfaAft$*U^4Jkv~JZ94CnQv59#x@ZpskW^EG)~Ir($HVo_myPi$h;{1-W@K!u=Rzu7}C+=bgeyJ^ZKvJc?fPQFxF zrBqloajjIvw=I(r)J*U*evkVfs=hI}vY_pDVkZ;Zwr$(CePZ*(wr$(CZDV3*Vozpr z^S*WKe)p^DUiEZ$b@h*3)w}w^T1sTGXp?8uNqg#K{UcXW;!C9@?_ap+*4Q*l&T1tt z%87HL;yRI0EwJbpplT(n6;hZ*B>FK?t}rx9r4>@?g(S7Y;$3*?7qDt2w91KfBH~>i zU-IG~!>T3eJGwr*|7@dHWgm zXw<|suzv69KEmH*4O_}hnT8bR%>xfc`(iSfc2F7|MUKp|*4s=x!$*4|TWt`ncCVIja`nbS7j zRruSH>vG^3kG?FgGfow=b@@iM5bGzg_ zHP-2mM*uRgy&gwy#W&cVCHb~yHxL)CBDGs~%g#oj`R^*xvOK)Pm;d+$5I*$=My-od z`64f@?w_Sm#g}%*ArK_$lX1xTYuYjOYc=BMGd3fa_ZVCp!R!8&KT@B2_tYx7y{ku# zC^J{mYltyy3hy^^=bVOBXtH~aXQFl<;mwY*w*il0EJ&52;Q6TkUCMlO6v;B%6HYRd zl>nTTBb@$30-+&gdsw`C1JF!+Rq!)+Gl)bH$gyE@(8$;m%+CpbQurz2f8G`|Ar&zR ziW&REU;ID@!O z;Q`*z;uq$@YI=$2U&6YP$9RNx_2nsH=809Hl70&(_V$U56Ed2SoK$}+(KQ8JZ;UgZ zrgQa!nlIER7k!~?LLL&ZHKh((Urb&gQHI-WG|Zs&K@dOO9H;CIP6l?=wi;4rUf4L; zv1WL}Wat*?dlN128UX^+E&{dW0Fbg2JU|B!(fOJ%)`r|m4oPSS(rijVAowPY8|xdj z6BrgKu1EbImpX^SE+~Cmacxy5HK)*1FF=lOx=xs4Czl}N@^_Jx_dwF*PJtBC$V#e2 zcWKq9K9O-Xwa;b=NET}{I%kIt;YzOdn{}b?28iz71e-28@k&EM;^8Ma>?fjIKQNF5 zHK)E=Rhy=@1T%jZdbgJ_Nm^>*1R@zFHrf=(VBq@uhFrF2KntBXwCYUdgpa^N)vtjK`(ZY)Yh_Jt4v%B zu_&~-afS%L6*%a*Q@#~%Gwot-bjd%?>5pgHoR5#&7JROJA9|qG&f%xA3^tO?(QY3+}6dx-Nx@l`k?(tFMu=wVfXBsLjZM~=YrtC zt^cwFeObCya^r%j4VgvJD%l76yD39PE7esBkGTIReX6z>?9C5EHh$$tf8S{Qg4Ar9 ziZaM9YoVNrV6kN+>N1$$GeC`nLAg-8W_&pg-T~)k)*6=OeZ*$mYYv|QehWn|qn9A4 z*}l6j?2!6d|GRGPjEmFC8IJIVv{R+EIlM863{tH)?xa~J$wrZ$v~Qwg^t4>lICI(= zfO{o(TrKN(v%Cf3cJKw%Oyso_9dIpY#(=53seRV^+SG;T&s@%+4RAJ7kF)%q>Jk3e zOwN>UmWyXp=Ja;9mv2bs{CGC80BU{bDPNug#sf-ogl4AY{WP;*toBen>-3w23voTi z{3%k#$tTQ=pe4g0W0veY?J3K@w$2=&Ro=89r{Gm{siulo@Fe6(mrc>K>$d&UEV{y0!!*4d%q`)g1%kCEg zMTSQN_bG$2{S8KS!?npHLE~7Draz%M*3HV{z;Sv~y%{R8HZYIwp}BEEHIMS4ak{Wu zw+%<4!~82qz<$#<;Uuj!Sn&9d8N2`v%8Bla?|F20S0#efymV{0?y*%E3+5IN}(8Qsn2KW#f0 z`VG6ZfPCKScHk!eC(ZkZ?NgaAeLs$y7JB-F?Hf;vnZDjkeQKg8l=AVvsE4bm;0HGl z&^`_O)Ot9j0}pes+i?Q0*o&#rPoA8>$6#5k00Id8vn%G9XmfhqsB>`S-6V0sVXgSN z0rB5vuyf`_K;=>%H7KJEi1s0Lou6U7#a13K1ov29BSvb*Y1tO zfG^5m4j)QnUO8m23jea{%7+R7Y2ciA`e1f3x7VYqyy`nxly8Pjo<`wP*K-f*=my;*L+tg z%5DVpbA;Z-UhM<9&WSaGhBU2{$_?D`jvP^rQ^+hAIt85vT=hYEgtlBnj<{$T*-z2S zDj@zC*-E|#S+ILJ_OZ>TXS}i~d478sDhQiM0lLkjqz?X@XEmvzk=r3{ zt*d`->Yzi5_rq@uM*r~D?AykVJE+>ePixwVy@rqb_*&IBB&~nl>`EZE2}QcWso#{% z*5>}7!u__9!5@4_J`lpf?IMJO?7OVbO4`)Di+}FH@q|IDIcVL<`lnAu@eQR4NH0HhFP?-fJy7?k zb|)43l)FekJPMaP0}Yl6;lX0}CLEFkdpIb30h-vu4yV~xyw&jOH<8^8Wx#17UuLZnQj%Y|Y*6&XS#11u3!4SYJ>~#914Pt z$?&!B?tP+t5LOkhZ3Ts&7&YchKh3FpI{JGmMhHX6^!&W&Gj6u(2Y_Fb^-a@5aF%|# zgtNgH4=38}*AMr*hnuVHfL)36w;#HKM<8v17(h|J$6Iqw#GlrYMPYV0a{1d;#5DB! zUJ?3@@pgoI2(#ly2E2cNRF`2YaKEu|W&V`d$FTOqGB*0LE7f2RX-qt#vz^Gvn?Ttv z6y`?z)aEX-&;=Hz^$HwtwB?LxxCwz-(`VZ3!Y$Kz_3l^SgfUIhRpx{+Gm;98gMB{^ z_V=Z%GaOt*YX^Xjgg)~;tmBgBW643>v?SxnLOG!YO*GI-h3bV(?%^Fi#L|uMF5xb5 z;_Y)37-sb4E_-MotdQ$b^{4M4J+-loz25cu3X=Up`Y(qZ;(tlxAnDaK_(Xgg!_o;9 zAZdW|ibFy_zn@LhVcElg+d~aZ%%43_q z12DV71)6zpXKwm-^Y`i!epomCml)mg$a80YO<~U)mRu>RcO6Ti+*zN}`~b@j@d63B{4f}d3d*ElzQzLW z5R^taJ@Pv1I?>RMLhaD3Qwpc(4*41p{bu1u$W_h?|L`@BNcpXP7@rZpLmFo8aCx3= zSB?w7(q;*7faqbOMf8myJY`n7V^|yxmSfx=e1qWsko^7U`#{CqSlXrUD?%~?HT}K_ zuAIy-K9G4Me}BiXwe9UDr9Z8Lvbn62JBp;Q$?TUX;$){=Yq^}wCZ(G2J&Ic@slm4D z8d?*CvfTh7jY>%Zc*`jQ0qC&0o56#gDXC{hNNx7`K4?_^d!3S+>rL10e;n@5em!=d zAo{COw3c_e!PhWc3X4O`wyQ2s zf?r{AkdK|cvH8I~IIGQidnHHC&pU;M+C&-cgLPsg95!Ta<&u=+rjysLlwqc*o1Qcm z!dgW2*WM~Mou$O7ax-jL!#xzsM!f(jX;F(cA14T%&ABUZ4ffa5PP~H9N#&*GUG9)QdU!MGOT`^cLV9!%!U=z*G^U1%aKN5LHC#qp6u2#Etzm%G7}{PBFP5giTJ-X(Q1_o+joV7YF*(X-5$ zCT%X^H;#%Vx`opOK976Q5hW{t40>@DFEv3qFwUIl6g*QZQmqAD4+1fZurOdFoQ zasWkJ{fdYaUYlc0jI*1s{N%{vn^>WjQ};B2u4!kUpf}K{Fb<5JhBh~*+o}rG(`}v* z<5VdtSu%)m?28BPXT))xm2nL!j=PZ^C#w-vl7_;7>`Bq#%Epf;OR&&Jqd@?1uo1NJ zldoSMe9Mskn6`{z6|FCWqQ7%4icL-MR8qi>&3WEuztJPyt~lZTQkPTGh_22w-Qf~G zm}j4z>EiXAmPT)5V-3~Dza7(OL!G~7f61bD4l(>}i+cq=z&Y?W(|V;;18UH2$9HjV z7M&RVErq!Sn35;Q#v+Yvk~ZpCrX~4WjRjZZ=+qN3nEOIY{{_S$9exMY9<0K^9pY}j z^-((3)Dp{HuRMPc7O@|V-EYjPId4o5L|MiorxuD$F5T>kSFL1cQV%Uet8&#Ikn#vj zJ=b?dynzC@zy-;Zdftc)E-WFWd9DUYM@~av$JRUgJ2t9MWGAz0x0Zo%>YhJf_|ivKU+A zsFPTIf*e>obBL^*Xw$cjsbuLU)Pl_1mFW~)suKg)+z7N+0>tr&tGFpGCe?8Fw%#SS zWmteS^us$W<0cXxj&WG~;QIuDH@_d|mMFGQaoYeHl{!Lc-Dp?Vv zepZzEzvkozFKT1)G0EARSx{IXN$MV*t!|pHGMUb5b`h~@?_+|CdI?vV2|zRLpaBQU zxh_-6eB$NCGfAddn>7B;n(B9Q>I-mE=8svaU(=F+c3ZqG1sOlWC^gL}11NT6{8%T4 z<04LB9@Sjm%Lr?D%##=(1Y?nzB#eqCT|pRS$45xQlxz zkj{sWJ*m`4YczEZ{%qp4yLgJe;LJgdC% z`v9vVQ!=fn9Me9ka+()r6x$Jta2SNuBS)@h^`I6j)50gF)~FCusYw!5sYy{)sY#Pn zsmailQ7tWrToU+ok-8*ys-#UN&RGZ`mv57%*2u1=r|#(pkSw+KO#@cekw|MZ7;3$~ z`*t}5+8Dqz1dkD97y70Zo=d4R`J`B(r|)BTL|p!Y&g^Az?i1?cH+wWlDV(P;3=Mir zAd5#PC%Zd>ePjE5q`sSYb`Z;_e<1*-So(+B!(jy3ACLAAsREA8A5sRK%Ri*{IG=x! zW5a}iBch@ehB5~UDtbVLHW0)_*l^`YQnLf$Hz(9AM^+stIG%fVz*vHOm;JQ&t|zDq z*{XO^F4aAEBtyIJqi~YJnD8;Tr@}$hMDyKKsIIhFm(4|0`Lv>DK;2L6ce*KtgQ&o& zwCD&vm%*evmIrvpoCOrK8z(kZOzc5$4i(-(74`)ld|M_(l~mwF$Mj^ow3p^2CUxoq zzS@IbN*+=9N$*wKubf6|S~@0ScmYy<#}RQ+Kd!^F zLBcpIHt->2B!ogf*8Z6YkEOpHLB5z82Z&3DWTSs_p-tB)#70m^f@GHt>BJaFZ;RPu z(BL_npouXGA~%8ST$w(x(V6QVn0FkexAsFF;ZZZaZSV*>JwX~_khR|iHckr*o0YlM z!qkE@Uunr7Sbf?k?e`Qj?>S%VX6Lxdh78!~$^lDs)#l62ny#}pntY1N^2i6NOY9;U z@@G0_18IKA6h)PMQknFXvq+lc70d{l^p$)Rb>hmiNMKdTeRRs}cl~Qpu(=MV{c#H} zoYPt?g3}U0dBT42DdefTW^c3c`0|;w)jQweufGcbE z>>=7@3w}!Zz{q)-m4?nKjmJaS)oDY^DiVM3EUmkEFxW5ht#J!{s~pMgR@ZKpsVMi! zhouu(Rp1FB+-k>InAwW_qH6NH+H}^md0^=DCtMoD!+Uy87bM6SJM*&%S`d{ z=J>gicTQX)rBnm=b(xxgoY#bn9cyUw3eG^j^f$TwK9FJc!GzEt#YTNea$M8=xMob@ zGc*P-u)jrZx9nkq?L;>!<6)CL4k@{Oz>q%B4XBP>gZb;nRlS|oDfS^E=bW+Z0reA! z^}RZ7+V+sMu9ogSd#D@g#vZXdD0W7e;Ftr zCXh<5@z$8UPceK92|&GO(g+ybqxr3KC!cD@tdi`hD_X}7tv&Zj3T}Pu>$IXn|){I(mi?h@qC}lcp2d!%>>^smnV(9? z$?Y3F;N6q`rYCE%8uotcRX|BWH59K>fCasewi~nobv8vMVI|^VG-35O^lRb=VG1h$ z2h_jetAGcb(Y$w)*z;boO7!k9Up<`ZO+uTsfy&mNW&&psQQoyc#g-gIh7V+)x+k=2grWIT_e{m7d7Er+-Uyjv&XHBQ5&!u}{^KoWO9 z(u$=NOT;gQUa#<~xOaSIS~=0+XLxPZD0-*Xt)b7cY@^TN&57!)X{xQ(@0fEB0hpde z?WTzMP=$Ic(|%Bez8L3j#49-Q*P%c;wsJ)nIDtWq5@Q`QNsRtzI)uJK3vNrvYHi7H z1@&Bm-PfiC23Xd9PpH_e$y9FFr0^J*uI!^wv#X5|N`4uZt@JM-TiLu7*mM=w8iw4W zNSqIUSQ*-Gz~3!4HejEaemhg9Za+IcK(6pPk4$Ud>y21{FF8iRzk4P5@`VyG+u33l zrL`8NxYtYBidWM6h1R$!A42O#eK^n*@S72EtWE;g&Xl)4TCU*P)>Uu%q^`yrRFul8}(bAmkrmaLrux7?4Bh=8j9OBhIWlrZ93I9t2!_?7EyzL z$bE@Qu9cv_8aWZZT&~Isp^f~rF??sDT-peOoe7&kzaqa>zC+^hW0}m@dBdJa?B=%> zJof{^j@)yN_;u#2V&(_Q3fIn)I45c1O2t5&^^BC!8TQc-!5y;kEysv(A+6l6xyIs8 zIrc?z!A`bE?qfd7cOXWHahwWzu%pLpr-X0@%nLWTov znZUD(7C%I&k+VwKH&B*Cugdf1G8P$S%v@J$>(zZu!B{J%9QB zJ)rccr*A16>s%moX%ofi`-lqWX{rmTk?}I&oTsWle z;>ol}B-ZI3UBArz7olZwgS;wY@WcD|qudU}lKJ0w?F0V4VH)&$69{@#NpEYAD=WAhb@x4_rcR zXsyE*c3vJo-<64|BDnS$gi>JmYZeM~{{hqq-A3}z$KIi+Fso!rQ z3o9=OOke3k;^q%WXPEY74~cu%D*v3J8N|qo)Ewi5cN6XwTZ06=JAk-9O-i-sZIoYa z|F?&N)hOj9J<15O93-cm#TZfp66hod$+%XGi|{n>*@VXWS1rm!n9^2Qvmn}F;6g=7 zoC&Q#zis;k92A6hp#85|Y>FSA8DoiwOSksm|AK-KW78bibxWe~NC~_RlrmwgVJkdam{H+P9l1I#jmM7(3J|6xecSPd?e` zm}YuFH$J2t7utM0&_$+ENS{M)_be4-_bd|wwL!^DaEKRqPxOa;Y#1*A3#o;incz|{ z^4{o7IwqXg(1h=sP7f}03$C^yw)Rn$apk%^D3PBZBCRguM!l(A6|H^wJMk>WAXSxo zUoLmlSp`)du^I%?jL@bZ4cMASVT{Sj7fQja3eAf{eTA-vAP&x#sypMq|wrWJ+W0?MD!;Eo?_CN<#KWc21{f9y@Ci%;1T4TU0K*8( zh{1@|h`k?CN@n|93ulCeJ3DRp zr^Gp4$AjM6KHN%h7L73Pg0q0W6s8fnLCQgDb4;EAqBq(h5erPka8l&Bi zek!C9o#F;sR|>L|cAyh?CFXC1%WRnfD_!owwq4U@TRTTwC$jAc#gLf@#R-(RlLW z3Rv{cLsp5X645zAhR5I^B$NwhrC_}k<34zK+r#L5I%2{E1wWDEe;+P3?(%W9g^!QD zJWOl|5Mc6#OOC!gW^8~EAa5VuH@JAQUGovZ@#aeoF)SPvc(aS^Jg|{$vZ~3>tHAli z3&f+?b1Ap*@&i1)H*TI9b}x+69c&>n(`{`b(SRoCe^ufyoi_$K-aXY`m#Il5@4d7h zL^sD(M$euWCBMr4oENv76Kdbs(7#HaqrW=pdg6;nLxk_<5lQam#r^ybAQF)O9G0U? z9w{KvkTJ=Kbd#$|9f=^3Aa9I|oRtG4j7W$Bl17w+Us&|MOh;BU&)KljLCNuzj0%>4 zg?0+zZ5N2lFSOiNLB9sOt8C%iwjM%gUzW2H5q;2cfO(Ard~v==e|4rXBl@kispat6 zidqhda(@MFpXsQ(BZNVM1u7{q)*%e*z>sBzlZ**xw~> z*vIdw6`6!+2*6w~G-{wkySxx`ba{4N>9+GY7`y5huY&@#uev21hT_(DM@HGb3SU;f zg4-z?%0jnmH28d6>I3|H!++Pm>a>+t{|Zk)y@q+&$U~G6;ok`9^6tWdYUy17qD>G5 zP>*y-k|dFCETc~t-A)k&L^5MOT6#;7$MRr<{{x%;$9VqR2fBdJ2zZYSIyFwEB2dUP zD43hkqGi-i+fa>Z;H?5)g4w-ax_LK2=qAK-{PvjeLTP$?iS8WnuVi?O_`?Hx?coCC zqZ!^d`XYMimf*T_KF$A?Bo`10)W=)nTJ)TJONfdg3bA*i7$N!9RFR<;NWLa$5*Z1) z;)cqSrez`bk!xV0+bqFF8{I;kU=fde@b6HpqyG}ReKpdNF(|uy`)7EOG&+AyNB}y7 z4;Ly3E#k8y52(i23d>lK90H5Rn=%G|%8jMx!o0*#1mFs(w(0}3XXMc{)kEpo%`gG2-!TcTtoBJ}F zp$Ha~d+>br)AUm?Ph+qAfjB#|p*EU$`xtxvI5-CCQ}b>M-tg!qU@YovN|{;-%;?kj zzfU$4O52Mv=0d$x{kado|L4Xt80J068g`$;m6+S4$RfwEtf+Ne z(GdBa?F=!Z#6o3mxH6@qwMnKY-Vx=Lx=%BVKB68OebL%M(oxg_ymVyWw;5SgBW-^x zmg5dgi$GIgd2DH@q0uYUC8JfT@qm_nD{Hs3FKdGy$Q}k<&dbmG?&4$ z@{m5n%1E_jA@ePO4Q!$ySQMe=8T;}H90e-4Khq%PEWDK#`Lk};T{(=4>FtEnaFr+#GNzsiihS61>n{KUY-QnSyVVyU@|Ivx znRW0HR$xV20X)_NPYv+yJ(Fo-cpObSp*B;$5DKr z5xW&YVJFngR=@^O+$XZfbpFv!Ii+KgR6|ZNtz!~ZLk`fEMVr(ysj49_o75@NT0>bj zr)L&jLm_WU%b>Q6TpDis4qzrp`NqkNo>?bam9vgQb_tD~Yb**YMk;uV0?@+FQBF*f ztuV61!-3}*n32sRc14LcfJni3ea;VSrdv>40a*u96Jwd=E~)SD5O* zSKig=LFpvdNJ=H5@4&K!qGNt?5OIJ$WrhKDwFW4LDEohQ4p0oT&PVYXB_HJTlMrs8 zd0JDxfO3e05c4#WHdI0r=+eOk%7^aJjEEU6@AIq5fojk(6mgE487+_6J+@=boePGYW?&u>0}?9)OjU^<0G{+D7VeD~{! z`lx4-+O(sBUUk)yUK6p2Onj&!Vboqi9d~g>LID%K2@(_Jc<}tflZPX*s7QaKN?l2!YalNhHE4nhBEqd4c;v) z(2lCfB?ZCXPE=^y$QrjyCX8hC=L$UX>;Q*c^8eegtwe_{gC?rQx?&C4X55uq4VYNw zIJU)wZ9!lq6HPRMwh4={Fv67~6Kyo9Sb>pXz`zzBIVL zza1v{^1r?(EYUwC_EzJQtB>+~D&!)vhzK?*^b`a9jE{O8Jv!95*S~M^1f@QbE{Q2m zV9Ar1@`R*5(k_X){VOPkO+E(0W6p-N%41%`3Cd#*!0cb9Hcj^wE{~BM^>Cf?RM#t1 zf%ILiRULzGR4b1Gh8C%m#~=(9tB$=t$>y@yms+|_d1l$;GMY!2teDVv_WsCsbi~g3 z>j%pxfmzEdgjt_~ufhC`(uoi5+`07=v|Gjw=3OK06q*Mw6;U$7q18GrVi?(t>yqbX zIbAWE|Fb!mj}4hIQMN}e%`!0*b`@&zF50>dTtVKN6QRn}r77!y3j9Q7B~gv^<$wX%BxoN@{2TFoC*L7 zda>4ZWo(+wz*8K87*j9%=+_CxU*&xFAo6I0CI)^Y=vp@PVFmJG!kX9yU2AuX!ldB_ zte-=n+yorX;ZX833P?CiZl3d4Uk}BQ^g{OinXe$venOlkcNRfzMoVXo8Qd(fQOi z&!dIRJj$s~Xe_gf|83l`nP~#B$ferP_-naS3s}8b9^fBS&6msMnM;@m7o7qsdySF> z^(55-`hnDb@-l{xRDRL%LVI$^D<2>CGu_qLrm=*CVR34k6zT+}2Ciyz-%^U-ZGk2b z7@07m#+R{~Vu?Qkm{R;p66!POzrTMouX;>ZD%x7?>%u+=b!lU-9<21w%u7V z!Zbg6O{)!dlfm}@Do=i^LfpnPL7B;dIh4|PT87*w(m!yn!T#bmt}v4&b*QHC+ynob zOr!Xvq>kq9kP#*oc9Q@mrQuLtU50;X7TaLl&?dIF#B|SATWzRuQJ}B z#O}bSYRjs1^*G+Va$k?8!<1JU2h=_facn43#GoYzqtg6@S8h0Frh^H`DzLa`5nDwu zis&NGC#J!~6kTBu2&*ul3jKf{V{hPI}WIeVzWUoU9&(2pGz|=>=z*&cmglmXik8Q~6 z98-@giM_|P6{|mXGKMfFIu<)tJSIQ3JT^P_I7UAvJ7#}WK4v$DI|d{;!av#`>mD;W z@;gFQ#q!AF9@9SsKeBhJa*Efs*s;~Xea(D~finBCQJ?0{^CQFMJe%dm3N~RR4fe?# zn*qiu%ap$H4)qYr)Nj@~RQ4u#?_I5LRV*JQx_XROJ;=!7(Qy;RbYUuLf4bxPw?k*A z^aw|6G6D?V5k7|C5nJG)+F<{+u0$MkG*!CrnDSF3SJX67Nq{E!*H*rRo`Odt4?}QF z__?oB3|+8+=HiEF4=AofnXc zZ{kDy97pczc?0=%w49Uc?fsY%=R9X~vzXkiV8N8y?3MRun*4~RzQXX=Cb!7_!h=*s zMRPt0w%2v4Y1+XNe9aRKY6nt}&M2w-Y4x>z%nl?p#r9{NMTqGucj7UKf(k+`zOrJ z=URK$c2csXtH(+)#DtG~jvU35@HH^{4CEUlY$VtNma-fvVsn@g6jl*p@w4dz4UD++ zF*`+98yYwmq! z2m#l#*O1Px!b6tyl0WVD%@9YBpbaz$iW}2VzVL(tdC%n$RQ#ugNyfrpzGw(q`v=(& zX@4pZ%i{aR;W}|k`dJXi!oh#c-kW0iVU=`Io@zkKfZO>EF#DTsoaA#s~#J-Kepds zada30dsE-Ob=KO^k{LaVwPKF0Sloh}JzH4EK8&R=-PVQ9!A0S8J16;_E=4D4ntWj*qTz)T`;avLog1PW?!#5jTpvMM{vs=!co&L9$qQI$zlzi1m4r) z>W`xvIw#!p27*rrTFiY2!Fp$?vdqaLB&g zrZY7gKp=h+uzI@aTB9vV`GaBnQRWfrlIg0F&~X7!AUkV%VH;pL{)kX;%Ykbh?}f(? zU?`EC5q|=6Vg5U#C*qJv|D@ZT`Y-0JKTB3T4%jJ&mNhNj=v7oP@JQzpTEVG^GM-Ht zeR4`|f}W?yt{EwRYQt<)hb($pc?imP%ch8`nNe<;bE02~Ic)DO$re4DVdisg*9e}$ zGd)fGNb0Qxtw|t%B)C#C++Wx}MO)V$*>mDEN&eW%-4o5qX_nHSW<{)9$1U43#XdgN z2wZ<)WFhLvo?8gYK6zyk>pThkepvTC2um>#Qg^Z*!F}n`Yfr;TdHs&-@zTj_|GW%- z8e%7P&pIuGmo~sQd%w2wds+YTU%9f3_5V(@@RrUgFwB>|oHy91*#5fzH*8pz6_dW} zjV0HZ(mBG?nDh3Bkyv4*^*d(nq!qz#LQu<PzTeK0$`CTLKp_-(>Tfx&U(v$eFrYLBNx0D8vxQX~4aVz~utjLHbQ{t?;M^Nc zZhNDj-&f91mHS*Q&J;K}IY(dp2nBC$Qg*q&xb5a<=IrzSTm}C9!KC*!1c%3l>I$c4 z#1x^8qlJF1id><$W4TpSI+(-*Io9wn_0WY3-*OE!7$tBF9tW?75NN=1t*fh~fmvHi zJ9;KpXCD+;wxowqgTnTlN{7OLDu=pEV~WV$Svjxi!s&6RVn;O>W*cE*(o9`XW2_p; z-teV~Zzjr{;#XfClv%_}rO;Z)l<`yJX{&0gvoS|VrPNN4JE`01YDGVsLW5JO6l1KX z$CCs?=+mD|KrF5fW*r*I>pRZUb+xU9+`xCWoP%%}=wepXRG0d&(oKZWnTco{d3lZM zjA)6Cj%y_#^fI+)2u~ej$jjBhs4-GAR*w3gisZq(V?326C!R+V{?VsfSLw}|RFM!tTXeU?IMGku0=1YNhYeS`0P5>HjGd@H3ElcG{`J0!5G z@)Ep?XE7+bV#-!izKW*4qzkq31`Q4r)LY-H)an|IhQ5`E3a3~lv?!%2O-o6E)6+KC ztvH>L25GCEzOV}xF6}!;Fi@xDp`m2g3PD@3W~hr#r>%`#p}e}Prf)eYql~X-5NFd+ zRr%_s);ku|y5ghw8>OXFW(BQEM--@DuI<P5sapigIN33YEojowgSpkM>4iZcW#A zuEyU%%!icYuYDtWOt+0;^bFC)rz~knKED+bf;X`a-=6-NCzJ1t9?tC zUQKkKrv{#YPCsMp5Si&VmGl(30#;>oziC)EKzJKfi#jN@A|cxf$dwL6!cgL}={hoV za@2JUaE0PYcYdg^=sMD>zXhdMdLCpYmhu&@#{< zXspva4gZA?vv{7ak!OTaD+6k(Yt+aaqK&wUi#MRDx>W}c%J4BVwEOA0*FOoFTYEP& zsafnU1emyT1z#H&q%0G_y$lI7Ws$2_pF!Fv@h`lZS++mb!cm0(xhw3A+Px#P?%K6+ zXB_(50P*Jld4yh%J-8&ThPEiH(B2dNLPKK~arbu^C6-vEfRv(~xgwBx0uQ&MrlzX7 zJKex!z0}nCaK_rDtbAPs$+nUcs)BQ#Nh%^Be?VZo;Oaao%c#KB4)rSM*gJW{pkZH} z*^2urDoqpa^(hI0ahMj`H`VdoG%>lt-8b-VuU`9($6C!*wN#0gu?NN>^R5lzcAy&` zMc2{H)y+*j0djOd>k{~bx-+r2pkh6UgtI5!J5r&h~2&8z_iES=4ZE- zCOHr8+Uir&L)I40;(;RlTMQ50su%T|y;OBn$ETv4a0%~3iTxQ%=IDU!;@b@&aTpW}WsK;yaWlG~|FY|1M{Tw7 zoQfw-A+N;9VUB^2=E5ZGuZ%L}x;4>vsm}0)O=?|yv1m3y$COtR;uoIUZT#@v+DK;h z=BspzAVb-a=eFu~<>%7?yg91$Si99pSHz*z7OHGX(QLc|sy*DtLgdH?ztH?dQ6+cA zWb}j+xq@G>?HfNN5FNdK%%YFx?=0ELA*)x=cLEYdA(Me)-qo6G42{#3o)x2EjR#WX z0WU4?Q2-kDAtusolCa~ZL=0Tn4Abjd2)3V#^x#CZ`d588v7P-4WLKS(e8COkzbv%flMZS+HhAF z)wQi^b!Mh&R*8m?zLaRis)zY)A`*SztK*K0xNAqOXVYk211iZZ!qr>m>*a+{gAqIg zO|=as`deM6CTgo$EIwF$I@pcfw$dbY)TUyH9vXOH77Tku*OoMf0V`H!0xoP`P2U#A z@U#?4T-mY76P;TX^;;SQJ>S0ZS?!y-d`yUjKluZQ5q$I|P``b=#*MK(FgL0IE+adx zLMBSHz#%%mEc*HGol)*f`@Xw$T6ck*MGtUY5DxDY7C?_PKKayqxiVw8TKhn?T!nb?_j^fkxNng+M33#_~sx&hnT@{ z%w(P=#_b867K}FDBhf(Yda;dVyL4EUEiT(x?H(QGCQUl}JgML8;0?vH@_s zBd!;j+p7J2H{_B&3p1koSK~%^5iXl(LC|aEzKx8ZROK1fGqXI#$VtA=H7hgQq%~No zpK&8&WwcH~S;&K->c5|r;k%V2*{AIof8xf(?UYj;V+EB2VpYCcHWbxNHFUSw9x@H>+}p5qCN7)80gs;9?=)UtOCWbjL5(s6^x`q{~j^vB@4EA2^G58 zS<}YVB_VyIh@W}sut*-rtqMune7`KD0R#k1z z%C#d2LSQN( zwR6XVyQ-BK$s-iCY}3_W2EPCew8Lj1!KTBU{^M~m;MBLGD~T!K}^xw zhSJ)1nO-Le&DQKkr4CM^xQ;&V`ojL&9G@<~zo5uBzR&d4i1xFG*9?Ic}RBhKWa#EzN6#{={y0_yL54tDy5TNZ0{>l8xlwp2FR?By=G+ypdc66N1cFRwh*J^t5nSe1;AyK0L7W zZ5+$e8O)_0rgXG26i%f_q0O0+$e6*q)da;@bL*?1O$HqX+=C{YzNHDd*?z3lQJi3A zDTNF@JkS`J21ajBlbbFi8%@eY*B@3Z=WJw?_?!}8n)n;J<@y2tC?(g67gmTI*nPxk zYior0x2oygQRV_xAEp;0Y3mtCkaRB{YTg4EJ_(?bqPCdwakH?C69Gj+rOu7nhS5eE z8VuDnIP<9G49O@5EX@15Aug>c~daYpi_1v&y1JuxA-IcQJPejmfDx*NAe-92G-Qq$1VN@ zb=0T{F0Wb@H2G5uVt<=DeO!PhvDIGwBxrQ`GZufAKS!FdvM$VJN#=KSS%tq~@fT@H zAXWqyvk@UiRv5=riGk!Li@(fYLFO!OT0u2v1$Ds$QjXUw{yKky=J+)=fwg0C))F>S zw2lVV|1Abx=GIhIE>5ppxqMNuCcUaGT}=Ceb-@~%`tf(D{eO2O>s$maq(Z+P$wdt#I1WunmdiHVYRW<1o$4{Fwe)i0HYK73vKeYHq{A0Vv#d4)- zKz30}@f9P%741r^3q_NtGoQ4w6+rJQ+6+tV*uKtiHAkl(&9kH=$geVmt#mZeoaZR znzX>pe?ghbH8Z?FJ&?XGzoe?FrnI~=P!~ifSW+;~=Af7V#Q#le_ss=O2(bb4sD)2&6@q~+?D7Hg9ZW#h5GSgTgfv;><0p#lPzXlY3V&ZElR zS{JlPb$_2)Sky48j;#$ZrZ&1-S~pq-j1H@HYu%lNaye4Vu(>|Vu_CF_v!%uAxl?v8 z?I-}YoNY5(6%(}_3(7U0Tg$UY+F4CYdRlLK7UV3V>-$<-KkA{+QRCJM?YqY}EdXi* z?7N$a=ov~f?XimP0NLDZJ6v&bWc;2|6 zsEAh6(JHlZq`&|2X%n=Grgj_-Kw42GGY+jCresI(0CMq=8adw5CTkek8s(LwGh)SL zK2=P!wCUOm92b|btia+a5oXQOk^C3Fhq^rr<8N)YTqmFJ)`}VQpS>iQ9ty|NN1&%& zQh!yNj@mCgO8Ih}GLiM8Pa%D;4%98Fr3V1o36?gGMhTyYAnfi@Cl*-Ri8Pb-)YSwk zYjNBNQt8Q9Dpqf_Q!Fh&(_^Eis!mpxP*H+c3uW0O+JDkk(B$1!i{4OBsKpXnf-9*mjZ&*EZ4E^s zu9_fffvK&F^ibUHSHUVd~JE(zLY=T(k_tsew5#6X&1?S0p%~Tv`g)LKXLu#mUe~Ai|enlw13Ea0e?Z+ zL{P4waCAc0KMX^VOPeii3$0kV#PYaDTd!@P!})aBNQZ5fwp{`!r2HjxxSS4G(cxxG zyG7Cy)wf#OZFat(FXivBv|TdakMeg}+TAi=K>2$u?LL_o_wTl}20LFU?%!i+du3kS z|A3`EDD&d}hb?Wt%okFB9>xA>*ME4mwSew_y*Ox3qJ6XB^dzT09R|@s>QMjK)S<4>@Q-5LfO_DF6& zKcvANk7}?Ft`W=Cv3N7xS2T9~tWbmTQ>V>dIC|l%qAAlSkC&~wbqq}gs({RX_^jfw z%5=3HNMWYE{+HhLgtYVY@iRm4=1iS6XZrMMn5OmKv0`o?JsHQSsed9UmJ_77$yL~R zaiFH0^0H8`!@vcZI;$=~PPtkZcW-mo1Z{ti;gQ^0pih@oRg~kT zjjhDrDh9lA4IS3f0e?MoRG<#kYti(o+Hwj-ai$t!VkMjxZHp1t+JPlK;1gLfb&tGO zQbc#TO6&^^`*PH`NE;gj0b>=ZY;7x-h}I(32o~}M^Rb21l3)5#48xEgC1NgHvv?7C zTrxncT8tAZWJW+dBcUjgp0vu4i5_Lk_=k9hp-fP%F55eA#DDsbo#1Qe;ptjBtSO`v z9oF=x6dl%4#X2fmN7)i$d}Q-s*rQrhc5)`qHzaYs4rc@S&ZNQjn$<-!o&QyN<3>eBk69+F?QvaC$r(lva& zsM%W6P_ck17JqJB)wG_C#vEbM5}QPg3?ejAGGDNgD3y*2)CK5yji6gPW^J9lkAvbx zBq!;|v{(Ss=a~9DQ(qVgYE+e)MT-^dE|KC!+iA+>E4Amyo+cDG&v@o zqwpA7B0cdp<^0y3Kiesfnw{E0c1}9w6j04L<bPsrhgW%tg0!+W*A~J?J3F$IlzkTDy^!@*`XxX)9yPCNRLSn15AX7aZ!=-$FT!uc^UUj|MbsB3+C|>Ea1! zI&n$ezI zalTiafi~w09MKRX&hhfxS)QlJ^M4G9dk)zBm?!fm$@6%5U6ITOWIibK%jLOTmamZc zmGZn+wtKqFpC!-d%JYTtoNV7ud#*(OTUq`kd?n=8lW!OK8)W$o*eTAh%lymmiZ~y& z+o4IWIKM5=@5%Fr^8AT?AI(_B`73$;M#?o>=D!#1F?tC>oCiog50>X)@_#(i<~vQ- z#rY-4k5qZ?CeE+nl`b%V=`^c6Rp=)`e$F0XIjjN99K8YjIa&k6(xDS&6Die&4rz4g zaj#GX)CI@^FH+9M#@B-fc0m-}jbgqRlHfT=!*+Wx4#%)O$Yc4s3$M3qV!9z%NkFcU zK+Z)V{OPB9DkdOZVnbq$$R&dIWk(_9HbBpuRK%5& zyBl&Epbwq<;;#^Y$Kr1Y{)RWgC@LS@02Amuu>mI0`S=EyO6O?}Fq6)+8lafYa~ohj zofkB~$#h=W0E_5c(g0<2Ufcjn>Ab7~D(PI+05x>3ZGcsDUflre=zn}_1FWa>84YkY zozH22^XPnj18hv)0vhpB6TCbd{S~mG?eKCK@^U!zW20a&8v`@gB$&sJhX9)b&4xyu(W26IKOZ zusR{5besE1Mqdh#!hb}Hq{Vd;(=ot~!WZ=Vl-q<{syz!_x?8GM8MZ-vip$B33GRW5 za#9=N(wzK8xUxxi;^+#t228dVEVd3}*{Onlj(w-1AE)TY3ExW^6eqlehSWStl}AWb zHo|n2-tq!=2DsRn4jnX9`-alN%Okh7DZH%>*w(qNv~{iB7JqHSY|$1f>gMpaF2uGr zw$j#h!f+Wq1(t2~5jX){IlE!=J*p{#3fZL&TX%(QUH58JBHZlX6?XHEh&TImD-uWi z;k{_UUNpAS3mS)r@XgBm)yTHGk^LrW!%`5?)}5#O~GQ6qx9$qg1GIjFhTqlQ4lc^Z{8JlGlz&b$40#Q?(mzv5pRxD`ZGq} z?8lqCYynfR$5C>ZVv^lRUq>T;2P<5_eWU39)QI}nC4WpG`Jjkk;v?&0moRWlhnuF%G%2b9iCGWNbDAfi@Q&M82CIbZuhLc(0DIV=o6+4dItM4f&=KSPz`8jaC>AQu*sskcqp9gd?dR7$)1R07b4kHS|QsRgHb10 zJyB`@LVs+CMI!sCO_oIL)D84 z=s6PTP(*R?07T`)cpvgMz`=S9RIp?}9$wv!#gy3#Z(t3ja^_+2eEpOLc-5TNgtQAb z3;bF{x*6j57U;^agI@f47{YIGAR6jGqyvvbNpn~GoO`bs=ROE=jxryKOe1_ELalJl z?SDo*4am7hnZpeF@9c;ks%fm*AH#S8p`a2?;eG(v63>x_(Ov6 zhg=UC^R$c^^YqLav;JG*Y11;uonL(exPNmp8sN4}^3Nid*#Ntm7&!t5MBpzVBVR;D z9)#}vC1l(yFp0kgGx+OpB7Xyx@He5BzYQDsyKo6k2Cw8Fz;*mX*v>z8glIdI+3cYG zJAz3&Xzz{;(a?kvlJh!u^%Kijy5#jNA%Y0J{#-QO->z)3NYym6n-;ann9@Y53xB3` zK_E>Luwy?nCnK{FehhcbUxUF9IRZUXkunu2Q;{-h_Yt`jdO<@HI7vW`(1Y(qvm@-v zwtFC(4fRD=eL;(%*Fz+!B4Jk%Nd4sKfzy4Zgh=VBidkuP5A?2jxAtW4Yh)S7NHEkF zuKJ>>zMu^B^!5q--W~zb1Fm|Ysec|2f$n+_Nnj-Db0h+PIutZAfeaDDpQUH&S?x5Y zv348liPHePv18h6%+-El@QQ3KyS>Id?Kh_P5|jL2m6sbJC;etlOs7WpIm|G$1TeJD z4u5AVfA_13R3^%($0z0`G{D6+H4{Z>v@YP%QoyUFItEyuLg))kQ0R>&*?(w%iOa~* z8{yyKu#Um@vK_Dt1?xWw);6R}bb5z|l;7o$5=)ssL?*?xU51Pe@TZu}H~GY#7%796 z2d0(}mew2mT0iKd6+p692wk*+kgW}dd~JxMN4-^#dOJd_M9}?K5l%^I+Ze|)lSfAH zIZCigW!RNwV*v=o0r0F?i|DjMQ z5$T?!nAAF5uENZd!|6^&x>JzuRHQot>CSA0Zmu)TB)aoDKv!3E=ZDjsgLI3L?p&lh zAL%Y=g>GILU3w){(mhK?AN^X;HEg;XEyZZG4znAUZb6;K^P~o-Y=6Si1IIAXN)ZbN zo?01VDMu_zp}SUrI^0mp5_(FsmUBl98-=5Gs@ zt**5Qs}5nUL|AJO)>?$M4ti;)A*|D3kamWHWrG#V2J88XWdt&vK(aUqawkPcpdz-` zKxQ_wm=2;m2T^W7lz-g79`1 zcoY5>Q!^S_de6YaIZ$V*CO1_$kZ*!)UC+W>yfG3T48D*Wp|3Hp&${SkW8K0 zHb`V@=jJG51jIxMR!SB<1oTk!xeuXJOT*iPo~Spn zt{nvb41#|a!GAx8;9o@W2O&#)2?vZ1Te=~KHa-!?Ver+$DiKSY=xAgp#K7^#dL(<=)S^a=!^?#$ooN^RravVM?1V*{2jnbNO z+XmxsQ7zE?jA(vAG`}L6{~(&*(Nqqjsr=zEi(G{!SNWn`hgm3G34e=84p-Cy)=`X4 zkQq9IL@cHFsk?4KFWqc~Nqxe{`YFogbc{((mlKXg_aPb!(fAQf45EpJ9(o*7jcR>^Nq-^FakcaudF|kGc#amp5)oJu0!v0~3ChA5GXhDEMAD;> z^jIW44wZa7D*1$tdV)X)JV7%s4o}bm%_Kx~JffM5Xr>{W>8Rv0km}68?+F4O@B~g= z4o}bmRx!ewi?B{WSPKx=iO8grkVz+Z)Dr|c;0c<6ad?6jXci%w5=2vqXci-yCCH?5 zq<^~f?|Xtk2RuP@TnBSO6hpeGWEdDO_1CWTqD=nYD|-A+8n}9!3oN5yK;h;c>+91Y&ry6%65`LJT2MU4JY^ zbxf-moKk9m0wZx9BXJ!gas5T;svm@&`b!Q89ivbjqa<{UlF%_NB~;h}3FWtt(5i4; zZy~O?5!XA2>wV4Ac`Lm#lKKOKcj?x`F~$X2-bFBVXco^SX&n!3LQZ_exlR$! zl6L&P=SVH8val*qk6f4NqDsSl0M-8ECVg6>OFnP%3VK5@dl(SP!hlPeBP zS3JbKIze|=0`zeu!X#G`l(~}O99Jq_=1PMtu5NILt2;EfdccFOOnAzb1<$*V5nMdZ z=8xjy3;MBAJ6_NSN$q$+A1nvT7xW?WsmcrbQ1MiSQnX{vkQ*ah@hN}6()4H&1NTE{ zHyW)vN06kwjjhbCbVxFUfqy9sOdqZuTMSlDc7{j{4CCK{^7#W#DDl`#4%RkxJ}|1k3^?# zhMqJl5&}K1IHM27gJe&(WQJfjmXEbA1IPU0VfIJAGy&yU3Rx*F|9F% zpyCWg#TkZ*GaUIa0&m&H`8;|VKsf*0Tw2x^BR~Vp6eB-5ElCxlTkyaK#VaBxiTG6jTw+>%!E8+7W6k}!$_kT z#u@YAcw;_HHx|GG<0RCYg^vCORR02w{^7tdQtzyT_*!sFF2X}L7vZ5swk@2CrO3q~ za&d9TxX9=;w30-rB!OcO_&3w*1%Hj~MmpR=hugx&9-|H^tpv+h1+m6z=xnTQckHn@ zu+qnOCB^NM;wXD-i;w8+s)xcHIpTuh8O$7~M&n%5I5!zYE zgtH;ZI0w>=4baOtANm;=z!2j?6w5^psG}6rQO(EZ=$IHkqP&mN_>goX?E(8%8G2#?;bhZW*F?09xNooHn5 z)x%hEHSuZif7Ry?29c-&l{id&y6qn_r_QJH{(z!D1Tsn$k8W}OJF16Mw$8< zdf6$S52x8Fvi*?5;Qw(rjC6=g>626V2aN7C=m_*@`6Ca5Irs=nVuLZ!H3{7jeV$y# zbp7Qrr-%YDX8)HR#HFj~DL&T@pBmZEwqvV@F{*M;PYQfW>|d3$XqzT6kIn z95{_})q{@V^M7wmvK$D0l;sa7%OBBa{}YmppHQCvM0x%K1C3u{xbbh4>u+#^@jC>u zY?<*VoND}~g6UZ0PKQIb45NC(aOGl8Q!e&22gmw?*AAu=WdN0m0hDD&P{*5)8`|ZF zNjm2;NF0;=zC+YHc>UpjWx?ma<|q$mW@4>_oGionkI!rDg?NVlHP(&8e)`T*1yTYuK&kO7^6= ziXAXlv**lpIO#o&o95}jEPI|^gs#?3od@6O$74!ot5~+3f;GIS zKG~j+^F7Md?vby_dik9?z2a}r$EQG=`%g$_=tQ~;Cvq5i@joG&v3|+<=!%m~ocg;& zB-gL|$Uoqu?xyQ^aG4?ZqTcVd{R^i*%6|Y&@352a>P10MJdbJQaVWl=MxJCBq=*8F zg?O5HjXUg7lz9XA&212C?u4%9jW{{H8M4h=9AR%SbXP0VFa$vXfE_i@rN^8t>daw8vr)1{oeMm{7Q)NKgrc1SkwfPXY| z7xXdjg8t?`j`f=X3e*6}@MK8Ur@|x71&}@_--0;l?-HnOLN>GL9aD2JA3izP4ilXK zL_BWZj||@pmf3)u+2i0w=!IxEcm+8o7fx|lh(&TBzN>Fj<3q3|oMbR>PCOsg$j401 z)e2&K$d@U(Iu45Qd_p5XZVUJ^HGdgXo1ybwK6QwW+1c^DxRIYQwH}6G?nHIj$)U?m z5to&y%i_cDOxE)od2om;*>wOCiRoHQr$)Z)0bVKi&hB}TSItXy?cpmLdEF2r*?5ev z*$f5A#-n`A5HlI&wXTt`Z{!;Wx)a4L zt`;djrmn#hsvkADIoWJl%B#d#44981mmfpMJ&vB_S?Fax2ffYbVVL;>OgCSIIp#qq zF<*uy<||NZz7D6FZ^D`8TX3cMHvGeU4|bX#!0qOTaIg6h>^DD#r_4{_E%Q@&$NUmL zHxI!P^Bcy^Z<%TSOGt1X(0?DnjMAs+)5QljLaBQ(7?^cmp>L;2!9{A$w$!oNNbsXiXMO#Z-40W8^T^UH-C@# zhVCMEVauCgYuM|(ZY{#iI&XSKdx3bV42_Pauk=J?>o%YbQm{><%wE3ZQGRm+gs&~Q zy3Cy2^L6lVu}g z)oVGjk(7e)W_n;V8Gn&q$q~++9u@884YI*^@fxwnhmCE1TCAvS&J_yn%DD%Haof|h z1j292-N*0bfXX~2?`d%5-J_=cT|(1-e&5u5tjfPfgt(uxCPNU<3EVjl=gx&r?tDmb z_l92XKG4VA4+gsnV4S-UCSiKIdw_~#dx4<`X|Wfh7CWWkEPtn)ieqQ0Ud`0Yh+%^1 z7>9Q1LW55dE&Vb2*1Zz5&A85_UqtXclGYnb}tH%xr7!tlXRi z0c+pWU=hxJ_HPb1t%T9t?5Mhmr0RVS@W4nC5n_tW8(Yr|XN= znwJZ-=;SN{uP>3{e?VOz66I33C2gYKs+W#POWh&X$hM`4=hNHL3TAE4j@BRjM)XK@ zNGM3Vy%O&>xEF)ly#$q{9D2ByLvME_48!vncQs6Q*MGn)cO9JIUIh!?t6_HZCD~RJOD8JX#~UvKXI%o9;@#Im7x!k! za$g7i+}AromjVT@K(CPAtUzC`p5374#mD*(R)3{lCBdC0*Au%c$C4l&%Prta-6ed= zA>Q;22(j$yz6reUn^9eEfzFstb>HS#R_vmDMOOu8Cjh z8;9KYIh-?B&bjHee8+2-o<{zB*!zv{Jz%)^Mtbd%{w75`5C7c{MSl1nddX5>(e5km z?te!kz2dIdL>xwYgb$<7L>hzX@8d-3e9?odhBBnl~g!+$<<;{Mptq~q0dIR@+W$C@Fug;vdPSP2ao zxrn;~QHT2CjpuLDtF2=354#e!SHS%R+T)k#OumL>_aTf)zJYZ2caZJ=KJpw#U*+so zbPNh|tG-%-IbLof_vEDHX{^};Fk6j(LeKRthp~H9!ybK&+%@mf*TPp6SraC>S>K;VC3#xG{(&xfQ}hsxH-{2JUs=!w8VQEI zER>j+V2DSWctUP$Fwi%AnUhAJMzB|Yy3nn!imfWiv^YZBQeNH5-ws=5bN?HB?%#0U z`a5K}4v7^Z)iqORq4>6uj(AndB!8@h-`>HV%8hxa%S9+{TJx)RM`+p$J{5;uh z>M^4~AR`;vCBMfo2xq~*2l*#Bl6*#+NIp*~n3|Wb^=;sv=jH2o`YM0F>n5B#<-0KR z4Nj2re0X;3f)LvWJbl6P^n-X$0d(;cLU&JpIL0#o`gx9pfu6yRjX8r9szDMJrOwdL zM9lG!Wv_yUe7cZIGRuDqeWHaro;gFp&YBT6=zA7`={XS+ zJtsku=MP|Tbp(48mI-74R|7=O@lbdn{B`iwAV z=qX2>OA+TX#94_rs}N^3^!KcAY%_GMtthMm6xIRiix&gzFJ3f9eZEBfw)B+C+CiPS zn|~exj_I#tnoJ;0b_0vQnNbfJboO1n8M;t{ephdSs0aB^^Wyo>d-$)9gzdfZtiisn z#lEh?zMc-5p7qezbAKib^_&HhJZHl~&pEKvbFRZzFH`+qrux0iwvS_yuqp?_W2YFpkGZEbC*t&Od= zU}RMx`|WsUKKY%InbGO`$71S`7*HLo5u?^e{jJD`VW7vy>F zgkwE-Ijk(QUk-itWsv&p%OLx+FHS4FxK$>YEtqg$J50Ew)wbL%+S=1jTbC-2`lR%z zGg>nAh+-&Cb$@B-rp>mADG%_!#OpI**HE7n)7?(LD`twGhmg|`Bd7NxryqxG&y#51 zPr)$HvoOK)98C8-@9@Dh6yzC-<1@r}hqy>}Q9hU~Jvtuya+#WYER!o2U0d`>gH}IJ z=XnX?y^Qc)L3po2n&%A%2b~kIW}l}+5!2snZJ#i2^?w6(o_CP&yGZywB>W)~{-_ng z%|1{^x^=lOd(15Hp&akyZaK!{I zCh-rL4NUW@uj#cR5<}_2gm97kjv_gXBKZSF@)wHaXk?Ly4?a6ZqIs1P-XjOqF>Mi^ zWXp?|Y|}PFvU(UFos*ir!H;2fei7 z-ZV9Yt&4@D>(4{Ys+1~;g)uD(&D0ooi$Zs5Q%Tr9d~XJFDib-Cg`CQUZr)zd z$A6mxeZ9S5l(!Ge^7e(<-a=U5?GG!w1K>RGK)B9(EZpfG>==aaQhd8hd7`@n2SZP< zTuF)1@qfSx$hv?0U5kv87Fi}N^6CF?i}a3w81G2P@Q#9P?^xuAzw?-9v7iKmMKl@2?@#;hbh3r zTG*l=ZLt&KR<;-=ac^oBcbhh+u0i$sf3-QW@aUi6V=?pVxrqHF=#f`_nw6Yb`BcY2JHIzaIE(NnBct-ioF}5%zKeC zECj5&yH7%iA%BgnEM#nI?IRH#c2Y;Is*_Ug@bBw*uS8*8g~Iv= z3hNqF-)md3swv^)T#~Y?d!=@cZHw?sTRh$Eaju1Nb&hOYwND7YDlg zV4(MYRHyr3jJMG-&@~y?ScQ8m;%+(6bt3r6xUwbu+gpX-Vxa5P0i)~WjDLz_B3WCE zKa#n{L`AZ)Ky131V%gM-|&ILN(#uKh(g z(|Zs$d0&Ftye~Tp?{>wn+m+$nE;z?So2F@iLw;SO<{zg?Z7XQo?2@I~72hTM5i8~? zjfs|FH!rxLbv`kI<&7a%=)&yFw5~}!{%XDH}yT3S0ws{t)g$CeJLH#z7(hS z#b!EGrZ@Ny&5zi%e`42u!mj;-D)TF<%)e1(4x`HafhuzZRpuz1?0*A?nk-ZuTd34z zq3B|`nq1qFiCB88A8_>PVESB;=rbV6=Ycezx0U%&ZrDUj-`o+xJzD*Oqb~{xMd9g?^7Iws4UIhA#dt#_PplYk zbf?`xc}Ie&V-$xgTM4FmMfCT+p2+`WkpJ1p|6JsMK4kiOLmyus7=Y)YzJm6GDb^)& zFhzg%TH-z=ai7*I?lvv!7^h_=NA%!bB6{$Yh#p)7<-UQ~?|);l--EEPz^c_!-RS^r0RIjAFg*m)yu+G^m0%~^s;{k^s>KGFViFHW%r1B*`p1;+=TtU2K#+2_IoQz z?gs4ZHq^_VsFydQUfzUyd2_pZS=dr9um8IN?qI2x>p}r;x9|YhcRQ-sE>y8Q5$HV~ z4sb`R0Drd)#TnZ4ji5-1gQ4y4$coc|3~WRO?m-4VfQs`FD$c{GIQvm?9!6$9)~@38 z4-0KWiZfD$w!0+miLK&pQ*nkm6{njsgcb8_-&5Fyr?CqMunW&4YhOgz2T=!JMGJn- zA^V96^h725i2{C@>~GMwN#vDsBdz!v$N_M%dw+65-w4?T@uF00&)BPtk{=2Qd#LAo z3&Fh&9^bo=;Cm0Ud>=TrFyu7f!r)0ks@o&(K6*85_mS_@h}(yEC}--}#{&mbdWYZs zP1{d6^_>y_%+R0V&HNZ~57Z=WwtX|tM;4egv(6E3^KO%yJr-|=FX&-uM&=%E>{R=$ zaesOLBkVlcPqtgg=Ar%lyht~OBD1`?!0dg(wT!DY|kE+HLBa24o% z^LO*FuD(HjF+a!NRTEaa4Q6Bhb6IJ>c7yk7eakXcGi6KFy-j76>dHl%wnB7*9{OWW z1N8*g1{WJ>)E})*&}n$;u?4d17r(adgn#55v6VC6RB}Sw2{7S@50}2VY_OCo2Jdu@d1A zD}}kNRF;6}6ss#svw8?QornhC8+zzBGWzOIFeE&2Wf`I|9Q^{>fkH1{g~l#bz^l5ymvZ%{i81 zA#le2fa#+c`<ezWg~?K3R{=aW!glNjWky_i6Jr2>Xi-)^Xsn zFs8I7IV?R^sdTLRs!go?stpoRpMS_%B)0~~|e-_D5({p}U~X63*~%b~=RlVSOMjoQMneP~uSxUChfY=F7N{v?uKAE`N?6{)$) zvAHYSY3|mD&H1bd&E12|-P?9^TGNMQCqw9i21I4JyJL$Vya?ykxfgz-yE81pZRZABB zfq0J~3;%3|g?C97u4u=+YFe0=pMlHIA;zzD*t}M>XI^zJ%**dXDi*~0{r`n|-K};B zkCrF)_~{$n87pAFspIS#q>P~GaGuVRkByAT&e)V0$k z^@R{Cu0JLxcei#9{?7B^;X?dfjK9k$b0wOo&nIm4>M&dN_lBPS0tZ>gmnrpC`aPr$ z*wxT?<#75SEGo&N4u5DIiLOLrpLVU;f`!K-3kN}>e~9C=b4iLql76q0SCW38lvk2| zzf}JueYgDVT$0`(KRcJCH`hX6w{_e!zJ@~sHe~tLthrfp+uxA8}^E+RJaeTlF*|W!HkAHTJgz^_ci3R$`juFnD zL^IKy=t=Y@`Vy@~e_~W(bYjdt?UC3PEGt5mO@dtiR6%u@-ColtcNNR>6wC4y%kuQS zl4W^@QW~^pb21x{S6L0n ztVF#5*?*PjYS5m+qjmKbNXpE@V;thblaFlR>dm3QOr<@CGa~I-eLH>NM|%b*?08K! zao$d*kpS#u9Ld2>hHic_Y+mO-2QB7Y@cPe#X#e>rn+qVte-VuGUk<1HuW~#;U9Wn+ zUiEyv>iK%r^YyallscfsUF6;xj84bOzk6lSi+@HO|Ji^0>eR@^pfgKpS(V&Pnw1i- z^<2LNI;WgRecp6EPIpqyYh>~Dln`RnUJiR<*?$cV6W3zLu7gbf^$z8W{7q#vy%aYQ zS8BLg4&)hPl<19;(1&qH7;|{ zjL-1l^vmTNmua8JlkPpY87y&6CF)d0gZ3H~zSf|g%EwlcBx#6jH&lijQt7`KM*>>G4GVfXp43V0%dM`CdE^(!=#4 z%Rb|ElrVf0{AAlSqpM{Yug!LA#PP$)=0R_v=}H zj!?EtafMwe$`kA+Z2Xlr@X85N34i^vg?ey_%QNXSI|(^CIa%|u3H-f@ZPvpp85tLy zR~E1Ru#_e@i7w0xGP119vZaGeJS7@SG3CaTm1vYv+Jo27_foci{g334g}=c-U$g)S z;BO`VE+nY0!CC!(M^R}jB73uq&Ca}O8=IYZ$2K-Q^Zx(d*lvJhP&J=HV|x~j?K#NtKMzCvFTxoA zL73!!31<3Vh7Y#YufBod9*@8o-}eEtfY1FFlP@Bjs_z2(xNj=Yrf(zro^Px6 zoo{%*@ozf631H^u)py9>Pbu&IZzaKh(FLcK2)(sz{6#`yBWS;&kk1!XohN*UKi?HF zb`Mbka=!2(z3j2|8-$#oz5H9>e@vYx2ARm>Vway3><#|T{vzBUm5v2I{4G&fd2*+d zrbqWoXyG?`AptI)Qg8QYVMYN#?w@X{B||P%UlB27I+m_H-SM|;icq8D66gIhuKQgg zr)83IjHO#?s0Vz{%ckdB4BXhdjyIo=eM!zS-Zp=@Q%MNY6R*iMp$|&|83+N=17AtA zkx2(?S*RmJSgenVIom)o&h>vj3vru7lrk~hR8UA2%GkJv!B%P}`p5?nn^Z`;;*Ul_ zS~$k&=y1Cd(}Va*?TDVeGWiMpXl` zxdCeU`FlXhan+$cPyI*o=MAf+29L@zBR2_&Pm zyh(PWv-yg&RhCH`bz67S4v(^w@7Y!ig`pnpGK5QQo!xZ-%H_42c}~}fM3ip5mgjqD z6_2}2alRO-i~}&#AgME&r~J=a7HJ!8r=)PdkJu5VBkG6vpDz140YU2tots9PN>6zv z6-VPNl>CjkcPE`X;OIqu`y8U;6W2<>e3oO5xD)cbfrC-CqkgIk8Q_-2?!g=4{btZS zbnF>8F|sT|MX)LDl*R9MiDky%6so+np5>Qssdyl0a#Iitu_cSo zFZ+Q(>3v@oh zht153lOEB9r*;n6<rg(3&03-Fb2Ia%&qRR}rlgLfwQxroDP8uX=JOJ<5=j9{9AVIGB! zrQfcpqj29i_WydL{jTk$(z88VN`d@pH?Q=U;)H49nD7{e4vmtxG3rl#3qOfl5bBw*fs+@=9Y-;Zmxp45a9&ESHP-)2WVuDKb9c- zl#?%Ku9lT|Hpw?>U#Tp>%pTE`xDvy%m7!z9;rbdH*F)FYy%Z1nFCe!1=@^5?KvX|! zttMFn#m0;4gEvCDc8X#PRys{#n)o(uTB_YtgDrF&uKCP2B_CH`d$v@6oHcJVr}%Mf zRZ6dCdfp#YE=391uIW*kepU+8bC2C|Nooa~vuON%UcIc;~N+Fsq zx~KQ8CyAAJg)a+e=@n8bpnoIw@tsG6aeCG}o&8PsVB=irphy2Eqx6Fat?}2jC~zND zRKpT;LNFe?N(*`dWqFU}|62?_!lBP)?r-)NqXCtzl%fY16Powicr`HMDdq|1)01Us z=;?m2>o^F${rn&~@6vdx9I063h{3PG6M}x?L|Nb&Mbp?^-F+o6@m_a~@KtMp8Gct^! zQ2r;pl3x-THpA@SFai7lBe`^ki4t4rot#T9M#<)4i3YkatFfxvRtNA`sfn*^)06`f zmH3;eX}5nH(U!1tSr_n+^jBf`stcG$2!a@W-o6doKZR$ryKQ;i_G_3JSm&K`yS>_j zH%1CzKtSvUEr1mQ3q8!MGEYfSoItBv$xf!R+HUsA%X6U;V+Q7^#^<@D^Le(Ukg6*g zw(i}uSByFQ(od4P57trJtk$(TK4nETR&zFnW< z=qb!u0fUZ?^>#61Ickc*C-W1t(HmW?Tl@|Hg zbQ>c%dP3wP%nIC0J5xeMGI{PxR4lj2a#PRT!Zt3q6U3)74MjD|i}3Rc%K1TmQR=mA z>xSlI1EBwpV<;CPrzpRO7Wvf~0#VoYZgc*uWN=3ICTYcrww>YD(NR?s*6aB3%#_KK zw|UN{-BY#rrsYwdVXe#?_w4Q?Puhjf?a?l4<8krqHddp|jZAGiwIX*sDbL^p>R7By z?Fe|-ujgN5o>WEt2XDXmt~9OEnYps9(NI_EUw~dGUksrtQvHwqFUt;;rkBfE+Fz_9 ztvQi1_CemEEk%r5X_MH-SnC_LDpWV@E=jQ=!zjmyqg>0BtmmfXnn7F5Q-3~P>}`&H z_q@}CVqnLhD}JNnRIJH_EycxAaz@!fzL8H`LNO8`O#Fn81R6OW!MQk+CCPg<9#8LT zPy*}IyFd!`6byprCLk2-qIYxU=94>}Df8R?cMCj%u{z;>=&cv?KBSL zx3MB8k;aa8rNr-&{&yoC<|9Aq7I+LD>Kr5QvpHj98kkvfErkXyWC^a2F9huOHsT4i zJ+d-o%j;u`G-^cZK^OT@?PqH~(P}=~K$C7Jjog2jN)h=`G-X6jn7|eDhGoKgbwURY z(jm<92;~sP@PSn!X%TaRLlv1jpS`Da4i_N1rSB5_mJ{~Yuz%1R4mMl<0J3bjHDq}c z02kJzW3(7a_22jGO26Z(qmH$LhQMDdqPR*w9=XO+Y^Wl+bbi)};2V2*l@a{w=-Lx0 z81kh=YXK0FhO$XA>SFTZWu>{#!=8}I4FI#aCYfUPd?g{Gcnv^=7Xe{vpJk@O1Fe;d%w0GclkaqzNp=jG|M zU{;iI9aX!|iz`#Y%r(ug%AeC{B+rQB4)W0F$7+$<$q1~Lsd2A0{h()3J*3>zy_!Z? zOo6cM)y5O0Ea0vVjC(e@)AD)0Ft;9 zq0BlI_-m936f%ADQ2koEVV^$D_wFfz!uEA2Vxle8I`ONX1XaUD=ojQ6w(`7LmW0{h zoaJna&`zhNs&CzC;Ko^Ytn&;6wKN1qh%5Bj4vY9Hwx^h7A z>hAD4A@1G&6(QDez~wCYdU?pI{DBPTLp3?I(QnMCZ-!suUX={4HVGZ{JS*+5`i4av&`0LO}2ybojiH99C$yogzZ(hgl3x%nKKzxhNEZ) zLo;5S+v&6gAdYvYIuE!PdG1~Q_MQg* zxyO{HATS97Lav(^H*Zz8N5xUSnR?57LTl^lFaI-TKvsL^$thU`LIKI(-E`V}p+JZi zW;`t8I{_%paMW#IO?nEns-cKlAUWe+8Oyim;Qp}muobe0H|U&uAx)M%M@3(-rb1X} z?A#m@pE@KSkk8FF5-FUnC821x_LOby3qIzNm>jH}s05_pK9NGu22UH>RbdFWpPcNk z?*+UD74Hr9JR`s}+{JU5g)q%6E!cTnTgjma(6k ztDS35B`;E`yXTV=wZkHfxKP82-~!@;G5C<;5jYglxgxff1YO@>H(Go%g?drxy+%%N zUjw{^K)*Gpjf02f*nx2T>eHqvaRBJGQ0i zk_l~tfmSM!FYMmP3-NY>6MeMQ;Uz^aN|mEVX((WVd9B1 zz|{KlNSYcAa<$%3M^#C4;oAB{E+&8tDvj&BPQP?#&$V~0jyIcwr=);#^Y)dyM9DEZ zZRd+yHXZ9!be#PJTnA=@F<@GE$YMzMCT{j!d{}19MIkT!a$$17pXvOJ0V*Jj`7ra! zbdfD|Ny_SU_JGw4As8F(O$!7n&=x`kh@Ox>vLJwlQdL`BeFLeXaU0x(9+q&QD>qe)Z98oNerOJ| z)*dj%mP(}gB9E&R=3b3K@RZlb`+(UYV9&f@M~KEwFv}l^DUF)T4@1AY5mu{2RB^}f zXqjYpPwT!|ztz;v8(Fk@0gBLS8S*R`3&|V)G@baYPNf!{E|kV(!Zm)_q?%42^iis2 zR}ouy|B0F{(^S=Rr0_V?TpsHJrpf!zWx=spp|&@@>jb^y**aN+su)|8rfDd*fvfql zFfH}cmSNWdXJ7j7-W zPOoMWWLTOn>BYqPnr# z2uV^$PY(ZKLE;oN6(OGvX?d>c4PDQ(gZF0c?%;Tmv6Q|`O^kIjVb^)g@3ly9_C^N! zXkTMYRDL#2Qd7A9Agvv4^|qD-hU3Vy!}`*M=jRq~@oa>ede~;A)$(jWh7pN6e>*gn z1D+airg-mF@bJ=?IbJ~3)UfItnIFqKJ8GR9OcQAeW%+onK0BnJJ8n3DU2&|R8$>xP z#Wybw2k#76*bAk&vXZ;cnBRt?07}p?h~U+Y`9_!IF-qkA1LOf>=M1Ght}l7xP>HnR43fz`4wYq z!1qaF7gkiaC)Gg-i%wgkXwbdfdJTvDL8B7%G1xq43@BA*S5Mu;#97qPfEC@vsC zCJDqXw6kWzV;xoeL&DOjPlntV52mG>`lF_tdcj)WN776dC(a7*0;p^84#HQNxitx1 zpFIBKw~X1~pVF>zfK9!NgzjFa*r8v98a7@qk}+vcslAY-k7Os(Wdnsi88*&dN=j?s z4&m-h*Ja95p(gq=p6zUSc5t@yRKOBRZt<;CB<9UZhIUxrt9jKbSatOMsAhegjJa z|Bhe6bG1h40<}+ind8{3KxgR??Zez=nA6iyk7kmP5+uJZRUmep^RL*aBdVGJj>FpL zO0>Jj7fRwpbmhb~G}%FT*}*3<$V_O8)~nH&-o;4<_LglKTi~J7>aeh8PG$IaSvZ}< zxL}=nzqiJT%SS&J5Cgg1l_OFbu%MIlGZsHml2(FVBBt&rfcjV@O=Gry_RsJ>z2&!5 zdcMZ+3*F(V;QDR=Ow1kq2gTSDiH@%{OK%x=v8~s8XNTWnG=ESBhy9qeL`r!Odi>S6 zOa*1C#1Do73ZRsDYO;~}Vwa!tR$~eRPXLb9nONz^WC9%!akhQoY;!7wcSOtE(=tl- zq3D4blouZC5=N3~?~vy!IX2mQifm61d6iyjaetl5CKO+y_(XkH4{Eb5Xc?sG6kWwy5 zom90ad$_^>j8^SGy?4i3NV8tK5Kq&IZaW6rBu(?7+AkWGB(NGK1wv+E6CLxbgu?Zu z3C`2O@i0)HdzOb6%HJM6oMOx?mA#L-L#shXp66K8sg(z!pG7*jS702yJ5*vVU;%b8i4nygKcHIPp&umJ@ z+yRsTDu?x7y-Ys0Nl zdVWi61IsAv)rQ|iz?oX{Avn;u-zw&?T`#y+B#*XxP6(F z5);PyO4%Rt$|<|Dc?A;p$4?@3>TNlSpuRNOWnDM%71ad4y(b1gGaYbto2J?wHLr(& z9DA`sLT+_j=#vZfQ%4+Ho4ugJzYtJ3t$sA}M8Ntj0yMdVH=99+(-BeHub52`>l@kh z+qy#DWFK7W(`QPjgs9i&O^atd(vO<;>yyR0G%fZ6#n8ZV_T^v}!>z}+6ZfUEy0dvKd0v(ic4y|7AwH39 zi!-fIxc^{Wfjg&lfN}VxW>}ZD%%RH@K)p}2#>@_P61EuU#?1kfHs<|~@pHi#$PxWj zd%zIc_)D!2^T+%HVPdd0-5+DRLebF>hH^r8lbEWW)g0m?h(UJ=pT;ru^q{Hhgm52y zLYOM67vHc)SMj}HW%}GNE(18zVXlJN`zr1X;2_K&AeQ%cAme!6HbQW19gUNpP1F0M zo1cq{zp<{6MLrM1@vb_Mqzw(r$ z?%bkbU07+(kUZEcP?zk==%g+H(U(uz32+`(aUT5o7s^83euqapXPq~vYF!l{?5jjA zzxG!zqODwM7|!ayvQ>4PzQ(1^NB;S|*9jojjAL;1-?lzt+JDrR=&ivj0JWe3!c$07 zKQNU7$!0QEa+&7=n*E1HTc=2EF@6o`y#}GanS4OTqLYNPzR&iidU3rqxan$ray|Vy z?skPe%;#lUoZKGsYC(;`#Pz3TNN5J;?4Mvyknybq_%;IAB783V*TWFL!A>1D1sv6G zUsJ2Trv+iNG=}wu-iF^ghCc8W9}F;#i;|7s&f-GFH-C71)qlz#x9Z3=|Ah%0Z&Ko0 zJ43&8OL+HB&R1RV*yEB`dK9pG`zv>4V^rSY+GX*H{NLm!>)_Zv4lD@BI4TGT`F}P< za5ADKk&)Qbv~2v)HvoZBxEHbyKjNBDhJ_I}Mc~H~QAFvTK_E>+SddsPS=eLCngq1- zQA?6^M046R$WEbXfTlvYKf7LbTY7JK&J6nk|6Y24=-nw1;XAWV!s$E9!B{e|m7ThF zFYTwYGSpSE@f2FNnZGE)-pq9u?J%HmhHhH{ViXKyYudNnot6BqoI7`*k$VvYApy$d z^z>wuMa4!f$Kbw{4mRPTV@1wNIv#|xR9m1c%M0w)7l-3&Kz*OIV8}{JE*YsD6FF@R zTcLWS8U>uRXG(_{_0jEN2gB9Dg+^%+kQfU30*=)8(5W@=usny0!w|Gm&TtAeOqf0& zy#@BR>aHLG+w}n2_#CSw41H{FynKl%%3Fe6S)AjYC$x}% z^j!`27S$|ufpn7(X@3E=zYO2s-_&CqutB#)NTe%a!>mLvhkRifi}oX+o01MmAam{-L#z2LrjW124d)VxzN${H zt_AALuC!kpkx53mV{<6T_dU{oQZ!>L4WsB{@CVmn0MqmBHr_q-P&_x~=ym|3_mvP^ zC`+0Pv29?mSLW6li{S>N8|<_)Dx6A}oN2Ii@{Md2oyga4&xIkqbmd^D`nwT|{Ns&E zB4`HcyeW9c;MHa2_H)IEBes+c*Vo4u=mpiiT@y!HCNc{mfRE5>~MQ$A;YDBh#^*cPsrKK7bsuTKWHZMj^c|K3+;13!S=29eE zmlf%%XV9PJ%j~Z0wwt}9(@%M<9>*iF+6X+5K+XsBT177DTFW=R@y-%s%2rj;f>E0A z6}b7kb+(p(+t$^qANiym{#*P`8m*718H++S2LZ(`%Een+>6Xt*b|47yUYm%O_QwC+&-Q?qj&9>jMnbuMj+LwUV&v1TR!{$K^< zK=rDK-JsbkkHMO!6*$3=h2-+qviwp;14=1MQS=Lx-~n8;{=qGu>=FPI{F{uw%uoi8 z`d)1oL*bAW6ZI=x|1|h94Ox+AdoHphTWz-(RUeGdreH-@=sddEZY%;T_T<;Lr2K_t;AT+6Qf1)u z-whjaEm0CFExvn&39eTo;n^PRa3oFNz!1*WVFfQ9X^o_F+%pSlyYV4jQoHIio(UD6 z@USF17{cz@Z5H|h{Q6k#iA5Bf-Y-^Bvq)~P>A~b!B;aiSSB#Gb~;G_jRR|_%TL^}K?hIz@RCpbrv3O&{_aZfOTBK`qW4->I4 zJl)tU#Z{hmNtg7=A~i13%*13Cv0S_{70xyj!W)?yeca(7OmXWv*}ARuHMLPs?8L+( zUvM?n5|+Dx1QfQ^b1r>cZ_5oD$>}K9g%7?QOdv9Li4mneAy_RMkWL4Hy9HKjwielh zdu1Hx-Y9Wy3W{$c^3+5z*`&)qlzv3hj-b@?_l~}1M4}z8p%JQgO7mEVKJ>ep*|Dke z#DYVWLNCTCsV`tu3d!#tziE6i$nIlZCf36QVSn5!vH`O<>=rG9^$c-;1coX@a(@Cj zQbX{aWQyn9D>aq~c<2*-JVAa3(tEq8i6w>@5;8P$2PQKRXMupc{F{M)6s5W^Dtnva zJH$0be)<(Q9e@U@k|g`oMg9;=cKi$7zVA+#h90vo$r&{R4zEnH`L?91Wyu8rT7OjU zmO7u?$=+285A1<^j|j07{N~WbKhpJfWNx-=>G%Z#r%cTb800lz1%4k0N#u5b1;gPN zvWEu)(N}t-wp8eaQNU*;qAS^$xH4JRaP$aCDKL7%Jr&@RJZCveRX`Lzo89!oVaRkn z7;uGJYpEACcWrIqa%GZ0I)$dJL#Md-A=93dX^-XdtU_N01Mk@zx#*C~c6fNNz${XN zb*~mQp%aS+^g?36CCkV)bItm18x$|VoRe;I-@dDqYZWy*I4{1%VG0%foHiK9e1f!85 z_An9HNx)o>yS@^p(U@|lx$~yE;|^OQ0ZYjE&jI{*8fhW;3sgtLE`Yy?`u>Y-_Kr;b z%*|yOeRonFIrr0&Ae~l|@N{&4GZ4vAwJ4DWY~5z3)7}*Rh5A4g;ZjOQWABS{W0Z~E zz`aZuaF&`BP{)?4WQ{i^@xwRqM6k<>u6xQiwn25J^Fb+BoX+zo0b>~&i1E`1HpwtH zus|attPJ_myO#qEf!=`}X@+qZ%XnXJeCYmYSv{M?bLtjK8+-*_m~`KVCYI`5uSn zxE~@qV7k}BzKt~-gQ0Y6_WL#4=XTS@)?zdO`~o|`bnKKSz92q5#9l^N2>`s4Mw>4( z{w+c~)$JSkTfDbvD!rc?6zjxR3jkJ2mDdp=w0Y0Y^t{ykPKb#^U`5#bfl*x6uPj%5 zHau1dzA)lqjzfv0BQ3E*S`Wc8qF(f#di&^_q1H=CC#%6j3tF{w$V{;&p4vBSFgnIdS4{S%9p5DJ+&+Je1jWgA#g^mi2F zeCkFn{C;3=J2pbJoo{uak`e>0Y2U>8ogap*X*h9{Ow5MxP1NhUHI$$%d+rVr7CAUw z*#IXpFaD_ja+Pjm)43T_k~Q6Au^!uS~vSKf^&@qc@aFSn)q~5q=+M_8!f~YgPja{y;~On zej1}t6=x9gu@6sHeWMX9Tp7ohKx#npI74E2K}&JoFuBAR#s9=+abG&7 zhFQUoKOQ^8mR`{2Km6dv?c}`v0FQZg^&v5HhDbSh&ebcvKQsEAC<;{dqhX*g7Ys_n zoXBfB=}5qS`?2en5*XI6lXub^e%vdv=Mxi5V})59nVeKG3Wh18nULNnPp3wGT+Prb z+z{WiUu+|A*vn?Rw@?U>``55xFj74Pu?}Mp{rhK6{Ote2>otu^Cp-`!Ak;7*AT zB$NjMo#5PDT3w)nI$+FLSN8Q52Bfsb|`xK~s$vbjl-OoVprml`ATe^Yu zm=)KgQCB%5&P9swQ{(W>Ri~0w%-h|*4W3fWd}psFoeEzi3H7Nsfz0xVXB6jMPZ@2h zT^;gtiDcw$=_9@}rj-F^nR_-?z-KiMH21)JZ&apt(7C-1i_ERQnZU25mu#IX?J~VA+s~w2C9Yr14m+UE<4!)oAW7*OJR2qK_a1=^sJI|F?U{deN@jo z2abA?N3FU+ZCsi)fqnvPziy{zKox>j$67XG`3Y5N#l1A~AzgkA$n z%m}#WdZJp_Ow$KwvVjI%V21V4^2-fyAtP$EQ*}-AihIpW z6+Qju8T$smE{n2Jq?+AM?%JNwlXFAxiwbealOrS%gh{0_z^>FTQu#Lq5;)QF1##@a#mvqS%OL8}`Dx}E`!{Nd zQc4iwuB|w9ORMcL;RB-=*6wBms?yh6(w{utNg!-33*KNkhprs7=n`J4lRt*|r;PBz@=FlX(F@9|V@ zqs||_$C#!c5;`-~BUdL|9g8Y-=!aW>2o^3?>69Flp;rKEvHm@A zBYFZ`=+u4m>HMqhfs8ga>6leImh9>!j%VY-lxc#3q4drV-Q z^~krmgop!Q!p5t`C0tGUt!cXnIYCp)_uqO4Rc@c>gs2VcT#6SFW(sFZ6wIhx#s+d` z$(M6jrcUGA;GJ&)C?u*YABX!7iNR4#&R5lk-sO{$s7;BeNqE^p(g<}vN=&&z^;(~% zQ;o1>P8;Xt778l8?SAJy5{EGEqt1P1?Q%udU9!M2XV&za?*5)M=L-p&k~18brEePf z#p%(Qv)d={H@=^~zzV*Yl~zSC&=`8%sGii_HN0-nb-f7wg3YBS|CnR;R=XZvs5%vP_IE)robld&5|%_KhYpWko}>8oS7e6Q8Gi@@K*!P19-q zXGCDQ+2N!xff8ah%O5#$8D8SjFPV6JQc`>#`V)qx^ze_y#J^NLtmKhC=A;vr`*8IW z5B#p+xNnyzU&XqA%Qs9f`Qrz8vU7PU7Q+_!Wsz6`+x>MJrFG|0EbDw*qT2$$6uMaM}QJZ-{Gv^ z1W4cD4Ua-B6Id=`Oos%4(6^5Rcc@0=6KKw9&%6PgPO_l>5}8JF_#Nc1G0CxPCw}qU ziDNt704oyijK&OVNC|ZpB;H|aGu(fnt1e;r)nF&|+$#+iL#ws|CBgG%0*Pt0olw`zWNiIRH8B;1V zK<}^hz6U;GI%g^W!|seEU5f$fBFMwU5D@);*&M=%MJ{|m+kpE)V>{lifI zG~pn$|G`kMP8qiE|ENnnCp-y^uW?VyfGu)zhojOiVL4p;iP6Mz-pj=^^4B*qCYx=X>Gh|+bhCtKNh zxB>UiPE!?iyqWa+6}cF568+d61{z#4ttz%jBo_<0t%068fmkQ5m>g+=QhG7Op$(v9 zl6jOr*|pqc8%a!Q7^{UH_CN<<#w~&LyEi+zWQh_gLIo%rkkGqAn?Lf1P{gqy_JLZ> zRLLCzTW#J|j90_sCWqUov!!CCkvkIOE)kbP7SLcSg)SICN?@Sug31%FnNi(jt#}b{ z5vhle_jSosH7WKiMDhp!h1~{7yG=i0{79I%mS7B3L2(8Nc+@U@(BWJ&T|84z*cq-q zw}`+_H~_L5syItXsHiTU&Y(4&pWoW5&=-{+XaHt9FE_*y2M|oAgnza!P=O}+Hb|u3 zWk+w^Lxnl_VaEUMEtKTyt2$zcqBqY%s>*-gKPJ^7J}CCIMPSu=iEA`cidJUtxN1({D6`lJyi%E>>C#=q_ZlZt%B$1l;Io36 zNSYEyj!#O|w?=tdaSMH^Xb=BbN_ilE8YemL0c(^AMWMX7UX|wc#-jgOwTjXe@$BE- zQUmOt377Olahhyl*sF4xP~$uANoZfC;tu@7n7=DgkeVCYQ9CB)(!Z|z2{R&6y3A3k zcH!r3iFI6>_z5C{rjW0q+BeNOzh8tAOzkJr4)y_x@x{aYigkWwL^?JgnhuQP`9iFJ zbW-`XZxRAT&iVe~@I|(FEM$^q->_OFJOa#ye&rNc@&Kdt0^pOK6I3S0D>l8;=yF|) zvg2hqhj=nfn&RTM9&d(=#^seXh^)Ine2w8_Kz_o3!4-qP2Zhs(P-0%nABnl1HYwbV z-&NJBa0rit^25p=%?0hxYZ2&;NoO*j5`VAryKaQhG+#xUI#eCcoin@%q)} z^-J(&KJV}QfE5#{f4nZXpgZ+l4a^TVa=dm8R{V)tEmn#dPS%;QYHRGUquqmC2HKF8cvmV8Qb#Qekj>rRrvOe1;J)QrXpU9m8gW4kz@qL24;sP zn-PbVVSzjSO+uvl?-mZPJ-!ZPhKBx-M!2`0TsTs(Y+8}Sc@?6;kVkmv8Bq4)(vmj3 zEiY?(yV#E(Zn{y^z$E$@c z#84uXC5ox6$0qy-rGX4s%W~R0bH%CN&0JfMn!_FQucpESI)G6~J=6Mf^pH}QZb_<5 z6;79#%ox|Q{_t<|^19|BXP|2O=W^e*!iXVi4u@#5PYt=Pgh`HTA2RE7w^NAeUDq*! zfJ3B=M|!+xP5DToASU>)XZ|W>q0p6`BTSHhwOguXu!@9bQ-tbUv$apTF{~W=%&dY+qSAANM4phE# z=WmSZib&4OWe`lAJ^Bz>znvpb_m>y(IM93ly&67La?lHJz#mS2JC1!j#6UQKaXUsY z6atwq9Q0xqQ7{57_(ST0|La$X_Yl(ofM^)6{*aH?E88&W3^3OPm-Zptn{9D;< znbt=O&Ng!Lt2LhO+?3lODPN~0ti#f0%}+eZWYk)g%*%)$Eh?Ls{+6dyHj71#g|~(* zR2t?CW8xO$p+CNobW=nHt4yQH7w&q+MRDs7IeOKjXJV7}DjrmZcbi z742WxTHfLt$DMga?2%XPkRq~hZZR+P;*$i|_X5(9Mweu-EAmoV)@n0^3>;F#!_Eg{ za!0JT(vz70b3@;Dj#_u$%~>D4dMpQ`(C?FQ(ZS#63#;o zX)OCM_0Ajw5wS2;2v*uvFtPPXj=mgQ&>f0ZMxVn-X@XbSp+CH- ztbj;;U-c>LsGiWS*=-!7t1apG>7TyiF1Apat;BdM8Mwujr=Kk6&_EiF0@-tMF4o*> zzv3rj8TJndj!4UZ7s|$Pw7!pH!$^g_!1L5nn<_L3q**39xonb|;rs-T zN$|9}-(R{1%Uf7dP(_wG3#iH{MV5YF%z%>Y5!@atJ8c@cTiJwX*hO`MAe_{T_mw8C^4|7ifK0E66`E`nTouv$!MF-WD=n^JCd6@`ml&;de zsG~-^4*N@lodg+u_G+EyNKy?_4ZUH^Kh$8KtYDvQFi)jq{$i89*P*{-ul|6_zvJOQ zetZqHy2CRX{1^9oc4C%v+5CgZ1A#N5wr9Ja;kmu$Kl3SgY~K&m z_Xl+*vZED+p-W^JCuT!XC+H#7-)MYx1MHx7QI&xk0?Hn6Lwe1%!#ie~3+UVFXTI}* z+oyyJ0zc`06;w>Ch~sQF!2ulL*b%SKjn5rb=TLUA45!?vCzlR=(BU)8>+j_Us8Mn92Ji)Ui$dCOW+$5(hu-1Dn|tN-GD>+xeJA(R zGYW=%=Edn(WEG_DBVN3LVwRsg|B?Y|9y{!A>_PnB{tc{cw%uCsTjq>_D5?A`zG4;CZd88nt~I>{y~5@^!1a4 zPN}v>4b8|#Dh zSC@F;HVo)BOU|$hXAWf(2Ad*3gh3f0(E<^H>DZ-CF&9Nk$zo=M9RgRmAN7-fOduv) zGVldJgpYW~k=;@B=iHZJYwDxbx7FHhk-hX*{1I@arudlEEcPZJ=x!YCp zdj=hha?J(J6;X{F04@pb4hZu4OHyMifWT&hc0)pCBCuYL6g>!&s}kt*_3~pNAruT$ zP8$(vx1Nwgy@y^Jd$^N^Eb+L-$8h%BX@v=067|=*&%Xk?` zLh$wSq_>BWtoaSLk~0ndXX#RTF;pIE1WQXpiuLo)A5b87G7h3eIwb37)^Bi&tUq6E zK_9cm)Y%uvmcXN83r)=psBj8lA#Cx#%&*+`8J#Y8EezOTVmRKvKPsSQMTcC0?lvB+ zaCS+RLfB(C$QO=RO@$DXkOiPVqbvm?3pX7Y8+;L*O2f?X;Uh3m_0q(=`$R|(B?#}| zxs)f2EJcYy?fu=Px)M7=+rcd4-SA#pn8Tsy&NbCwYe2i2V%JL%5L5Q~;Cp6JKpWu( zgEQRaZt*3Xa^k;gZ#&5w1T3U1YY`H8(?NB+Xh^C-a&%ecBHSAA-xcB6XvVy=%m?J~ zmc#V=y=JBPszye5gE$nDmv%KJF=7?a!JVo92Yo<-zeBrQ%9Y)%<#d>B!5k=Mkf6k# zQ5*6jId4uk*tsizm6-D^m=6nZ{&jwYH{szsb}>s;*LVXKb$2%H-oj}Kun>HSumqMG zu*`zxu%f#umO5;-NV&fj*Hg=xF(Y>g4O?ZwY8vB;hW)`vtv?!Y1B25@)7H?sBVKoh zv5dit#Z`e!wZW*$6~jZ}OnWmkQS(W^!vTMVzpOTpSsl!Oj3Vj;JiHS#qyDv-p-KcG zmZSO=5HO(9g0-am$IkSmu)n^lx;#P~R25pk)E^FFC#_<&1vRwwCQ@EXf)KFQf;s}a z5I9o_L^~9+pdQxYxsR+1bYRi@rw9$g~fXihBY6Epj+ta(XZ6=(- zfLB-0n6oT@I2$%1>7X)V?(SA?6B@tMnsQc7DOlkzIAcV?*wtqio}GId33#3b=fh^) z8PtgKDh6Y_QNLfWkQZ8T5nPPa8iG}UrsLR@S#IEPDed$Y!YJw1P`Kf83$B1GaWTSy z`dWWE&TU#(Y9&?v@FFyxfna%H{PE!3>d@6lv!WV*51oI53BSR^P#vtT4hG0vY$bDX z9fRUuw+h`+zk#+Q6b#VbY`5S>xJj9WNOc(<0ETYhmYCL8hQf7ZeRf!IE9_*Dtd8;G zSQnb}Zq4d(&*XSIShrhn2i%FuSsxCNh1t-($&8P&E$v+v+zr1)RaYXEgla=!RQz5! z-Kw8|J>(t>?xi8N%`B;^uB|`|P1F9p1^2@PxUlt(&F*y^lRciWAF^N&@cf&*|6_r(UIL8z#IR`ba^z6;8VVX3)2XTkGyI32x(WQmvbw zg41#N+=4IQON66$jVSju&Dm&7TfGSa2AAB#mt-i;xG; z=_cTtH7oa6paEZF#EXA1oRo}POfZRm%U6y*D;jWupSk}(LfxMkVKN;Rts+nvF&Xlf zwyBdW!D5LNgt^oL&OxZjl5kGt)#375g^^;hRF;P7r!c15TTea=Lu-?Hl$%m8lcgh= z6o!U*E!L}(@Ir)|tT(!Z>N*TT38AmW`VoS?b+ZU;vH?i0K2*D5Z74`M11&axhB#uwC&yp~xK+nLxeJfLPGI?L zI0mW=kM|i z#cp8RF#Axe*AT6)9Ucy>4KxjRbOu$aJXBX-P2pF;@$=MU2aYEOH(Kl_b~DmY@o^xm zjKR-Gn_VcC+JnfEv1W_yQ0vpQKslg)J~_wdZLoWA;7XMMvimIddup2`L^Wz4QG38*53+}l+S+iap`K#$ zS>46ttd+GH48yWHterthCxVlBb{p)YKJGyct3bcW9?LGCS0c24KcfK0QX5YsULg{HV9>X_M5Qa@YZiN*u9?he$hm1?Z(!@J zOjkmZ_2dp(fH&zbU^DH*+ZKC={ke-Wpb?_ut7iY6#olKhkT0gWtF&=eZV3@+Bg66+ zi+xO~b4uKQ+m(hI1JMxmeQL4Kj_f0QZTEd)u`k(IXprK4B@JO3h-Vq|ZTh1kd-gYr zea*hxp35=7v zftu_P?qNQS{@!9gu*0|rHE2#KLG1?pSKdBNXFrjDC>;!PyA`E7NnD(9Zg637$+aWz z{We6R0nE}wARMMlUG-FlhR?@wblDW}*Nt~$gqfYdP3|&yg2fZ*s=?C@BKbRN)dt<5 zLAD!o8pe2v#Zx)OL4G;{<)Qiww2a+Eo81PWOHkFg$KpN6?xb|8niEA&=RGa%<-O?Y zvI$*(Kb{XgXCPs;)CekL-@-g zvSb(CvQ6jN79T=DL&asm2*GkJo~sbcL#mx;@qE=r*C-#`WDgu}@ezC^8YuLX!9wR6 zX@;EqY|1-wvV$|m;zgWdrSd>^t$ounOHQ7DYU*f= zS%l!)&fGo$7V=Vy&!tRV^HZ8`a*T64EAv-HR{L^RtXoh0@JTdSZ%^`lj9!f;ZPJ)24EjjOkU zcTq}d0W%09VKvH}F<@6>$r&Ah2FZb6I_PG{6kFc#cc8R~#*ZBx9VWj3rYLxwdTDov;7{c%V#XGXtbC2#1$L}nD4_y?dI)|gK zzSh3sp@Vjx#eYwp6utkP(E31sm>!FeC40c)5AuiTDu6KQ-Xn6<4YmrUX9c6vs*!a9 zZ{=+U-)-@BQgH8a@aSoPKQcS8f$;ZOd@so*FlaaVqqzO24$c{tYyZnK`D3V4gR@5B z-$ML5Dr*$U`-H`xq+7!T=caN>Ej{AlPouqH4<+#Z{D8p^TKrj#aYHv3s0Kr1{Zn@Zjm; zviO^{1SZBnDxo1VZ(IBw3gkSU4-e*r=Lf>&0oymcYw`E^`>0gqbb%K3lk?Tdwdc;D z?hkQ7a52^XLWmzz=PWXRm2R}S*#`gY$h$bT;`W4S(G&Qm;3Lt#wD?!_ctleVK@iOU zX7R82H{<~*vhD71NO#YvO#Tlvko8eHX$KvTZ>do(r_@v9zu2g&latGy*<$kVDJ!az zQfqkNdM)$-~e{FStIZ7=IOPIn%w^)dR zD-%(dM#oDFR+u7@3<;5I^oP;)MNN@J_i+SSZ<{iaLZ>}cTVaZ{7&0z<0E2i_c<5{^ zNc9;gOgfGw`&CfojP=HdIcccKK=CP$D?o|Y22Ih2?jiz|))Yj@USV`9`XQV3p>Rbf zWB@_XHesWnj?zDWG0@2e3;e0=7|QT7@g1(zXCBro30 z&7YWbMDS>XO)&*`-H(=C0D1_t6=Iqtri&T$%)npU5TFR8=aK1{V>ZT{VkWr?G&rZ5 zf-Y9d5Z@H^NV~G3yed+SG&`Wf6!WleEk=(5Hf`EuiiN5fKqXnMQocYSh|D*k&M#Hh zgLMIt1)D2>)N{gcD1`l+=uE6uPnjBV&azee9|f+w0ri0 z&2APpcL~z6BhwVhb>=qIl?B3!{pxXxdrqj_U%P~V&K$NKprnU@cwm3#P7kg8q9`tG zslVPCDB1mB|RV{ZH+&pG@VC=Snb*U?Yki^BQtAX zGP7!b@|?%J_~@=LcAY@dt9u;^7Lic7iUa8aDjJ}aH5#s6Hqxmqk5!fx#vp|xe6V7f zT`Z>yBkFfbY>WE(CiS_2%<%>ak12A-Mx~!VBKCDxB!J6cHU#5Ux(l9$b5#k8T_r25 zvTC*D2%OqbSxF8zjwIih%=HFw5obqpq6N2T)dWaOQns7RvpAmXV_ub<43A1wuoI5^&^!4 zBVz)Lj0r%HZVp}iNhGeH{aS+3elye%T^mwKmZolEktHs=sH1h$>#GChba)b-z?|-* zBtB1j;T_y6h^KNvFZq=51n(M>u@>;c1A^K+j-pRstr`y@4rxtNy0k~fte^0Ql5fr z00xLls2)!`NwRoShZrM%DJeKAOhb{idb$Ot8*|$b_WgNump{f%#lyA!D0+#1#UYfn zkq(fkCAn>r7mpl%SG+gWjD_K9)p@zqWP} zdie3C#9%dx-r>Q>BAOXQ&mDVnN4=?&pIIFp8p)i%CYlnX*f9z?&UxW~Cx_+IOFywU zeyCa35Q(bMWr56KV6D=(VWz}@moZafjGLz3twTwPCcOuQy#r!8STQaWu_(%oxe^7y z^uDk1l$qtWZC4zs)XLcy7y$P{dsu7tsG*s0e@zHOanCV9&t#e5KxM#w8?PZ4XsX8r z3RGm0qANnVC}D{|*hyu75F3ON=AoDBq)+cOWh%p|-Gvli2w{4;Lk_v`90imxe52ko~K)$&kei`u{vC9#R__27<)s8NkAy z_0WW$l3qvv`t!C^zN<<}FI=gz&MBi#c>oS7yysz~YQOHZ|D@V~>cRla9L((u_${Ul z4cOX-cpS^|K9(nUgUD+Gmpi2m(zb(7)xB+yu?>>;Lciti0lQ(~V^pJ_J&*-JfCq56 z5RLfR8+82KfaK2v51a)9kZ~>s!Q8;lw!^W8;MY8i4rB>OU?ySN?3 zw!(=SnrdrKdvd;eD&grF`hKX%(A!~JJDfbupkZc)b^v<%G7N154#ZN&a&ill_;$hE z14v~rEL^@D7PrD&g5b}Igd4=lWI_%;45tX7t_(wrXv{Ew00a1wSVH2)`AosGQsir&C!)KQ;JqI{nm? zB?a3d*a~4^ek(Ni^4%M7s;zJ)cAmK(#!}%vryb56Co|*$&|6?ghLnZvaKSZ28j(9Q zLyE$5Z4X?30?-DR;mDSb7xUd$xvy!1YsX1i)$5gd7_tR3;8xg{@4neybzJ2vdzn&j zvD={;7pVo()M8NcVYrP$KU5|kZe9z0{H{}X9)x`SybyQ&B5=W_kPcg*A6y36a5ap9 zYhXHD3#G6X7Q%I~3a*Dr*bYIs5w)!uF?Yb7a4S52jGxa#3m%+%;2XFPzJ-V2JJhYLkjSm4*d)%yUexK>d0?-={a9lPb{?J#u4?DQO(0OF`C>CsMybY# z3y88hH}&A@zy;FPxuK)O3~=K=fRrC0lj`C^ciQ(*kk-THIRts>hY57i_b{jfdeOV* zU4{XENP6e&C@>vLb{Ga>Jt+z2HXKIS=aSujf-=&Xe$$uN3ist5fO$Sti3fe|)>ddE zmEGf$t?-yH)og_)eXJFpp^s+?_<}-uncAn+lU~R zdx$2Mj}cicpCrOqK0~yze3r;#`2umk@@3+I<*UR7%Rdq)EUV}kVROVB=lR_e>& z_bBAH!dJAA-{j9N*jFS)k(REd%bhT&AYCgQr~5MWHuxu6USmJF(Ac)Ye>Q7>tfk{! zvP54A{P?CFzJDBkLNc9OF$6aN*g(+OAV_9|!Nam4mkoiDY$!~?`c#$+r!b$I%V?bR zNR;+scmR)QE_lQxI0JH1OXBleg6;*~5MnM6Tf}9!BD9EoKy*M~=U^om;&S|l`vn6I zsdfAo{_Xgt6R?E~#=ar1Sjy&q=95`vALY9{$UC9S@a4%i#^$!Lm-0PKI~w>f0u2Rp z$AATG%+TLoXTQ{h{78XRV8@Q9bOBv#J6EWie` zN|wi}*cevLCb4yF77MdQEXr212DX;1M@SPp1OIMjXR^!L+3b3Mwvp{%o7lbVe71*O z$PTiL*qiK9_BOkWeT*1?V^?+B1olnbReht*5uO?LCB1WxHo;(@iz~2KsM9kDdi@B= z$`wgZk6sxWz39h7f81`jW%XljG){@=^ljU5GoDVeFiU+#EA#tO1FfvWXFQ@WCnM0{ zVQVSMX=l|7mP;FdP)E^@0%$fM6vxnQz`7VlD~mi3H*|wk9Jv(*zYY@F_0X5y00nFt zOk~?(9{ScL>}EA#%NEC(u%y>N9iLb1*wGt&sRNFX75Vsfv4|t_`j|WfbA;Xy6RFQO z@Y)~>%)$s-K4W?d476cqJ42`2&2yYlGZghzBeE)OnyW^CWZN|@E2&0R^lYqj8p?6# zrGVXmk;k22VHD$Gcf(NjTNuyog-Pr_Sj6r}MSK9(VRUmQ+l79p4V7>=T+iCo8cak( zIUi$>jhJ9?n1`#d32TDp9ygvhppUu<*QyMP9K3bNL*Xe!NFZOd=ttCHQ0v{+G8+`J&ybR1k7bmqN8}a z%YHA3?{~krq`MtSs~t&YE4$!-SzMnz0E_RDtgOHYvuL;<)6h&sYXwR_U@m6-P^6LcH z38U1QrP#O^UA(~LqK)0(&UP(uAeeTT4n(>7=Q`DO2Be{+f5zFqi?e+nda@6oH~SC< zvX3Bthy4YQ>BlgJeS-e|GnmOf$F2JU{AhpHvaetR`zvh0_SNjaan)T0W5t!26lj=T z*R#3eDpcJZsAe~btJML%Ca%QS& z#&yk&DTikV?oclP*L%*o3epg@t`Fn7&dJ+<4@r6LY;POew;kjId2Q^;(!Ff|^4;v< zT%qD2QKYBq`TKUVh570F=psWDndwGqX)|1jMO`yojK!R0I2ViBW;g?jnavQvqN*8c zu~^a!0W2Du;Z!V2nqesx<;^f3i$%>a3yVlIOvPeBGmOV#T{DcvVsSGRU=eMGAy`a* zX@&t<_?w{@7Au+|4U03HApwj09pI5DmA(xU3q0)EHun5d8;N?)*a5mN^ROL|oUUyL zmn_m+AU|E(215}%;#P$>_IAkVG8&QX1QIpJNG;d_ndx#n^dTn6xDc{pbZVga2!8p< z4<&A6FE33uw?T#ta?|Lph-Q)8th1JXpYFwo|nkiZl1cbd~ClB($=(5{r$* zVp9~kL{Wk$N=z(HPApDIcVYKVGc7|;cNJo^^KMaUda6B#RGLE?76r|!g;Q{+Ctzrj zo=}v!+11ekMtW)y_WTyW*o^u!MWu(J&$8QmfL(U|LF0R5`!pQ$?;~L{VwVDclSM7V z!TbCuTI-Ib9sAMWcKBb?4gcqlYF~gqLyzMBxWm5<`QPWz;z#qR1(RzE+u4W32GupY zZhDR4WUpDA;`16_Joq1_&M8XR>=G^d@4QCmn6hH*?HpFt&A3`;T;zD19L!G?R_V`E zKLU4PSBjlIyhS&TqSCcf`?AY_F!P9>S8Q(bSZ>()P?uq8UF3IDUAOBVsvCB_2h~lx zo=){t2dSseo91DMPbZ^f#_PIA5=h?H^-0U)BQDTcW>qzO-j$8w`-K#rIkKJoH z%^r5I=`_>r-qaZOFY%TyrYCNPWZXmxH!-ON7LoZ^E~BDQj3`d)(v%~AirulMRK1=q zP3-M~d_3N?$}%L@1OK|Qmh?YeMW5I5CdGs%fjua24-!~Y0{8vDE%5)zX8eNi;$ofB65EPINDnP(o$> zzuotr5sh8)KhyEVt=nRMKDCR@=mI^`dZ>n@4_;-VYz0g2k&Z{&>uqCy#{+G6y(ExH z0>PpGZGr5y>9i`2m5FK7uN2GgO-4Wp+F1CKOlNL}F4A4?>{}1}Z#(;LoRYSk z{pd8^4|2#z+ru#;ZsP_u+sIK`e_8X8AmejpIYu44%uDa34FB7q9>y#%lQpb`BrOF5;uu7H+bu`3dYAUd(Rh zW7*w&9D9&YV6FUrMAptHvb}sV+sCJ{C-^k>G@s56@RQifd?tIF&tgCDlUWC!%{5-i zU3{JZzED_vk?6%2i@y96k;#{c9KKZK^JQWsSv7Z3Aw;t}2;4)R9v3STc? z<4xiXewO%zpDq5zH;TXWbHu;+d7^`#FAcs~Ch!Yn62DmX<(J4TeyJSFw@4qqQWo*6 z`4d_x ze^Oh;pVBJ%(^@^>ubssYXczN?+O_;yZ3ll&yPrR=?cy(J?fgY;FMmnf$6wK&;IC`@ z`5(3C_#4_E_?y}X{4MPp{P3I!3^BmiECw1^i9yCqBFnf-WE=O0A;$e;sPT}< z$}q<)5x)`VV){RuO%~T;hG@cgwnXKWx-5c~Vk=C7G&vRKiR-ZDmUE#*T#q%6TmdJD z8?e?xRzjZGhP8BzEtV!?-FYi*Zwohj9i>a_DW2$znVi=dnM| z6*abpc{@xLJF%8-J^&+s73H4hKFCs(z2-mQVu#9)aF$KQ<$`*fifaI@u&KDl zz%-kRYdVa!sklywQE@e+RJXxKNORo>`Qmo0x!Kz$sMC{5wb)8LZtL!f@5W zWP8oQ>NL98J~LC?i`){}6J|egAC66APn*5P?-4JV9WcG(eypX?y$<^;OgIc#^kB0C z(!o#mHgb~2Wd#M9jF$&B?el6oHk7d>Q6JrdOr7jdpeP&#}VGFeix z_yPVi@`UWXjJ_Fte}L+LAK=WC4w#3V-t9<^e;B=CJpXtYL>oVT6_HiHK;#FQ^8+mV zRisA$Z^$$57l`}>MTj~XBdH#2GR9F;|A+W9e*xe9J)F$3idyVkPOIv@Dvq z3lhcMT^Lz$Mpm4WWivwhU$U>EeCb%;%U z9-nr!c%5R|ySyL8I*4LDi()+&e;$rQ<05&KO=YTfh9iuf#$m~rFelYyXV(P1$=>7|uk^~A zAZ6BR*4A5KfH$ojg2nD^ue)YOVsQ#~yK9PNVsUDJ3oJ<2(~TYA^6&!8KP@DIL-8L~ zl51kLkU0J;3tE*(sHWKMb=%!Ch}7JTHb!=^IMtizO+jJ3sWp`-BZ@{sSOiN%SQ!ee zU~ZH*r4k3Eqr9n=M5m`WsnLdcy~&LZuotGc>Fs=2vB%rX>&1%KQ|aM_xL}24R2KJ0 zH*mdwy*;o|S=__h0~ZymK@T5Q)6Pd@HjOFrg+#n3t|me~yx7|_DcH`(w(|)!WjGtF zvIc>~)k6#3i;AJe8H0;^XBGGHdb1n7i8bC{v0Mqrns+yS`IXkpk+11{X|j! z^#1ATJK<@}%=^nV7kYcvlob!~4j{6bR17VD9_UTWrV#^c%4~v}HI>DKa5brJ0}}~Y zRy;VyI@4i2kXUEMSZ6w{2NLUS;wvk5;6j*4%~d?uKBeB?-o9ntKHh$1>X;7lW>tCz zd$TK@)?h5XgNl25vv5j-akAOP{WkY!Egj=KP1SxFiPbkTN_Y#h#XA@+y^B%Ld$3S{ zd;kIQA#4zzz*XW?xL$k?w}>y`PVpt&FTR3@#9!ef@i+Kfd=1}rmMadi z3F14pKzz?uh#y#39A@W8#;%rvZIhDSB{lYlG}v>}#a@&N>=l{FK9v?bER(q|Q@BT_ z@`2LLi=>ComOZ#%rt|gEi`j7ozg+fz#!R;lzZ)~<2V{T#upGdjz;OrUKsx8_O&AWh z;Hht;hz{acxSSR*S49E)6L+zz}gH1qx^$10IYzB-K zk5ZJ!7GO5A4{N=+2ksM(VQm2K4K3nvtYz|nutPk7wSl|{wumROHi*xLM)4GX)&_Gw ztPxLREsL+mnEV;6Wupf_sG_(2WKCigi64v^Nvt_W5^Ec6i^LDA7*(nfJ8UC~HHuMn zRokf^EE68tFjLjYhPhxG-;DNf63~6j+2R1!5@8{4MEi(wH3WD$T1kwnVFRBho};J{ zzGbi5tA-)P0ejV0I(tZ2%rusN%bJzNbh8yKD4wTynT0Vse1W2Pb~QUeyohs4XWQ6t z@se7}N0=pERx9}w)5I&ZlI%J7N&Eq88SF*)LA;8!-s}}PBwoW>ANDEg)$3U6i!sj& z;*VJCr(EJ&keFhb9dNmNzk;iXOT}HBB2oNjP39dc*EqVD`a9rkNbjb9C)Rro3^-12 zyrts1i($ww;&mZA5&HiUx_X3tE9`VU-5d1Vap_^MuZ>Td&E|*``9xo8Zr?UOW%)$j z3`2c=`^hzJe0n>dHBROo09S^b(*mx%3^WOIuW`G$}up1T%G`9VH8`4HT&&{9`pz~(SU^vcW^M4+V`la>bD`-bL5xdSX5oM1TFTwb~twq zP9yC>4!%8nfx3`n_vdMa9=@=h{iz*JF3pqJSgc-5>PPP)=Zg`4`PztlV?@3jk*|-) zH%IK|r`)fwmMW~Fh%qC7A7=M1L}>vX+r^TGT8Y_-mRH8{m;C~Mc4A^8`u8}#{d&|I z8((51olRz6W|I%lXaJgRtuYZpCVNo+K79uaqmD!iNn431IKt^oWTer?S7IqgG$ORI zjh~t!?{9%AiqUC*icwEnW(#rAr6qRC;Xk4~(dnmd*17i^VF2#^6fosfuw)7D`84P) zXTVT-5{!~Fp;Vp>%jIlXE$2W`mcrR`9$X^l!{u@T+#(mky>c-;EKh+)yBuMA73>y-J)&UGqIv#}s=bWi+S|(1{eW@tJ4y#1g(b@T3DO)#8%;J>{25ba z21C*0Y-Ej2{Op6I!_XUZqr*^Whzk!xA3l|T52;-$qp=vl`}ar6cgJ4m6!Yv?M%dmw z4=-=y726fvatJO_u>e4QR4E zqDKs9Y=Jd4eB%-DO)W6fhHp3mer5}du;HO2;OknTmklph@I(i`cC*CTCbKiPc@jpT z`iCGv)`MHF1Fww2K-qvMuMth&1~hkPz!Z5V%#a&lzT5=Mf@*22JZpEW<9kj~pVUOGnPsv9n|=yGZV4*UEO*EcdW` zw9tma+y&S5U-7@tvpZ3@EPSG8qW`#{w~So=`bF2veLs&+Gu z_=~EwBJ5*T`x2fLpWwmK;7{-u6_H4I0lvmak9uE+PsL~0OGj;Q{Qbwh>P=`nJ01dV zueT@u@%H=)`l|bgi_qK`VL_3+*ZV#6IHV$#Y8dRewlm}3yUA;3AJRMLzFqL1hhJHL zvn91x6V}^2{Hl$c=%x3gI$m}qc4ug1GuRNVVr!n`|sPRWuwrlDK5x#oETvx z`SR48i1Y=SJ)NWzs8ha(CiA5(B$MJKlhj%h$w-{!sm|O6IdglHrtoHWb2}<)m#^X! zUc)K8-i6noIIlr*@z0L)YIeSWP=W`4{OZ{Iyv5k~js5bk{mp|G$VSjs=ZI(u;z7vu z3gYsmW+LdQYaIC|B*}O1p!^v!<$K_h??a*d5MzRmV5erL^9g=`$2LgHFdyf4j5BZn=^3w{Vea8ADyV9K#D010{I{Em zw7%P*zb{>VAtha-FNa=ud(7dpJLF)zQXc=&U z)*H5Hec)QHKWx_qzz!`F?$idtJzADp(p9)vvtXe398*yGy2ZWm#l063Qnk2P`w9~w zj_J$}OinQx#f0x>`UTv$)E?N5$tt}T*$cL+m$!B31J_{kdJqi9pcx$)HkkJ9DrP_G zJ4O5sy5t^Vh>71rGB^5vdqMr;B1d7KpnEzj%Q05Jm%{Z2`Tbbkg-UGK9=^wCzeT?d zvVFK^2HjYC_#+;^uZ=%Go3i+)Qd8UcGo)CE%b!=crmvm9c#j zRsg0p9NgLn=&g;!x1dX^tlCgL_UsmG(%EgyF$Imsqcij=~}AU zMBsEC9rNpL{EcleARSftN(E}?Z`CAXqn-bG%O-kN(wnY19Uq7^=xFC3A(&ob?0B#R zQtYXJqNbj%b(>Hx$MAkCMG7*w2jwCTQ6zXjYDrUup-^FiQMa9CEB<3h>o!11TfyLElLoHMigZ7>O-l7G$9xy)Q1La-!O8pli2x`GQps z=Zn5r6W=-Kwuks$U3ut0Pm(rvzC(XleVJk!2lc;mI7&Lkxd^|T&XZPgA}-?JmA0k% z1ZgQ+ZV&%w&3y>}*D>&aEBJqofge)v?~Z~0px}ppkAeTB;2jE{6o(Vc*8GIQKGOL6 zd<2az$y9nSsI`Nk?SV8*76)jLK(6*Ep4xqABp-u$+T*ZXdji&KPr^FwDKv~v!zJ1? z@EdJE+^ijd+qGxA-0a`YCa9gmnp!~mhVxEwm~>YypasTZ7{DkN^Q40MWnaz)25>8A z;fJVyD~7nx=|16$xs`Ud%Uv8K`FC~7uR<>EWze)&AVvEF4AfrhVqJ#V^28or41@&n zqxi|m_|LK39b3facm$g+CZbF8If)7z;jkC2G7lElShD3b{r0Yw6 zp})Qia`crjN?!$&_0wRs?uTW1IRx|yI9;!VGxZv{Sg(VvdJwkj5%{g%2)p$rcuqe9 z-qz2C&-8QP8~t49&^NOb{USC%zmyHvFJ}|9*bac4al4y*jaggoX| zc8C50qb!wQXpqBttNeme?L{i9KpkO!3q*%92|6p4piF|vW=p1QRwA1zG|EzxevP1q zv3caI6VO8Nxb-DxJqar*{Zj^{^hm)!--Cr|hz9DHmO1(#K?%qh_uC6>xvx*wmfd2= zIJsBkF3*rzZ6dE9+bxE7eoa(aGW}La(r@qbIH{kCBIr*)B_dNba2_Z1lU#j&RWu1w zrI7SpNk+e5%n{%kY|{}g@a63mg{AoiAk~+bnwff9n;4@2`@xg1zVop+P z15E1iZ~u&?|DpiPMEX`on;6%BF2)~~9T{&S=eN6@{@6EXO^lu#GVB`_;R3sIFK=C* zn)axeuv}=5iiyjGM@(L{TzbURc2TkjYcc3aSQj=-i@|0gj3NXD)nm}vYJ8~;HDb`Y z3Oe70nlb2tuF%vtiA4&0iUW?*Sfaqo9B`b-as^)LfL$^0Dka?}2b>Up1D~p}*ErzB z7}&4Ce7>wr^Y;5q{Hs~m7@3>;F}>lApm2tUN{ zr>$gaE9YWd4BB)IA!ooa?If6{&4d-&EU4E`h6}aX=yc}5F0B-v*XF`U+C2D9o6l0U z1#GCckWJJUu~W3gtX4aJg`KZ0VOJm>DJeGR(j^m=yD(*L(6J%1mdav|Z=011ZscHO{Y-8I|A|K-WV13!QtMR={;jCslA&Ages%;EU6 z2k?wuj0Tz!f&?vugw9rcinI`BozC;ElAaJgX`}s^&>TFhB3uw|Kb)1SEH%5Nbt+vf z-;|e|2r=RQ&v9Z+>4otnA(+@#MQCT*sM+p4SMEjR1!XI}%t}$Lgwqv2i-F&04&7z{ z{CgzCOS^MYO?Bl@&ibe-fj%PcM!4jn#KZj<0n>01^b1PzD#51V;xXe-Gjyl}L#|;h+Q+ z%AK<@iHl>eyiNtY6<0`H@Blm%V(cB-m2%_n|7XVb*z5iC_t$R#cm|Inn1bmFlp}dsw=WXMp!`&7>7Fx~-q_r&z$}Bs)S5(OnZ&BZSP{SLx^GHUAY!mG zk!u*8Ij&vCpejdve;{6)zF@#!GMKfvLvCwADVb)JtY$-={?|Pvbf0u$l(D&v4)sS| ztyv8070suj*Pewp=Sa4W+t%45g4Dl0bymegO ziLb6{{0W!Z6W_uop7?WP(T>@qskdo(-0-XOd3yFb2{ZNdAv5MERxuPZ3WO7l})-9C(K6SIDoDKTG}``SUdI0{M%?HHu#% zt`jd4uMn>iuMszho5U^Rb+{3Dlh)rR#>87xcbmxkpNr!ibaC(iGh07_{Xj7VcX2F- z;40k1v7Q&eeRvS2KMYlm{sB-+0|W{H00;;G1uaxo4RWW({6PW$0A~aM03Me?&IT2i z9!d`kmr+Rv7Joi9#t^WuNu`7~ZPGrNVLNRHw>z7eS%^I8*Yd#+;D<7vIo%qR_USk0 zKWENuW`6zt@e=^v!@CqrIj|Nf>2s|`*em){@#0Y}R$b=v6wElVbjr?HF<`h^JvrsR zLFtos__^sF?p2$Jz50Ozj_1I_t_-zdp=q!n=F^zrn|}k#mwXRCdiw`;bQGa5)oxe& ziu2Hc4YzWogqRxiF z8HM2~Vg_9rLW>jYG~>3cmP75BYjMFyT|{#yIA>pVHLT0XffNd!FR|SGm~y=V>v4*m zjRG89Q-6dVd5)*tw%7J3KIun_YaSY#mDDUotw4FyijvJ5(0*{p^sQ|~LzI`)!S ztog{w;ibfbzh*`o8I25_Sj#>^T|+VAcDp8H<#SsJKIPG0*|s&!;YR@b@TXuMW?>Gk z6j}3Vr~k3@__Z>S1^dNv2^V0Icny|_%W$1|BjHNIRk%sK1#850xJ}H%25~dt9k@%} zN=o*(;2!ZlJRm+Keuqc!nCvIu5)1H@_$=Y`gfEhF+X;&aU&1TmYfJ3$4fXi;4^T@3 z1PTBE2nYZNEmT$(z6B6T1ONc;1^@sumqE@36_*}L4+fWTN)H-;eN=5v990y44(u|! zv$HHvSgfrrD7L#mp;gOEp_SJba7&Q|l(ve)>|GfdX4aY6TB0$vZ5lP!7^^WQ#!roW zG(<$A#vfqf|M8P}?(7y6mH9CDo^#K6&Uwx`_x|?hPrm{<4hd#737f6vb+qB5)Q z%F4X2evV|wkngNZgFFMM9(gh3DCq222TXZn?C+82Tmb!<+cYvs^%r~|b5gdlBkB*` zqj--q{i~0x+4b8rWsnLE@AQ!NUPsYhvX)F&6>B##_{0RhypA;Th^p%p zD#?5w3;<_d#BFq%OlCQ5u!Ze8EB*UW*GEj|qB|A2`s{aQ7~^3ICUz|Av~{Z=1{srd zC~!?#*xh5Mzfg8!*W<9Qeyd&GZp7xPtO)9%#qS$KI1(XEHCe+WlRSE>R#G;p=||{j z3eo~cIF$G}YP<9=Msq6Qg~;FuAc8V{){lHUBtW_{#EiLTG$OW}(`JU~aO04Pqp4ym z%UeE~i5MPzf97?%5)X(#Qt>;qtB*iiv>!)XLeaiFwy=4v(fQGCH%OmQbh#u zj5`_8^(La7+YO@;4@v*LIu{5w1#Wt0JtK2ER^|-7Oq3kMWK4{i_$t-K#qhmpmx7$; z6o6Z71rbA*YVnJ227V1iJPS2j;MkpaXT8-H=FjRppS(ltAV0CiF_L22j*2n~0sOYA zKZ#NNx4H)Q!2`5j({eL`V3q55OsHM0&R?o8^#-<6(0&(WCaFEsWisjKRB`sy!d)RF z)_7+P@hdnJ!sT|Tbx|W2IImnME1@feGl0sk(j=J)zreH+#z!6y^@i&dTU@MAcvZI` zYh+#3j?}3Q3o58G`#LQ(`+Og`WYlJdc2}602K$zHmFS3Ti?Ko)EVQY7p5#ceo`2wF zCYAUnYX09F1a<{E1(hV;^wYkQVx-1K7I<)Tc^!sUySFijTfvi}#f{z0)*NYbTY!JY z2uM4sJ&k=j)dPPcfar@4?GGTGc_I*9@1(Z_D4&Sr7Ay*}GV?Sa72rP~>38~G9KyCo zXt(-Z+uU(WdX3*_(o_(#+qe_210;m?WK%wqc%*92h8 zllTiw8YXKO+@fXe`!M9wBJ81U4;h;zP2fQq;?#iCRraGFd#H~k?;KE9J60V0i+~%M zthh2}fW*8W`gjI->iv3k%80{NVO5Qj*~eb2;R)s|9p#iNe=u}_9cd89x;pV8tx6a> z+}&imVv7U4I=zZ~cpS{}5jwhz)~7xw{2J2v4&_nGttq_!hN>Z6b2;-43Hwu!WKy-2v$g> z|7c1uEhk|=#9zOjD1ZIJOUbhYLruYw{?QNBS`fGZoJh!IAxZ;MV|=u@I^CK=G%Y^2 zqb)Rc%nix&&du0(&T9Rk-DP+?VJ10P%3Z&$SY#gA^pFL1N1GAXtzrP%XJ(;;|SPe>~|*vQ+>W{ZbP0ib{?Iwz77XBH?C|8 zs~k_!ucXwI0dE`_1v11`#u}D*e8L0Vq4`z-yS?>S{?4U^w$hnx&_fIpeY0XnuAnb~ znaN4l`^7%BSpf37D1mP$U(Juuk@L9#)Y{;{RkA*`nZJ&xicEky0 z{Z9l(x3cdt;%e^;!q(-0T&rcc#B9*1f5MxbD~_Q{X26T_=>e+;gR%eHU| zdB|@hnZv=l4xcqRuLx1|BotRVk(~&a;?o6&!7-CUP(gUUP1R+IzAHvH9@Cq@*vXE5 zgm)DeM~l|^Vzss;^eBikVa=Yl^h=iun2$TOn|8KdPFvH$T11BRD>bt;-jvAb2cHJDaMwb0E zj?0Wo*7{2Q(Hf62TM-42OM#(t7JT%W2bpsT^r7Hp9$)h@InMOt>Z4Q`h+{o~)TTda zw|I-D1i=7ZZ7^?>3CZT8Ipkx=asZC)FCvoAaN->!dl0uLh=5%RRWPaRHWV>v=LLTUxhqJwMntt!8g8XNCE>$YocDQER!Lhsc>Uq zT}2i{Ap4XNGx+NGt=zUF*gJH;h6y?dThn$^Frljc%R*hmH*`GYLg=Wg_!~VN)mVcW zUF?q+HaNR#F`+_SoY880W5GIdtIPE}o!ZF9#NFMC7SDEUKmZ2yx*SdR9&klB*kA0< zo30~(D_N9JMX(J(FYO_{vM#jnG*j9Vf9-#rJ!=_iUS_yU)Rx71noj6g;GU}0%mNv+t4I~!tRdCQ7}a>H zHw-N7O0fq6Cf`p`E)cd4<#EIcvMNDxBh3Fy;@80h@$wt6Mr7U{KUF1MR3npaFp7?2 zC^Z#BHMQkUnCmrXGKC@~U9|gt`lhJ##-#M-SXR57R*Z&j86+l^w+mOGgrW+bY=VWs z9anTp)c?%L^a2Uxv1qCprlyjQmSiy@)o6NgcOrE}ZqZMJ~=>a3S4|> zoqs?Q9xCYHbIzt1t*mX6p>8-mM#y>K@5AO>q~Z_ngi@9*YsKbo&n8OYgAvH4(C3tp znkEUwu*`U5!w9VfM;bPCa{Eg%Z#`8{9KmZq&rS{CU2@_)#ibf%Itg^KR69zN=^`HC z&l{#s$h=#P#kOu8?%sn&VEFP^19f`-{e1b;Zuwr4U?xD-_i*XNmH`qQM-Q(r`pQW? zUh7Z_%O(N=HJ)D}s(Y4HGTWO4)t>3<8B#4E0p=^zwugry7LkN*$D|cPOb`jZZaWv2 z25$l2lGKV9i@zPO`_G4IG3A(~lCxcW@uXgCLg6v2WWH803!x;bYKP=HArG5~SO-Eg zfmoTyawTmDK19DJwU zIm37#R>3V=pQcBfxX_wrmoxaNTyJxGnVa4f!&)m(OHz!%$Pkg%9^h^Jg8=$)0pJd8 z-WG;TDsxV74XN#0;*<}<@0Uy*WlkjifWD{_AU8ya6jX(;5G-bNq&ZD|3}A`IbsirU zYElVJHWp9n%Vbt+dWbcP6PGGscByPevw2es{`m+2f8=93%Y?mKgIzJ9)m4cqCcSvr zw~YO3cGHG+v~CGewBy?=?5lmC2V8b0{L~UIBOMf*Q#V10B@>Hk6(aNGE`@$?{yj2c zz*~PdtXjRvuT?GSRm-1E0>+p&WI3g*@^c$c2U(>0@(u_W{Wd@l+1)WfkQnGY(5%FD zs8cGTin5x+Njg2p5;K?PyNuVWDzaOaBrdl4ZCsim>eO|$ zQ;nQx`f$>XoN#5@uH?YB#GWeaU@swOui`J!-670kh?`DPr0YIg|FdY-)ud%#wf$$Y z+(&|+s8y24LJ?KjwD_@>3c!QyyGuMJ!2=}G8uJVygAH@8;2%8;%idLRMvToOM4dvL zs9CLGRz_*Y6O&(U8BCNZnqHqUdVz{$uRz)vb}^()-_FBY4<8h%ohcV7!wt1GyFka{ zuGX{B@V1q`lw%F{6~TLq?=8*bok;GIYni1_*5YItL@TgY+D__CQ9XCh58$8xQW zBorP-Yu&bJg`HV1p186dw-Ng=2zIyQ8g#a%zM~WUz$X6s6#dY`;IP}5|GobpxzVNk zyP724ev-V+2YD<6z&eKF-%KNvqefao9&gP;x-v#fUlX{#=jOYx$iYRmC7ie&DmKhs z$?Vojsaxe(sm9sL7B(-|IdhR7J>Oc)T1^#olHZs^xh0zjk62WvNqLnXJdd}QSZtQp zXpJs)5Z~HLO3xoQFKO?j)Sg4xl|k8+Liu@Xs_;hJU090;DD?2=)z1Sl4Tw&3!=tXK zG;oM@8|7>KZYsWn#g)k+`YG{|3ix3kI3q8pMw`gqLnlGP%=$4*1S*OzeQ~8RS}{UU z90jxI%x1j_NW5_7@yMJ;BeqkJ=kZj}@i{}Cg34K6H&a2BP3PiF`r#}-S&!?DIOJqj zuyHK4|IQo+_>z62C$*o*fojdh=?JJ^YN|(PR}4)rad}ox&pEqB^H+s+^D5KJFdwzD zA7PnFwa_>|eG#H<~Cm5X};Yo)y=E^X6DC7OJQ~ehXF<|vAP|DXoG82AuoZu~@ zd3X|XUn_{fCwuOoJ_Er`@$W;nJ^{`C9whM2_&#$5Fl*5n-83v;JME6L5!vFqN@6~PeMV(e1T0sQTxFqa(*EPZu0go0){ErnY|)azjG>gTeX@(QhxtzbCF_fXGt!a?-*sSJ!|*R>7&StVv}XYI#G{ zbXiLFl-x}lw>y=xCiVS_bPDc%$0W{@C0nJ7{h8&x^`dkaW{w&%zAE}xU%H)`2POW9 zDV0^cb8T}%RQ{m6XouLN;D#f+;FU{4bROMGu*OY4qbTi@rE89=n1YPOxX!?pvtJCD z0M(Fxea-D*D&zuxGB^rGJBPq{AJCdYJ>{u(8Ddw<2;k#2HRmq71`!|_tUN;!5$NN6 zF`)5Fo%yB55PItu`tbnI!^60QDv%H*s zWFZ(QxmJ0*%UQBn+4t||Co$I%llmImX(Hw<6;m#&`)>$qwxT7Br0RD|{2SqP0PZ;r zZOW9;k~3|!dRN(Vws=A?m5fwzI6`1`h{ zjnrKtVb=H5597CaAqaiiZ*d1n01q()zF|b_hvB;sCyLWI1#4dzm??YXrdK?djGZCh z2QN;WZvT=gf_=>g3HNDlH1nyITh#|R^}3E+^=E&rH9P3_1^2MlP5Gq@Q!7o*NKfws zEj?;#)xmS=#Lk$}NF%z+H~Y(=l@Q)H`*{JmOJG2VJ(avhL3c({d&D>vz#DdSohHq` zV_v%KOYND;TU)YSSyD?5`MM|6Kla7rMsjn8?<9kyC37Zv)2W-w$vWR`(!5|wzt{XL zKJ!9XCB3KL=wZcz8E~M~twW`bMk0vtjlZKviLX%Rqxw(mFis?Oq@RJXCIN_bF2=hs zm`Gtm{)!9Me|>22SyQ46V1u8b(@QHfLnTKC12pl8Ws>xKulkR^TVfpqHEL&tB3n51 z^(HS&!~Q7o6WZ5rGDkf#9=&-Pb%hqwz~JEDqitIB&K6a27TCz6)Tn@^RuCgCj#x5* zs@kt8HN|KF39Lr2H;4}sDz-cM`frgB$m#PQsUD8I+*-7qxO;_85+S7vjBrUnb`(7^2MF;j? z`|lmvdUV@>VH|pEzV(UGP(tEfOxm%#*ww1ko5ofPO-h9NNPV6mj!KWj4bsECT&zYx zEcaJ1G1M-k2t@_=_Dx?A0SZWYON|+}QNU7JKH8`THc$;rljtu8eBmHmcmq|cU{u+% z=uKo+#!#cMsA?;Q|2l+`Yg^nK;>F~O2*NC*COlQ~l@<~#%!ScQovaYcZfAKXWhZlb zI*5wYMDvUN<)NBQEOKIcpAt zTNN`Ww6klHow)fc_ZLXk9L-Zla@pz2^FKp-NwRR@7VrEryCP$(TJsMyy=8KJbWKLt zy>rHh;F4LT5OR`zRfpuMhbr2{H632x|)75C-TH!&I0h2ZMw4-dHBCcHVT3i8t# zAhnNgEjC)86qW2Lvvr#dht#CkqiWFqG#pbXAh1QB+-c(FC_maTh|OUg>rAuAIJG;D zPB~l5Xhq}FV3ZW5M0koaU!(`~S-K~`RnxMAgGKPl0JfISIku@RrOII>4R+XD`blX< za}xeaUSDo0MTQux&pV8p2qvJp?hGCuPXwcZvsoolXE&o)cH$< zbq-|-IYKL0Vu`Pe1KK7JZ=FffE^k+NPaU54E9k7?dRA8<`c2^`ng;b+WLhZtgE88= ztVtF;lfd`n+U#~AvK6tDg!-o5ucrR#;`WRX09Zd1M{rt+Zg1NqCo~;SO!V1#t*kH? zOad?JhP5M_^uH^wB+-gS1s`W`dFrcq)ajSbjkL^;#~jw}=LsDJlhv zQCi6yoFYONI!x#m-prrswdU^VyfbtrIHMo?HzeP%w^7|6b;)D~w7pa97{;#=p$-V? z0N1-HjX;i1di%81dYZV#=S}@}Xu@4lukRkdPmZX#8SVBWo4Y0udWZJTt*ZeHx9TyV zx5#?OtN!Y@L*Y*8^Hw#sXj(6LjX*T5_IRZDp3H)NHgF0!-GK}tg8F5ib4XJ262M{5 z!KHnve!;kG|Mn{_comssqxiOH+;7Y(0P3Z8Hc?BM-QhJs9p1-kjL|_ng8Ss~-BHP^ zyq+)+T!4b`rUVbrn_Dv(loCJnfl25r#wwy)@>CHbnHM_TeQ%aYUPE3hFjdSs{~Bi` z+#W@&p0Z(49mQhcZ;|LITraHSy$sGb_QqjTR`$%zoko}!ilJwNI3+od~IYbGfqy!N2gp&9Yb*6Z}PX9|}ajs15e#nrp7Kh{c zy~AExnP_t3vA<|K*gW@t3O%DM0sC!ajZc-mIzyB7;nk^``hR;O)!4e)`9DQDWlfeo z7BW$uSvXEbLGDxc$nb-{U>Eg`8SXF0vR5W}-_&b!gxr`X3kvlGBpovwF%92lSoTsd zAJM=wN32CP_y6ikKnd)Ib>SD6<*3evjkMikD?23~J#ojB{9R4CC8>t8GCKXo>qs*U5D-CKyhH2IW#;^wq3ZiHpm5?(%xH zE2hK-q|A~VZqOaVfeW=rUQw1*)ian7kx%xLGpdP_5DI^g6$88pL*rhpo@aj|dfwqzg?x z&MePYbLttgrDNUFtW|yVZ#WCaDl+}`^`gOK*n_(U+bf6{pq7MrW8=X`;m@Vm_U94Y zS;w&k(SG~@RP#Jy9ks?%@+CR@BW7?kY?gpp3^Qi1kyFPEN=aWPVB%foF`52HK zYD&Z&N}1l~T;T?|N6E1{@!agetD3n{(AH(To&3J1`qz_-`Bsyjkz_NOwOR{0J*i!t z&dfBo9xxKMRTq=mprjdQQYW4g*wdeO({A zACuum7PQ;>H@z1GI2ibneNE5$8V>Q!s*aRN&T9#~T%Yb(rc@fAl|EXA)30Q*7B^-Bm4+I&PadI}wJ z5XIgc7U(_dwlU_fPt`}7(e`g{%ViT~^7eU*+TLDSXWA3%nU&T&wywS%N5xKDnq>Zb zQyAx5kOWKk8cl!nuB_Bd3$|OTrTE zX$xv)2Og5frXtiSC>%RP&9ZXfJ?GnJO>7!+;x-8!qLDaLuElZA4RpyTYjPQL@vd|Q zbz5%B@SpkZrO{y=H%P?n`x`KWnQlDBTP9q(5whwUdS1;Ph?QYs-EhR@&10ZGIOhrF z`sY623BZ$GNd3f6vxcHdvUrT<^f<+O0fc{`Ld_mJs@I@V{> zOf(z`+aTY0f44rIPWpBfsT^>dzO=n#t*lV%SO40m5K*lyl|4d=YhBMnU(*Me|#kmMF0^; z$7seTc!>uOE9EFEW67=Y;Nd+GTA#?Xe5a9ztBv|RQ%oj(9oVC=plgCZ>zoe{W`ELc zld-KFyIZH#^KR7d(uUi7YW4HNxAX7NhJqZ?mkVz{Yq@nQmT zd)IOP3B1qU)_Kp@XBtCjE}(DqP?-ef;pEj^^mv3GV}L^K>jp`dTm3c@Q1-eU7K}gB z!i_?6X}03xg}l;nUsKO>QT>E0T~DXk(B9-g9%}_T$XFac;j#A!9X)}a&^BM zm}#TxFQLLvJ^eUZ>H=`W01%frUR!)h9yv|e_Nas;pSH(;a?ysr7j)Mxl{wf4wyMmm zxOHVayHqZ#xBVU&+Y+7x#l1p+`M=3(01N&c>O*l8ea+jZ$m_z2?%^~tj5QJ?hxi$S z9%lXhLFQ=7J>T(dA@isXd1oU=y2fC_g)055Pc%3{aiiC%+zcpXFza+K=G}W%oa+F1 zI=)Ah`+vUR$F7aJhvK+#1M7l(;!Mk?z5jl_VJpZ$ zR>r$sZ*XuM4j`Oe_>;~xV@{4Lp@qHzeG=T=x+C{0GU1Sl#RrMeEBY9N)zL5K|CrcN z*LwQ@<-qRO3wP3l76i5GBs_Ie8xgQbv0ZH{?FDoW}e=i<$CUPuDtEKFP{YPacVaMUr6TA)Ju54$fC?QwIW~A zaT}j6yr6)tlV7ouf1<4%R5bHT`A4QEjq7* zY3Bf%9=EvHd4jDDcG)r}?v#|PF8Z(D82jzE@3aalEBHtbJ)Qer0$-k4zR%YfHN3BX zx$3Z>#Mg1)#rn&&*_faCvlCC5 zpZ6oGt>13 z^{>NPd9e_xEX`zEL!2`rwU4^Le)b&quthXm+Yw?iJ~+C+nFZVeW>~%{Ci#9x(8ePq zajAX|I*lM|uF2+evPDuT5fm9C;8>vGKHy6o_jC^0XJjPYOy~$mIs5Y2Gf0{=<3;eM zv<1NDJ=JVNn&Qmu3s?C&z%N>)8Xdi59sH04HEf;idyNZPyEbkFyAT|H z50G1?!eCPBfLHa@)}~Radr!Cq+RaAo^#8Hm2LD;_Am1NJ zLnkHu*&Ip;R)y|eYALFxvkpZ|+hOuYx;N(_f`Q+nUm`zDpw}Ru{5;@$$lbg>xJCir z?PPkg?PSy0+^y&1^B-2Pk4(^RfWDBR7@{mJUq!R(UUWeQ%vt%d)mf)%28X*|P3s-4 zNJ2*`&mHVu_y~xzAuCBCVP!rTwTOu%Kzm_6SbWs{LArAvc_!5E{F*XAAdWTyd0nNE zq#to{idx^?Ac!&lRAIJkpVbImbO}j!^OUF zX9&KO_Aw5;$jFb_+>Wt!2)Gli2lCpImg{2+E=4VGYmcLE-CWk0Fgvx@ z(5{!^Mo~*T+=yr&Gq<97*z~QQ*81l$UHuMsa#)QPQc*W5`TZt$}(tq5eqn#JGeCEV6xv zvGO%E{vw#WXTH%`gTf@q1|toB z{+3Q&{j<0do7K6MK%Xuc>3t4K;-T`Op`wE&QVoQBbeQ>DtYR^cL`-FXKDydP_{2ne zm?{E`u@Km<0VgjEBJUwaF{T*ihzq|+P`WHMJHe;lFt^H}E=BBN&L~wIoKM7T(n7hO zew|T%y&O^>a)Sbeep>QRpsB61_*Fu}!o12Qo?QztqQo_ zfZsP1X>Ve9|GH)rh8J)E`D?P9@xgWn(Ip>=YGSH&iKyt%8=*aak=-NwzVWX9kpU7! zKi5u3j_qa>>+fR^6iV$s!n&Vb08m1dMVkl1UK;sfhk=|e;98nQ0U}qT& zVNsmO!g-?lW~WG{pG?N&2DFVJjYzu&fvcGkj=RTclVTxwi%*Fx1RG_1$rIfkm9% zDs~8=f}^H2yE{mN=d05Z>#|36a8VgXgavZ&ZON&R)guApQkUur?Rd>hw|Xs!RLk>`|vTo-|&+ zV@i}hZU^`bwzZTbc6$|BjB_b!J!D!Jvg=kE56on=$~lK=-GkeCnqakjbWQT)-BA4R zwVVmg*^mF(=2}x6Lm`M$x&k1e02@juLWsfNlI*mS=%Kj&#K2aICW`*y6mmge_)5X< zND)faxa`Wch;C(DP(l3B9NX@Bs-P8}w?N*Mjpp^ph(xLxX;)wG7ung{`XK_oz^Ma2 zZMlQ8nCQr-2AJDW-V%X%7gZS6I`{kWI~o-cWGiuPRKf6Vd%*}s)Oj1i2+XihD-~gU;A&EN7(V20bg+aI zj4p2c!7hZ&pSp@xL)foMhLS=0jSf&Ei6+wC2AG7-ZMssb;DhOk?S?SwjKY8O-W5;N zDZOBg(X02d)A;HnB;Ovs0Z<%q#-~fi!7dj=@u)y4zP*g;0ySbmX#4bUY*H)AZhVTC zHZ@_pa1;V}ET}n^?HBkdQGTQgC16Jj=2?7O$sWK(<-Q~igU;$?7nbT=fV>~<)iIZ=KAy4W zC|r-(9ufYW>b!1KM(U^bL0BN@O=YM;_oE1Rmg@b_DC@EZW;mj;i({5Ss~pXu3{YBR zx~-@5Y{D?y{dVCNjFLqZ-!^DN&p@NGtcwqcGHlDKK+#sn?|qK@#tHFJU>m_3)MPWX zgIZz>D93f6fM?*!7vKssY%&9@H{wfN*sF^L zjVQ04b(P1y8j0VkFsUA}OMe2}qj-?c(aMq-tgXX=@ptbjQishk?-&ll2nvc~=IW7b zgCe?-C-{3$1ymI=HZnzjkX%X?*ZbLe6gS4BmWbbh1LpOTAK_kVu?e&?;VxF%tBh< z(mOnbDTwc@aX;Oo&SR^(fKLsqo$HeEuoo@8Jc9zkiIX}qymO;%;4rnKnXmgTPOQ8v zfS_h00eO*9>*gjbEc>~vBcL==24EB$KKuMW--#-om(F$=#g#9J$bu~Z+;Ebt3CxS3 zPhgCf+sQ2P)mudK${&bozt$9T%_aQOKD`xb^F0BuzSU?w8-*})Ft|>~px_pkO+F*X zoiLA(%d5c!(&U;g$YCIC;?{`i99U#j5xukTzYzEWKlSv!?=r5u>YKt^Xy9J-iepSF-;~xyQ-`!z z$7WTvnX*nj?kBc3n8+AAR6%nYA1lv}EVh`ABUA9e)ezZL#cFD)`i~b~!cop+!yPCF z*_UBAm{1@0Y9mRg-y9S7Mz=IEXgkDBqcYGM*vEDwhA==ddzr8R0o1IbnBX_MlmR^! zOEfO^m7&~u`=r5;(a@zhD)c>>iVoN>6QSjp!&t$$5pU`IO3P4{Q6iYd2`dk%vpT(8|!$#wx?9;URaUJ@ZX? zl;svxYOWitCZ;I>nq=ET*O2hjm`@CvY*k9j$UT?KTuU_Qpnt?@NzGEAsN-p9B>MWg z%$L&b8~Xaw)aOTHTkJy}C5eN?jG3IjIMZdI;3w5#|Ilk1t&y_ZIC}(P-sqN|4Ou^U zE`cO=HS=}{w#dyO3nl(A@gyf_`)M^?J1lfq#Y8Oxmbm5sJeI{YL-k}bdqjOTE%0-opv1$!O9tRxaFc#YSh75^cT^_oS6AQ&vQ$${f2eDzp}cvv7Y7H zsrm!5eRY0`#24}oy`JI9WNraTi@Fg~MBn66%rRUMrn+N|44YY%NjZS{%k%#Km_8%D@*zMK^{(4jZSnGpaJuT}&g8-!`2nkn)`b0w)E8 zLjjS-A1D?d%CHYJvHLm3@qoXq-^dFeG?RBVin}|2UFdIgF;9+H*_J7ye$U|Qc~auV zTSl{6Qb`%sqb7c_8KTj=Y(CJ{F+RrPEn<4i?EVE?e2q+ZL|l%523zv@EBa|G<7`B% zjiJ$thP&M-I9>n;Qrz6pnrz{h{1rH)oF_JGABfLuZzk|8I@oMe`Zn3{nEqlq^1KjGx(ji$jUZ*hp7P{lTll%0kS_{CeH%yV@wfEF z?z(_`WWk!bosoa=>q&A(L(;T!xMGj6_19!Hn7y>ex>LV&f%ir>lZto#OHfX6FnN3Y z2uk-KAwr(w7z}}*QWf)azk;i-CGJKfz(lCWX3|q+$ejz^6&mo-pr~)ZPT%@FICC#3 zb9)Emn^S9D#H80;M@GI;!NBz6Ljon*sP_m(G|JkhQr z1kY+4uI6?ACzV^#-(}q>b_9sjSKnh%xXh!)aV(4=0S4P)d8HlxX@Hb29!r{KE+<}z zEW~}DrfPf=``lj%4_;&JL(hdrQec;JvxWJ8JrW_u@*E)I1?l?trW+-{&Ks?Ch4asL z8~}M&?)5D0r(?TX4iW6nwtH@3yQd#5sk1TUHnL1_Yw`iH9rqA_>1J@ZG*S_tp9lkG zB!bU35md2p0`I^5K>-K-4<@rNVwh5H^5XEN_t?xIUXHPPm?ZN&Kr+ezqr`xf?q0_@ z#hf(BXfo?Rp!IsO&ClYgO;#k6e9nBqWZe)*R~GQIF3@MJ1G!e|W2|FjE)vY9 z(;Mz)_V$~g-}&y$>y}6Z8E}RXVzgZLraRYLX5*JOECpF+oWwy|RWnXO7Vsf(R@FlbI zFa5I~Lym<(2kEPJB%bua%o0o&YP!HBulHW-u#A)=ELjqDD+&6u#?-PF<^%{z5CDOI z4~~wP5!9jL-wU*WZW`5!(t?f4)ein-4T3F(iye+rRVp4|8`a$RvykPi@tk;dfX%G@ zX~{m>*|J5&VdnAr)&2Dhtml*`N4tI(P1+d-_-DK?Sci+GaB2bt_`M34C84kFtUYRz z2C?x&wpPOtKE}?Of z@1@+HS?yjz(`VB6DfEdmvLN<|!*9D;eX)Dsi@MIc9Pm$!PYx3)3gtBPRc#}S_vb4$ zx33JLo7s*~CXe>D>zhu)_p^8K1YWu+ep{Az*+(UAYvYi+{a-B7UX%Q+%mCwKYiZ2o zwHoKVKA9=p6H! zd%|psTT(QK(Z~CBL87f`WmtG8H1ve|I#o`%bMaOi@Mvpsuk`WJfrVHBcW!0bZQNK2 zH+OLL3*LoY&HW~n`&luFc>v8HM@qJ=6HJ`}Llr5S4I4?xm;qLv4VIedp(&yroO}~o zl#|`iK35%tU(aLM3x^KdRlv_W*(DF&0T__0DEF7~P{i3X8K#Fvmi0Ya{OH)7zqfC% zqF;(ST=nA3_39S&F{I6bJ28{@$n}aJoC4H;KjYQ;*uDoZ=cSGPQ3U8SgCz4Cwx!On zx)%wmBVJvxp=9~m4PPn}#7k7b@oSHIypS40#sNdc5$jpsa>ZXkGfNU_i*wgtR5TsS zYta#uBIXh|kF+Dt$>>9;(&KUcp~HEV%ic2pgY-}*;}I$_(WNzPet!B1&J%GYuv57e zGM@aqsW}yy>nkz)VgOIDMI|* z6i0Qv1PHW&l`6eXNz=V((sIERLjDicQ%2mozuQEM8TX1f8-T%NzQiC5c)&YIPYdY> zz*A9k85=rQ8u_@}d685mvfVwL^I1t;L=O)0^_+L&`lZ8TM zaoeR$6YGt}Gf=k4oRJ=o6){aj@ zDHTkAg)VN^9f|e;E9=6#wJgrZ*7%o9OWeJ(krq~M{!vMF@A?s2m1@*Q8 z$TzyD@*Yk672q06_PRUDamtaKea-0t2k zW@9;&YSd+MCUTh%lZyNRQeFJH)(7i1frE; z2>|!BfJ;cn08Ci;x2MY_op*#6?`tQB*cxpUu5`wwGlss;Rx{c6OHp_@$g@&7C2~6X zKiW!^-9my9XOpnmKb5+z60r0X!1b zqz!TM7i_AMg)7K&TVW}y{h~`2jJQG6&F8rq$8tQ$~5 z`ep1SG3#TCs;ke zeKsh95kgh}El34Agar)+<%bUuhQH{A5+3&D{>}*WS=Ge3_+*9l$GgCG$rChQ67JPl6}KGif+!yW|vDv(_>0UDwGTUTMXm zmzS#79gQ)f6f;K>Csi-?fjC`^>Q{2Gmx;kSe|zkkV@phR@uv%((V=+zs$)`AV_*kY z@sF_}L~h0`>=hXF1Ck~Jv?y-NLugaa$aYT%3VS39*s!VEqyo!DEdV^$risNGxpBIf zt(jp;xh-Ur!hr9xunxHCACh|bBV5t%YgeWJkE?TF5+rQ0^`LFrwr$(CZDSfWZA{y? zZQHhOPP?a#+uz>UxOX?A{y@cB@2QN;lg~M*z9?D8OlXFWdvtWY;pE>L3@K5u z3m7g9k)ZA6JCEhi2Az7@VQiDwu~R_*XVd})Ih~{79P{E-KNG1U0bY{8Cnng28TAix z=arHx$WAo)ndNrI7J%qoN6c|2ptvfibU}A$U+=}};~KeaaK55M+5JPZ|GN)Iju3|z zN*v!4N_srUdW}-J{4bM=m8xF_xEXa12WmR}&P6{<7T=YB&B9T|=rj&nZ#iK+h)8}O z=?QM(d(N>YTEh=Ejsy4Jp`Dm*#<$CVG<3+SGCVNZULacDvB24N=WjgcGg-w1S(MobplrYNI&B2c4MTE*sI3MzI05rAqP1wTO=dxQq`UXqDcs5(6Hzr zEDWz4&Uax78&LlHYJIV1_g%LL=LA0H2{!O4T|yObvYgrRM+;vzc68!Xut%V=8&ln@ zRIJ7LeT{zn^WSfT7Z1AJM=??t$R)c&X(tR9tOGXs|?P0np-?16GG8;&@h$Z$_C)oU0Q<3&2+ zDYpoYbozL%QU=i+l=Bw4!sgqj!Gs-u@etx(R^t~?vn=nWR&jw&c5sy}eyWmW;Uwx? z&Ep&dt_0~4OBEq?qYK}UYm234n=cGtfGgW^=ItMal(Sy&xWpRXB?D>)(poZoU5&Vlt#qVwcF)*DJ(rI1|`(ETB>a zSBX_sbH0;R`Yt6CYhnVkC_MR-54Veu?zp_C{M%-eDx$mAQy1}YI8py%6U-|??ZJ?w zRIun46n(*U5I*V@>K0LprV=t21;oh8i8~REqS&ucxJU9!}6R+S60zYB%NOo_YYZjkhH1g z)gQ8MkOk6F*&|5o%XhF%BFigClTcftqGeMX;zN+XjI^&Qa6Q#XSAQ-30JRnm{pZN^ zWCjfUrG?0rC$i%|L>fQDa*G*FgRtO~qXfB!Y5lVs!oq$l+ay!zMw3jD(BLKch(}g^ zY#7ps%J1IJQ#)X&Zj@`FZd>^T;}~EZ1zI&Yo@ei>2OUvQq_%MYhXx_qO4& z`^vMe+XTMz3EawU*GAldS{>ePC^pZR(>m3pyVxrp<3I9~LEC@gr|HvXgG%{40Ju@7Kg$y@)U7+B$#yZrXAk4J3&~Bo?PrxMNadkC z$7Sd*gy4y4IM)pxbgk!`9VBU@><0(V&JHo{UBrlrEPAVB^4Iew?$W_79pznJ#od2; zEhFl?^$$zs77_CpI;IEGxfosGI=|X=v{!gFMNNv zt4;`_e*Ms!{rp`MtFc>LNkoE=bxhaKpT72*3QAo3Nw%szoA$r^wYA3tb0+>JE?Ol)7GZ4hQ%h#EVzz9$Ig`0`mBC-{t^P*=%L}|A7-;FfF2)5~d)PKWQvPO( z-=QS>HYne`2tir=8JS6HiD2zb>SLdih8gu}=F~%KOjYHWxP1v3yaZfoxPShgDsWt* zLT`r(*@W1}ApaYV>z2Io&-ko`b&60;GtwcwEyp;LtLs-i*)r{NOi`mif1`@uRZi2? zsEOVexAa&=Ia82zWbU_yP!3J!pYRAzM_aZria5(l$KnAVOX8Z*)FU_{ zh*l1tyhG%w;#zw={TZntKlPyx=LliR)VZ(pJ(?Y?8cJeCLVxB^jq-#2#|pHEbkWG z!KTD20c>fdvldgyX`$E2u-C~%P&Ia<%S&>cVO^d3}t} zcnqq>$QHDlHn1W3ZpQIuVH5!CNH|h5TT{XfI!lWeBBR1fgbi)kM32xJ#Enq)#zF2U z4#IO&lH+KZ;s8xMl%N|8YZYzApkQXJB_#$0Z1QD3Rb@8O8XrmCdxIEuPUYGl%CL`A zdjj1eUA}e0_^H_i6nH)u*SI7{Gl#{dQFFEGLN!C(gn7*Jb+>dp2}qjX?520L?eOb$ zSH>%SQ;bDp4X11=UIQF#rSBS(dAgQWjT|Pq*Lq#$Ho(%rQlJ~O(u&pk4@=~vQ6*nj z+_~}GGS;n!QwE$`d}Z(rvwc}_;*o0pj3pbsZv)R{f?*pRv;*Nj#u=t=gb(aSyaVrw z;9XqqymS-p!@WgpJa;Mnx&GP0<8HPEo(1kOU+{{9MXoVq!ykg8BU5_UuwX=72L(z8 zWvh`g12DwTekR6~XNX1#h}kQl?rcjxna*ubPLO&&^rTN-s*gEt^}ZeX^v0%)X3yrC z7S5`Uq>NVofX|YxoW9H@&otOVgOsb}8pC_`G>?G}mJ?%Dm-P$_=an(VqnEvZ(y7|R z)5lkkIXGjeVsRyn;0?|H2H*)twTuP4#ZV8Q0b}*xtrnAzRBLVt!;M<+!vwf|fu&79 zZW9(rZYQGXVx>cR;;KJ;(!AEJ(uM)%$fZ56d~y+O zUgiuZ#%;btRBW5(MdlJ!%0ag-!QM>!Qxfq8eHR?p>v(johVAQXi@X1 zChpYHWpw5q#WX>G0rs|(Q@Ep8GHTwEtIOO=O`-DGMI0*9jEgOl<5naAg-6F7K(Twq z4`@<&ToIz>@BM>_SX}8Gm~IH|9+3<;>fScu9vpXN?uzWONRaKCv5asCL!Gr~VKy!H zR^?Y^KJPuPB|i0S((ypYZv1rkw_70iW*5?oC!8q0IE2AVbs{kkN(o}s~3K41R_tv?OuHFwm17O=2z;Eaxxhb<3Ve1ZG z$G?t#B3F6-U#<8P0^RD^Vx0DlFUoe!;>nLnH83r=Fr|(aAzL3Hh)2D4l zGC7j##~H_mZ&{z7Q6FzlkOnZ#LOU`3F{mIj12G$Q6LEIyVy3nRqRtI|lJ#vmOVGg= z1x_%sQ*DODV3bu3zjgo#j7bPkM75b8L4+T`Nrok-iuFPX#uP_Df+D(5C;^s8y1#QM zqf3TfCZPgTIqFM&$4EGJ%WpR@%>l;iLCN5%2~Cf)AENRp)Lg<11}gWfXGe8*lhz03 zp{NsaYI-v?!WEsenhldPo??qCc7b~~`<0h$3FIBNzaWD#18o3I>+`@3u49YBNKD&t zY8;x>bnP@zHG=r*cFl#K+GrOT<>h&M*tX+$P&VS*1*RTT6nXb;Fy*Vu*Xz4EWXX|aI%3607cHHnXge7s+DlXP}6{}5l`&6xE zSlKZ~p^9^i2-tTrObn$2ee~x}a+xLjsVg&Et;oNZgcKLVd18FtVlh|3N%C!wf0SFJ zIQ0LG4m1Ofh?@5;D1B1x5spUVEgSwcAg36aN+($@)QSFQ5?4G04f0HzHQpn^b6@NX zCKN_TzHI{6afw^m`|B}&9m{O$3+F=KDuzg@>T%Ni=}LFx_e%jWhTj?O$h|S^%+8HP z$NvjshRU@yRPc2nmj3HPBrjEhlL864UmgRL;O$jAO)az%)Uq#!%%Ynj)Dx@($wKtd z4|I$?kNp~4!`i=bo3y)+9{Z8#Y2UEu-@bo9$Se#%e+KMMxPXqS$Ge$Lb=*y~A7@-V z0{Y!wPS6_=mI0U(vONo<6TN@D+8}=WbZAsO2SIu2+9lz2$bqYd!9@O$#tGx>pDr+ESEPX2 zp>kHnyWm`A^@(J7C^6E^ z{m%AgB{sS7Diu4%DxAmZqKte~KFndXJO$%>rj?r;a`Ll%%`RJMDw^QaLcFbEl8*XQ zyeb|DkpMnwIVKDz7GXQAM4`#@JeAxwnnuIAd_8%A0#-SIJn;h4KgTxv5+;OIHD6u9 z-C#@7fZrl`E)$3&ko-^$jtIaS+2y!G7wc)zTjr@_?bwn8J|Gu8Kx1AsxAj!uN75P8 z?Gyb4x##^01{?nLD=S7=-{IqHJK)9d;aFmWAed-_S!uj8qL9J$WYC@A{&B__--5g; z`oSHa7I`*Um8&r-goag+&t7cDUkcn-Q+ou@rLi*_Ihw<9L#b@NC7*t%y+u4pb0P_n9L6Nf3JlZ{q}QICL^^*qY_(9yWG|CTuHqldRbk&a#29E zR;!)Iid|p(BCoQtx>3Hpqp9iar|0L@1~+@WWY606>wDH)3a9fW=kaUTXLI%+@ok?s zh~GiLS-l_z!~3ms?rFi z7^mW`K~ND`0&TYTWY||~6yb&QwVk-7S)EY8>`0l=)=@JI<06x*Zp;CdXbz(ZQD2x* zpu(YeV~}HsBE|XkVq9eLS1=G^OpGC0q8bKjsuli5x~$8pGzWh-#y(?jbQl_$q0?o; zcWIQjb>mdl8(z)GC9qXRYeN506Oz*6acA>m<_q!7Z_l%R5UGM;0v;Gsv?h|m|<&(s-}$9xgC5=0#0*hTqz_= zNH$sO;!fkWlojP6&lW2MHGHgPA&N~nd2crg;qEswWZIA&8F=!Opy`}8Bl;m@MQdJq zfPneH#yYQ@x>=aoC|{@`yF_m}?r+4E=6bqr`#+gAZ*#Kf7cdnlXmqV70=9S{=qW2J z#bS{jJnkod(@guzv~}S$N!$J<`QMUg69urKdmrXGu;dto?oHl=~W5LliCB}d0b8Tg= zp`wGD(%u^-S4>ufRn{)sAwWI?p@A;?_@MJ6VAq7u$vaAN7fAUi48&9M<1{*S#ULl5 zYeuHGQqby#_{rpPsUBKClnPAqgWrgukZ*Nb%c;9)ml{brE1S8q{;IoT@}6ix;|~s7 zq;A$`-V~Oah|{$5#cob1l3`1mG5gDn$2u-;WeH!LK@yWg~H2h9I6sdNDVs^aTEM_|^zc8l8H}IBZI<%hSlC#UL zDw}WF$13JV>fiKp%IO+!P9_IzWo{!qoXpY&%0p;)BIsusEOMpWjWDTf4t{$Sl8^pP zzA3?v);x)KV6E8U^gQ}#5@8RRP1A7a`JFD3Q?22lgHzCA?A2im9G{6ex!Oce@Eh(* z;t(p9H4VCbACk9v9Q~Gs7P&s&Wwxv7rD+qbht^Y%B+zBKtNr92o*@~w_;Rr$RR7*2 zv^aWqR4_ykwa2~JuuaMlt4gk4w)sfWWxorKL_6tXKNtOpfl#f5sj3t)J>8!Wjj!$T zojwjzQjAt|cwKt{Pz0=Y&7WF18n=k#(~8-^uj_>VVQE>$K}DMPg_&@)XAW&l2YC$9 zo8I9F?yL7bRSzQD;J;5RLvu5Ss^8$QKBWb1OR8L(D|2~_ZJaX|i+49)gL|Gu9%j9d z_5u6TMp{S>Cm!Q}4Ib2??f2{}a77m74B-E0XF-j8+fw=s;9oI_psZb|c7|2SNtW3| z2ixzrnC!Vzq6u#h1h}KkBWe%qZN*5)@`sey zZy-mzPQ#acBi-a^byoJcT^gOBRveuB>!wQc-S(STQ_WpKnMmTxA_Ex2ppnf1LI@R& zhyHBdZ_>3mfU15$LRIb?7e``bwY;=#Ap_^$rG;Efs{hZwraS~WVwzSBWd&O9;~7Gx zCL@IlEm-A3zN)6BR*rtL!WD6G_0)-B<8xTjL51PBk0WcDz;!^&v34lcO-MB#s*AX_W>Xbzdu)q=qhd26ziLqZP5-G!bbz!Wj z(R$3FOtbE#AvgbCfzkCEWm-S&j6|VdjWo`&eUEdx%6eR_P=lc2Pa*Q{dg^^B{CuGN zA+kv=b=C&i=;VAM^vmq?+aZ-XmEWMZ6a;J?f?A^Rg+Ud@$ih|@jdS(mNcRB5$_G`53zKuhbFyHI{f zIa;^X>|kt(PK_DWyckCGEQYGTa(lD1+Qa?K&dE;2=93N)4RoPVdx;a28}$`>7&heP z!@6_ki>17J1#$BVw&qaTpHvFW?F*U2gX*2{z(>@@f%XFxol5)L+@PkL{EeT<9?@#Q zh38p;@NV1w>P6|4pOm}p?B6Myc)7y$%lnGT&QZA10g~gm5`^vE?g$n!cOi6e95m@P zo5-v1`krMbE@IMF=K4WkF+$a!bEdvmhV_}NnA2_uw~XYvM?zgL zfEU#);aUCqv}3F?8G`>5Lnm#aSKdj?`@Vngti}XK3(Z!1R6PM|VT9w^n`@YiKXj6W zAqw&d(;ln5+$59UqI8y9h%o`=T+G1ge+W1cnWKl+ri;Y^MXs%}56O`0Hh$j9Y2 z3WSS68os&+%y|q&)%EGbd{nqkf!9}Vzz?Uvm{}deEraD>@cdKYb+n7pv+1lChVTAz z@rw=BtT!@lt~x}-y*R#RREd)&^R-!vYjMo|-e*TSZK6JN)qJG8PxDamFQX)J?MmGH zaA5?leM;DNmr-pc?Aice3jM|xqa`hFU-cnod(&Awznuh*B~HnsgQh#k8C_R z*pMh=%_{kK9LkR~xwHYXsx=gaza0Kj&D_wcDM8VTaWX^mZTC^;Z{fTH2LJ?RcUv}` z`&nTFnHS?w{R#6*UeFU{tMQyWKsH#>)uSdc+KHCHmD!DU>M9_4PoU!BaSi!td<}#l z2d7O=E2X?u1cUFlw2Dpc(vNTDOer`&(}qMk!fE&R2j&#QL&JJ5nPjmBRV;n# z)|;?IPf+=sRc9(UJJOVsohhG3@raq_N9T#)>zg~BBuB>yW6a9ips;@jU`g0u1!crJ zp%)-&oL|D^T*Bm3?iv+H%FrCT5#Etg|6P0WGIEB_y6X381TFs47u2Xl)E($W31Wra zCZRtpx$1BDSz_yf#cV$uYSFLGSPx%(I$CETj6ZeK?=P(3)H#vCfppRDWVn!z85zfG z@Ex@-hJ#)43*HJ%UIb=rQkzkH~Xz1Y7Y(+`22gz!mD1)oKS*hxTc*-JjVQ5wO*Z=M-nq z23@Du^Sa)37`1z&X)VOEM<2J zqf<;Gzvc3KoE`a=8<1;Yz1zaP=tXcCbq0>xXLAW{h*q2(gRRuY6$f;oSyR5p&VxEf zYvpQ5@czbYj5~(`lvV;sBIomWZBRIhd*~g?>SYJvf3Zj9XT_vhziZ^n8G!J#9{;G) z+2LgK;RB6nwGvc1;B$f(6T6dn#u;{<;8{Km-r!S>&G%)mXyRPrNmWqg$!=^EHf>|G z>Y+C0J9!C~m)Fa14`)A~uu43ics&&qYNRZ9_WHKyaQS4%#*2; z%epzt)crD$p*i-5gg&*DBe@fm4XL8FRmgT?E^H;0H_FEDax*A)?juu5YHZ?o?B$Ap zy~qt{*`bUDs283T{P-^OMBJ4}ACE*6rIOdBY-y>AQxQo9k2VPZnL-hKw~7_EDq8Xx zseeXb<25tpSXbVKydWQ1qn6S>MF*FAV;p0RUL`{gZ$Qg?1@-lf&EOf>hG%Zz87O&# zINDKMdoxZOr+`$?)u}|4Mg!CFMPGe8YjqyjV?7oGQic@@w|XUdpLNzcX@7&@E9dKu zm#Bq4?4w*d;8F2?c@DgACzTrG=wB=Jjw?b#eZZyQh?n%191(7cU2<+*9t>Z@E!y#v z9@cz$R}?=epKesob}^+MSh)`CJrjuG4ylUJWI6TmE!F=`UlVXzsh%)X@P)l-3*{lD z=f7hB#^-|{_cnG7|L)3t*@)p$DUQ8ZImDu`bd+bP z(%F>b9I6-wTRA5h_Zovn<&PBj_9YzfbexRL?+b8IVYL;(>q3`Dcq!mio(WGstHNW! zqkVhA{_&)p^?)^Y&0RFMtSf#1l^mj2rg^smm_wl1+2C2A4O_?;ynZjpXi(hOc+{&e zeL!Gp-gjXJ-}IHKCA2;W;KsOn%Kw#Jnjwijhz^&-Xg_RnY>^Wxrtm$ z_JEq_{l}CU&G!!>?I&vD>GZ%)dzInsRK4v1?>G1)X6PnH8+V5c1CVYB%#}hJc6p5w zzOIP86>%qpLS!=kMj9FHo()~_^^KIDjm(?xzHP&$GDhV9K{Bzl+;^H5k zS#qkT+%&tX2Q?4d-hM3!`+Q#oqtBGJGf#)?WTtMHZ^nbqZ6>^n>5m(KlL0Jg+7g1d zvJ}Qeqh}?dYzonYZu3&631#Bilv1A{psYtqwe*lL5(i9kJG4PhVnX(8_FI6k>M(GtCH1%ThIKP0O z|MyGBprN_rMWs88-m6kjv%qtMm~znQqKDQs2$~mi>4;>?(6+M*i1eaLg{tBbpy;~N zvz@-^qW(-;p#%zoFPO3yLE#TA6!P`J{`j;}Lobn)DXF@ZPJlX2(9ch#x2MHDEY2k1 zUab6iSt!HA5xD6_bbTIECm8a+))A^tmPCDAruz_89dTezL z?<}>z)Me-T9!qxNy!fi9C_fFPokyzu!d!0*=+u*Nr}Xi~wB9RhC^2K#Nnq~Mm#{LT z-q(d2+D95~OAA24xRR2*7cAWJpB#6`)vI#wNL5)5`Lj*VO%2(*N)xQ6)LpLYCU#uQ zJZfqlmo}}4$36J|w`8))YApjni%RZcmm9%>SyvA>XYJ(TSaJCLwuT;Xl}v;i=nA~m zJ6!r^O<4&Nk92fT{&rzj&s=tx<2tA=dKnuKR5G9z6`Zq@ilDqMC3tbT@DM@nvESvbRrSn?Nmy7R#AttMy zA6j}{GZ!UovCn&C5en?_o7y8YvJrI6b*CMXok;EaQPWE9tuItYeinZaCy^~$sb_9^ z=rJHa8T<4N#YF&9X|s`aW$`-cCvB2H37dOfNMh~tR^DZmo66fum$0MP2z>Qo;q}1* zEytAVt!^YM@*%C+Hh;<2;SW+(229EKs5tYQW@uoSbVSSIiQ6bHo!{?>hJ(t4*__(i zA$4akPAzx|mQ>yB@gLB^h}3q@{-`|k4;;kuV3)g%s<#6N<*FOBhZe)AbIG_K_P6Ue zx1UTP&%=@*45R##xAO1E2mFs)2ku-4pRN$M+a%BSv2TiTz-2bU=kp_3w$sSxI>G@U zam!Eij4ts(ewE%qSlxkp`+9qKi<_eIkfV-mj62D&7DE59i&)#YI9IkHT|75Era_6c zAbp>coC**FlFDzOvNxz$>(#nRPGIU^HfyJ;Ni@V;&-ir`Tj$HAvV2qUSBFp;96bc4 zOHoD6Gx!{f5jfS(DUc_y@WrdUI%T*BBmbrCTrdH5oWdz2bPpzXznmllEKA+G*}7th z1&gurF=IKPa^5#XZT`zBbScJMu3dTKT?(;?yLC;%AqJi!;}eX zdm`JX4X3K0e`9P^o8k)QWfyHlnZaav(S5jU9eXVPpaly69crX9(34aJD*M21=+ z%}T2J4~*g6STy~!4Exqc-8{G&Q+)q;LgY4cfiDNy;k z5at8s_v+Z|lT-`tYfLYOg>GDNL%23hYQaD^2s1UwM&}&=s)6OB)T}RRF=G)PJ>j@= zXB>PvaW_MwBvPNnOqqOBoJr^XVaT)Xi@>i#YC~Uf%k#Uft&H!j#4_8l56z%zI5B4} zDW`32p6j=#t_bEbVtsV}KntGf5CB`k!Y4Sm9U3+yn_{;S!8t^mV(vX>+d`d6lGaEl zWAa;D)^T9$s9lUl`d^KX8qI5QtqI>&A9Omdjj%$2tEi;l^5g<;d65R`?y3{rV~d(<+2TPe3T+(yV1( zRqfwdGB@*W;I;I|ZJDL_HS_W`-Apa=i&ak-%EpY|LmY~?oBJDdYPZ=jY{1@OKtn3M zLEw!-R%sNzhcur*i(6}go74w-Jhn(__L#p#2|Vw6flH?$kF3&k%tCz$Q&$#x7I{l@ zRF`0Kk5%*9K7yU=Wx6=77?7h|z!j>lwg@TupyUdV-m;_EcH4}}o;^;S(4JAhV)Qq$ zC<&l5%r?sAA8!4ik7Ji}^8Ji;b9rLq8G`m?Ky6Ll+t;>nzilaN)z#oa!yk^RS@22HBpbyX&D}fIitkImeUMNhf2DV%KCLO9@Rq;Q{ zuRGjBI?g_SK5$J;I5XAKYq5JYpJKk8rM(_v8C!HcaCwtvHYdiPb$u_t47Iq!L#ucR zTBX7*J9n~|ZwSBpJ4z!MrWx+!%t4m&e9Cuq*|*zUswEv50N)PwuPXj*U0NOCfPIMt zC-q`>ISe)Hox*-*6lian8)hN(d~qHAD+OnCpVpC=L*>4imUeDiay?Qxj_=9`6y|0d z;_gjYVH|M;PGGU6>@y7FM5i8su%sf-8p-vw;#9L2x3qGLEV7+%OuFRJ&7(6H&ucni zwr@@X=NE4wsU?eUwp`T=yyPb^T-xW<*gLcld{Ihr3^~!qKrs8_AspHt-0G%0!q>7q zcz|-j`CW2LP=B{0z!w>CmRrAcDNIzIdY35at>7Y2r}%yTM$cK(3Dv5Hggqk4=yi;5CAkU` ziPX-eaTV1lt4h!d3SKX%QhLph(EGvcfph5FA?p*7kD}fV`2YoZ_m*Wz=b+VgLOh03 z`sQYgTBq&(g@G#wUwcVt^vzcKITw3DI%(p?dG@pkSTwa@u`uY?QqN?~3l25t$&dD13e5(v03x2Vs)zxPC$a&W3b5|cL@9xkxJr?$u12HgvSPW~s zK8`z}uY)>Ys=05pn+a*oDyPROb9ID?F&W0`bH=zJZK1e`rz%e%S9l=g4IJ-oLl}*7 zG^g*>FW;vu3n=EVGK1r@G2b#ooifxTXZ6<6t?ss0$euZe?Fi356O(xTtH>U^QTcM` z_Wq3d?wQ;s&d=_M@&Ht?>7VH}>hu0){DemTe>-0P2@fJg$Qt|))+Rc+cN&~9c}5-{ zJUM&p3ueP^dOx`$QdrZuvhZkUWt%1BkMtF{42mTGBMiPLM2NfHv?nJ(;%4=@8|b>* zY`)6w{^8;82Fje`s&K6!66SDjnk2?Ft?IOa2}R507;84sB$aT9WCo;HcKxA3!&%^==_99+1w}qG&8uJL zrDe{Yk5I605|YNZM0NLl`U$QM`7v#MF+`9Qn0Q3$*!&XMC&y*7DO7^g%KwWoW_9+d z0KX_U^p!~2jMouu!Wki{SQtC~dv3)PaTQM4zQ~EKuZT9vYpPV1MU97r$3JL?G+0W=ll(%0`>W*-STAFt0@G(9M7OT(+*Wd{ zZ_<$tM|Cm@(|VX_*7$~Ce9cSr2!yD0?a;d>*e+Cw8Z+;hEqDJXPE~F5R6SjFj>}+AtJPRtU@fhpwRBz?^#3Yr8D7dBu78VHT=`KLfl633ZNq44i z2GQ|ZcH=Deev(;r@H~Y?m=~3AD0!@8GBY20Co|W-zE6k9f4d|`7yKp&N{DL6!r)TL z<(ArBWk_2<-Bw)eTvX{5|J9|!H?z1#gKg#)whU_XT&2K5R73z&XF(DPn+mE=EtQK0 zioZxUe-S4_4KcSUgc(w)AivX6X(1XzV5dI5tpPs5@do22ZuQz{tYs*DiZ> zsbNVSDRY9FWBfYPPOalHCl*36S9RINQKh|uP0qEgswr+d;Z#XOwLDh+s{R72Pt6jQ zjST3}MZxKyqJ01u;ZfrkM---HDo7w%MP~?=$URbBhb_PcJVq(k@OKhzm)yfkT?xtXLp z4C5oZ@ZJvw7yNt+4r!kJLgJsPtnQT;V}98A_C!$$R) z56Ps?!c`;Rjr`sB?}1w!{km7R7jfFG_L>{146e(l%TzR^Imvc{#28g`5I3gZYEz#0 zEYXUJAp?Mh^r90)(-9n718A9bzdX>UnYXN@A0so|RL$;)z2-2A3D<-nj<_+gzY7EU zU`zNc@C3tu!`a3&u+MfxDo;0RLJ1}Q+@Vc?@Xqb426>Z3Drr>8{vB5Sw?9pUWQ3Wu zBpKu%B5pk&9;_&pt3-+ zFwlOs7ky#KPC<&NBsYJgZb7s6tz+Wd{V$Xad_#2Y%70KcKZ{8bZ7tU&E>A0V|6cY( zzH%6vm@YxQ{~F{72WJUBF=q&dY(*L-iFEw@56Wg3WkvsgsvoE~tTfVaa_2NS9WX2R zW$NJlS-5VutW>U|D7f$ij-ZHTM|<^0l2r33Iem5E_Um;Wo{*7!qn1@c!h8DmIS3B) zIGBg$SZtb@Uv79^raE73*z-rrf8*)jXEI~J&OtDQ6AfO!YLE(IWZJ%pYB}7zka2v~ zDQaq+QfL65V_Aksk{KK%l%fEK0Ekr(7#HB4y|yMfzCQ+s5H*U_Q#xCE!PHki5Qw1O zeYZla%A2a;NKDDS74u%H6>=_T5zb$f<9S>et9Tv92XC2D=x$j64^B1EuzMGG_3BYr zQ6lb}Bxgcz-)|Pq)t6^F50mm_+tF&fORe8Y>#bqQY-q(}PB>`YbJD*&1~#HtP2E3A zeVJPkwwlu@_VFBTNRrbr$N_Z@QqI5SwQ_?^E_vn0duq5T;Xbj&sZM+PkX|`rhdt#P?O4#Fv~qwtnA7xX3Y2MH3C~;n!H@x z@++RVpcT%6JMqICIgJt+`a9fqb89I%HKE$Sn~%IRir`(tIjf34U=p~pd%O0=hNWfr zd6ZdtGZ;5-Qb>)`HO5=cA5k~*I|cSV@Zmd)!^J=JjuL0wq5kIyqcoVo#eYd(U2@ja z*Z-~aOZfnwc?HMcOmslDjoEAJ^KHtsX#1ht8!5YknWaXjw6EM#f|zx+XFtgiRCt7i)XZG&=tJ`8Lgg z#E?vPJ8>Rn)W}j1b;d9kSu;4{e0h-VXSqp?aB`R(H17!WeP&uzE-eanZ&C@1aHLTo zOL5+`)=59-SS{Ta!+lKaFAYiA;J`G6wmUR11_{5|SGAKk3eO+HXmoo>sXn!`l5Ky0 zPY8BJgAq$-;WoWiBGD031SS}?Pv)FCB17{4F4Oahwk{0|8=61Yp!yFZaphoek7%AJ zWmhW}C9TXb8E~`_vNJmA@dga)o((zYMQ%wLYu0hx=Xc)BN4Qr-o-`=gRjt%~$&oQ6 z`{baD@tJa2IAbh+OpQ5+Tt-u>qg-&P;W&y$Rxh(-M{5p4!SN4)E_+23S{yB>XYto`FkF zfl1Mp#J>{4E-{mQBv_M-9Wn==#QA>Lvd)8)}QEKTxVwH^HI9J`SI|y{q}dB z;eD`mU+1sYs=_+lD?lVPhsBWllZ(J<#FwcT`UiYY;Sb4dRgN} zL?#)sNXITf@4)cSU)1sCy7x z?dLwST#qc1RtI+fFX0y|6$X-1m%x32FPRnxQN&I2!{EXIYvx@>>9XfM9|VK=b`>oi{1j($GXX@ta}(D^3D6*n+N` z2>FC@<`0SRgcFugvfm<-M6SH}T92p+2G|tr@XTQtt-JVwR+Uy&Qnl2TG#D6AU~Ln! zE*slJP<4XA#1MfPytQ9|5+7^^_aA$1! z!U=8yfMIls*9l)w5PMK_!z@opVQ9E=FbgF~cP!^Ew8B9JPvI%AaY!O3VTRTfkk7QJ8I zK>vSTQBg}13WM2C23En@NR)${e$vtqFqon@=&o1Mp}Ll%A()n`NJZA|=BB6Mj(yut zf=gaq1?K_+gi91y0%v-2>^a>gU3AN9`MRt;hCFKRu(x!}k4W!eaJPaF$(#?=y5_10 z5V=_c5e-A_u>YCNv!YK->wu{xvdIc3H;5KY{)SaQwoCtF9?bl)rg~wy zH~yV_hS}bfpJ*;L_dXnzhPBaNa zRjq9!2Z(6L<2GHa%x2>dze==b(|wg^oqRy8*_8B8QL|ySm4-lS?tI}pg{|G9W!Y)Y z@>KZgue&DcAd5n=eiyUz;PW&(G0R__F60RwI+t_;=IRbZ0r6F#_c_J*?maQ&r9zH` zTp{(%QN49x#wDw<#v=9aV~lO}+xf?gnw(oX+i>CEKVj|Tcm%k@`?M*(b)no|z{CSC z^x7-M2=}006K(}}$UBI?5YxC|$9O_}r4BPdDbDB=Wp$I`h&TAiBD+8 zevGlN-;LX6>LA}i=;P+$`1v_LMb+_el!SJZxg#+WU%6F2z>VJIVQ#u}?vx9jwkfWe zW$plm@oWP*1{#Q{G6W9-l!cRSQF;J%^@zf-Q+(M13(|@s$g@KhDP9(|a(ZU|Co3AS zaLOjfPvaL#$KGqWE!&$OCJ-Xc?PxS@nFDRzjXClkgp7{#C;7bIE~%j+c9kB# z`#wwGzl}<|B$GYC%%IJ0wucseh4Tul!sT4|CrwDI(OI+$d;OdRrE5b(V~ha8Iqbsm zWWxBoDPC@BF$9!hcA*&~=!2qgV|$kO+T_)n7R|k=9~iM`8l&6!f^fW2gkzl~_l!<> z`cbCKZ@ySs5jyz4K0(fv;g-mWUT2ZXJ>HE_567X1BteVToa5Gt!-y{iVhO%#>4e!k zisxhlge&9OWtchA7~ctf%NNu)=>K_%H>WeeJd$%Z!I^+{xjq2|-hNR!HGzRw)Bs2o z;+KdQeqUIzqq*9PM zup&bQCtiRNK~SteP^+rp9|Go2%>$0^_`h-XA5A)x*|b(^3G56Z zKM45{M;lIfBf(3Fk-jBW5!R9p`EYCjydTV&Y1XzY7H)<1dgbYjaC^Pq^PX!JEexc7P2 zpuqeiY3kif-JjChlmbbr!f4Lg%H3mRJfWHmmP}~(89U%+YqIw{zNf@=5e^eig7pl^ zm@yS*sA&6y2M>tWX0M2YuQCUgOa(lotUSdWZl81!C9QF2C4$g180riPnY+3RgFk)C zs<0^fj(RGu`GVY8 z#E$FncJvv%%{0ZIFaDa?rF)Z zEIbhrQpIL%^{(3+%8vz!k8~N}Sihbf`m*1dvsK*F69D>)!L8(5?SjcnVFM!F0{&m- zWl>_?-hnBFJaqRP5r()>=rQPqOrz~_m^BevnN=y^z;)J7*b{>Q|LFw0eb#5taL@_B~!=yLK)o-4>D|huRg#_@{&`lyBQb#+GSGFlyI$XR-LT zvN*gcqq9pGnOS!s)KSNnL@@DVA(RK*?Yxl8xeZ)rT%81Bg<qU%Qai5eG%!;X;fx^ z2o;p|lb!6bP$MooH+h@! zom^yX)L`T?^!2muzA@wS8IB~h8f|x=_|r+6R4ek>aW{@GrA9&&;%mrUY1}; zj7k8ooxVSStdW^NNrX?C(?F7SaX{S>U_CSu&Nk^!VhAvumOro6Dg70E*US4wm0IcRN?$`xh-Ltt&iy&_2`s6Y!(%w$t-cnPNI5N%U zRi$ky`^vr_<{V((YE2IY9u$~i2UvS@k zs&Xa8R^DmzznX>qRozISC7ra{VhfI&n!`maow-EiwAs@DQwB0J2Y=E4pd~F>$I_d! zE4fX?ClJRkjq1aj;hv;$<;Ddua@PWQLy4AP*h>W8lfSbFqIWNpC_6C>?Tu8b;x-3o!E}pS`=W4W=nYk6HKEdQV%K|6vQ44OxGs z*&Au~FN3c}oHqr5fS8wTPX2PeeDwEHbGXqZI@utABNA*P6?FCt?1v$HHYY0*ZVTY; zmaJ*xbb+?}5;TL#tmIolfg%StnLE2{T%4F_+%>hV)Cf$l(QCm0u-<74BQ?7<^ex8N zAyoNl%pqSvhk1aS5P7v>=tb@z8aLVo%>`DdGsM^(B9QVl*b$mmSw)LbbBw`oj(O() zK{YZ=DO%2hB>seeK&3=*5R{tvNR$9?u*&Q#;j1z^3x6+1CFvIOe6r!z}AL}Vm$3plb zs`1MJssAC6Nu=6`5!o?hz;R3OXW7q0pWhjvE5QEBrog$|Lk6)ZACYLxd6~E@rPk!S7 zo(>W2I#(E+!q_F0()>s9nX&FmF9hpd-LCx>O1U8jF-&2G>#H@g{(%TBQF_G60=?jx zAi`vc<|EDkq+zv8)$H1fh#ekQ=$Dv1$ZBE+5=MgEM>kF*W9<#0(wXY0$S?$bPXpVs z8tGM7wSQ&Hr^NAs6!Yk<_#Uc*$^V6f4^;8@W(tBWdZU_gS;S5|tqST+m^_ikb z3D6B7z^S?RDipxJe-88Zp3X>Ta+I}?eLEth2>N~cq~X$~wGT8-yXfl;ZXYTj0I^p7|Jt;62ojat6*n@2iA}9?sor+qNETO( zKr$Ggf11_rpw>~qhGkl`xWXvIasL}QtLPd~rWDzkrUF)%h3kQQFXlWeV+m$%z~PO2 zT&j6SjyEgn0$d&mVllqxl+~n=$WV}9G#)tKTd%TDl@*m;ZvRB_Cf~+2JC?$ z2l1$t0b>!YL#C#LW)Q;>CYG9h53L(|$ewM2i3{drCLU+TKG+oValHO<9J~uW){Y3! z#X;?>M3>9X->MB^*W`359>$`}gW-&@mps(v5MJbfIG+ga~ZYr@e>>T zdx=z~drj?>>q1aG@~3(2fmV**=?w1bH&rXXE*y#KVwg{UcS0*t6+u~8ZXo^Y6(o3Lh&EIqcHs~}P4U25*2cz?s&;shdqecX3c;=bl5Jk7yDKj% zbuOA{Mp=8X+Rzb0ZBf1#RQQ6ps5k=0ldV1w8@e)n)i{6TqCs2u&C7T1PBAWg)u)7h zKHu_!hmaDxYpHE{R&XlxV#PH!w_3m>#d&riDK5yY-0IaOkh_$tf=;3+7}U5dFtKUXw{Xz2Qd zw^`AkgJ;xEy=&n{v6D|+WAKIjYk=L$lVm=hDu1^h9jR>{{YfqX&3WH-R23Oa6n|6X z@5)``h_lSp(E;j_+Yy}i;JqrKqFXpm*V7ueOeRIAf)4JeIBKpS!l8s_parclKB@vD z!-vQg(tQU(;WSu#U=3+NPm~InS&2`t2$krXz#SFoc+wN)FY@i}HE)~NLAxN=zdx0l z^0T)6C)J!p&e60AoJ8rR=m=#Y%|5I-Ud<>oeGPhlqnKacFgxnJaRfh3Ipimqx;$ z+O~x}sBTMd_*^0~wC2~hz$BKQ0v`$11KrLh3h0X&eiDlXbx>7>?mcSeq)Aog7DZpX z68ZDh(YphG)X7Q%*g_Q*xC;g1WGX;xKD#$phM7-go?Z}5dw$`U^^%ft>5|inj;f>x zPoJnh_@|IWOQZHuc-L3?1jcl_6txzon4CHoJt%4joEFv(!h*_-%C1Y3zSty)hoX)TSv@8@;yb0whc^!01_2FqX zOq*teh+N&c3!_KL9*k=AMm6Fra%~oBn^9KQQ|Gx?3#A$=L~SorH&(F9aN??LgOFE> zwtRgLT?aVzRL97t5Bv@vw0sh2l1GrB3`CzAJrRV^lAt~VJB{8nO*-7CszBT<5}MTT z6jPP8=u-ay)KZ3-CiXc~Zwge-Z!T^g7kO|&>uFuXjAg19g5UFx3Lr28wg(b`jG@+r zLygqH7=P0!K<`E|`PPH)+WdLe9`o~)?xA#jLErE-tBvjw;(=M$M?94R?Fib_Qze4w zk9CivRUl>rc1s;}eF*DoHSP3ocF);iy#O4SPw8Z7ALSmQRoY3>Z0x&D^3A zOu4K9js;bX$qj#g9u>ts7S`N+IV88R zL7y;_K&&`0=@D&09L*=52>Ry10T@h?!H03vL&MNVu9B(~<*l8IhI{VIZg!qy{_yJr zy0axEsd#d*t=%;B!51CGn@z+Uo`w?-l@LJox#RylkQ`jw>(K>v@Bl*CL?+B$1Xux} zFoK||$!{9itdGzF6Q}kCom$Rk5LK-ktLIgzi@A#p9^Em(GyEdR6^X0uy_R=P@fR!K zmo9Qz7R##z;~yHv&FYBm{K2MrCAjYerZHI4EC0<}8@z&6T&HeCumbRmd|W#~qZfRd zX+W$_#MTB17{!WB>`aDhM{0b{t`B|z`Gviom`SM3KV*%>$qjXeNwGSx$*tiRg7>JX z?dE@e5#;L^7ty-093695y{yMvTod37NHxtbS%WmnkvzVhl8+R|V(L^G09XVhcIMdXKM5XNwrrQjJ^ z^!7(%MFfLTzZhC8;_`U&bK*PGJ_#-CV1Kk#qno9g{d*YKr8eWS87Q*Apjm`P45Qx+ z^|Z;C(+Xrhe^MfrVdo}GaqW=hR_-bUCl$ug$=LI7d30PByr4<-c;T)9nzqlIwlW}K z3Z+fc)SOPt>n0_4bl|&Idpf|qrL1B!3i~?eH`6jFJYp|#ob<>qeIAKO-XqS5KKQQz z^a~+Efi2p1mcJ%ej*|+fi={Svv&!g7uxkU4ZK5p;+d}B)(-y?-u&$Qq!?J11ceg=v`zx{mx>lPu(6ns4dBGL7#d=Y*97zf`VY=DMF|5Pl`}h~QVW#aN zhqyj==ArP-vi3$!o8b0Wdu_SSt$0*h(0KMHy25Pm4qRLIEefRP{a4jE)i7rl&wRu# zk0y9vvr-!a69(Jg2|afl)<<=u(5VwGe1c9~h`K_<8>y@!n=-8cZ42luZwNWIyNiNY z@zh#lJ_5&?g;iV5)s0HOx02X64f)EptsBWz@grFWb%9KDJiZdE9!1ZHvIFh9M=r0W z&`Xwc$i>`_-#I(Zh6T92(dIGVqcO`JYZhmE45>7AFm4RPj zYgg*Y$Zfc_sCDs+C9q2*uh!+*K>&F*h%Jv!7d_rq-oWip7YDgn6(Oj{(jQ7Xhu69ZS@Fr0Zn&Df0dgA z-!7;1fu?c?(55V^XQlw4j)eVP|6p?)!r?Wz6M(h6TSY!$Y1i`!Zni*F;>^CchEo;t z39lAEcBt_jpO)pRb6xwd%`X^rY0!@rJhhpy2kVAC>xshZ8pPGtk7ydN|5JKL^rerJR-86Xqi=MeFDoW_d_Di zb%oF9pZL{eANHIAqa#K;6KD=r)8Yq<_SW-%_b`#Z{yZl zAM~A>0_EPaY}U(!0;fTay$c$P!8~7}frlM^rNvDH1YKXE@`9iASB46;Ntv?STt(9^ zf58g`(5avHYdAiD_z{)5)aoSuZgk0N@FMf}gE)7EA@Jle##4VbWHc3Owm#rw8tV4< zUjzO1CGbF5TRq>jom0pZwUqoaKziRTX4y9;U%;}m^`--rMtvDDAE5;gRh{xBBh_&> zDoRHemPb}6$_V$t*l7FBXlnIVl+tRDBlfH#KuQ}v?Ay)sP;26hQ?AcuSHAzcaNI{j=C zZ%A$IEnLZd>(r-8%~kqI%U&iil&=c2kfGv)PqUd>gWl?&QZH@=3GWHemt7np!&>nu zz&_9c@2J;;AdpM}vv{RZ<}QNi{6kDwOYgXk%2O^CnY1#61zU~kVcGQ5rb5_2=KjGA z(VkB)>_WXK()}!*JJmSQ?~BHK?TS^eR+_R+1>X7!ScaSnws-q>8KkXzc`UGnIpiCQ z+u?|S<}=4=jCV@wT=lKoN+fSbnBR{DFg?_&y?fwU5*B9vAlga(DXM*^Pqs#|&tr>- z=RQ7LjkBLK9r$K6Gnh|h6<7I>u)P=M!@d6!kIIets3qXv->#)y$+wr}4=Og{6PLj0 z<3smJG)G$Io*CxwRE60a*2ET3tfSOUBYHU=j=A8y9Vr&a+J&x4bq+jK>}hvf0HWg! zC@OTXqWhBV>!>k%MYx?}tVKuBA?vKA)1T><{@4ZpszK^rcJa+;i9PfxyvsILowd`6uK)r0G>T*jqsGqJ#@>PAt1TgWizGeYuL?@X0>3VC}#LAN-Qc<=`x_&kQ;M z3ikekWy?@Vk_&P8r}AR6CeTN0pj3sp&P|WmyfEWAdtt zu^c9&ru6|B?N{RQU%GE5AqCALzi~RMaL`k;7SFR<|LjS}*1aN%=3{&^(-RFbIvP2F zdnh@qoJ~6uQ_&tm6T>D!n(WOs!3I};|B0( zQ~?N}(eD_$1f1*Q{k~{o(7&*|_bE&h_v`Ih5%z_*n0sDgfNnH}WR9iLfSlwdd(8Q}^h$uEd z?7CMxrmr6o@Q$IeurJN6I}V?oFK#wthM1IJNO) zSQP4{QUIM7hOAmXf8VeF&hEoh8=FaD0|7a)ryK1;-~j$JgZ~%H(uVQWHOu_^ayd>L zmtv4wB+VtwWtZZ~l*)R@W0#ZOWVI`iVxXcs1Ir+%m~KhVWMq+oAy%yQq$|)ZiO{9S z4uP&##qHIe zI;s$%aam=F53~B=o?O!$K=~;u>NBFl0QBc^@H&MPcH4<`T8`szW$;=zw+uBV-cp1h z3DEDxMULdF<|>lRp{Zr_&m~VA_wpL($IuQ&MOn!$JL^{nd2=8`W9c*K3D z)l}r7CVtZe<$&~iru#Dz^>6f399#b_)`mn*oLp3HVF`6t7M%P0&;&Z~KCL2J1DN2A z#jZedhlGbaOXOdv>~YUdMvob+vGH__$9Gxu)h?Mg)+Qd?o;7U)8yxIJEzgzPE}3W6 zhId1mzZQixpF|(mv~ypCwsumk7N_xgPq~Ck0NxF@*A}bJZ4obK*QTi;9mMl4X6i9o ztST&QfbZEB>DSavkAk9pk~1AU0CZU9ieIe5+4VG@BBB5YRC*Kam~SO{^0mZrvEAmy z_fQCSP%QN6cW2yR`sKT~Wp#3vYUkBEDN93I)~MZUIA0#Z2lkhsBG280dRZwt>PZ&L z3AQ+M*4Fy4dp9u*d>S+eq(h33IP8j*(T&2zd8{x*=Mdn*)$ z?}b9!MSDe)pwrqYF;jA$KEeA99+cdFs~^Qlb_|EA5#Y({Zo-gc?Kk9n){1>*f8{-R z=@t72nJx9i0Q>X~v6js9Z^VzmG~$Q7yWT_##S(Y#A}vA`lXPZ({Cqn?J?y!yGfZ#v zfUwChgbQ!Ph>|kZa}_KG1c!{d#xz7TW$@omzq55lRsKeVTln_8wT`VTv}xo+jl5u* zq3MmwMZQCT&dNnf+HdIPz|=?E>FFPOQZxoq z_@C@K3pXBD&nw~;6{%48_Jh+~NHTxrJW{9rT*<@AjG-~m8XO>uSaBEP`^<4ZHVEAw zZ>|)s`*tq1lLPg6xW^)25H#RPvU~?Mniv6I+RK?MBbqdC{&(CaZzvw)1rYHo2HnDKC#y_v@qn)cGBl-aSq=k42UTlNpj(sHz7$&J+1e#k|6N>j##Z5o=q{ zgOdFC$pW2(lcKTj+2jd=zNJ%*2Vl{C=2ax7dj*K{I0KspS2WK=Fic;pK*A+uI`;-D;@l?*=2BB=Hr*wYz%nlw*zDW}GO8m}GqL|5*EoHRM z3cV;ZM|>u@Nrp0LjLLS*a-FE%n-ld~LilcUqiq_^Nr z*9~ysOHoM`4?RpOCyRc%xOB>>VSOk_xzPaCg~C}30YT(Jgu1P@*uJT=Xb{Z&69Yc5 zM;hLejX_a3hdv-HTB4drm>Gf%@rBO{QtvL`N+U!1kWH~E5>|y?@NP_*YajhxjG}tj zEZ-77;LZNa1PAhWhz3gYkS*pTP(2j&;}KvB+9%pt=@8Y0l_`C&m~xcf-gR*P_l%AW z+x`jo4A;=VK_va^MNz)|*5~l>LlFA;0P&8QN#&{4A>c+tr6z`nQp*_u(~)CgDKxt7E;bLjakXFM^nqVlmIMJ=-9!M? z`B-q*>UlW~`-r04b@Z6f7YCR55vJ${UIkIXfd>5b$<#IUG!;>)GS5nPJa)kvvCLUe zh(Ls6?!W`hA`(9>&n~T%|gcpj@I>S8;R(MCaigc3>mOY9>G8B z(N%5fv(UDvBtInyY$jP9l*pYqvxI7S?YKhiLVQe!S2zwXlPJsmoE}a6LMDLDrMGaB zo-HSqx)F%5_xJS~V)NVS3jZmN zfsl#O<%Oy7QAEC81BD0R$0is1W<>)QM7YN$u-L}-0gql_;I+iEXYnIJ^=ubgJtiWY zW`eHGhr*1wr_5Sqb9u5&;adQrt~*-0lMpz=j8HOv9{(V!;tBg%qkitbJA7##wckmt z=M9GI`BwAaVYir&k)@iUXGZpuDmhM47K)SRJ;;X4tlWimtYln$IqYxnH3G(aC#Mc@`)!@uGJ(6eyD=D}*Otdd^|H%*>H3OGG_{KG=)fbGZ4_ul>T~ z$VBJ5;2d}tTR{5$0BIw5vJJTNSgKIdlZipZ! z25f9tlt(QHPz5a!p%{QJ)Rev?@{VQS{68ltM<`jmr`)yHO)^H0-=R5E+94W*5!}Q` zeB|YzeAlR>N?+eZB{>H|FW0Z_1L-l-tT3N>LHe`73I{fH2Y@@NK?|CdtG|Rq>Ie0y z&IC$<-=I+6sLzLS663FEw3G+HzVgIq`Dmua(ztn4>iZ1SoP+@NXtoz~V>9x`N5Tp=|D;svf8r||73K5Rv}HI%CGs7PK?>^YH4M-952*?H-bW7DgJ_k`Edd; z3M=cZbyr;CDu`yUzh&TA;<2pR#}2Ps`j^b3uYO!AU%68&Ci zWBG@awFQ%%vaCP|iFFv4I?xe1W*wRhjTOIM!0hsplwC{Y%7VIedXZ0{5tw$Xn{kim zJ+Vw=bcM1jP~)=}`avp8W7Dr$mT`V@FyHud=cG|6{s#d2E+_TkPEk;MflIk)T{Qf! z;8^e*V`&G#v$vQ#eE6|5cNl?_u?0m_;lN!(eww*66qRg_M4{FjKuCKQ+iY6s1@`XYk;;yB}x z9ZdmkickQz!Nax%V9VbjZNGZ1TEghT<#|q(H{{-L>?7z?JzIg-$yy|Bk+YGIVJf7E zPfSZ`|I%aVh;kshEbup?y`w7jVXBr1hQWoQ#453IVevR665j+0mNlaS`A?KE*|wDK zFh%(aS$19zBj&79W3s57Qj8B*1Q0b6w(;9sV@c6t&ZdeB@nRna{h%Dd6f`5 z*tiU6lBiAuDXC*ut}5GqHHKLbGaqn%QA@5btkqHOz~9(PC~O>@Q2rbv0T12YoAQBk zyC%9~wY#{@DTvND?ct3@Fke5UWbMo?TfoB_FJ4M&Q}vFL)H0{mH2PrI;)4a_jILqS zVw2qTu}#k{$&-MC)uG`Xg%zc_;~;?)AJqpun+z6*^?6otScvdM&At{-9?)e?5dIS_V=ZxDTkIG# z2;EABdn5^Xn}?OeMaKw-<#;Js3*BR}gv%~?*F4#*++)4Ers{qG12*>1781 z;(bG|)vQP`Ge4L@PN*>Voj^xWC=5OGX;PMT8y@SF9I zE$WzexW&j;sINv{HS-PAlU7L8i^SMruk^mxKB}_2;e@kE@&2$!`Cxwq3fO<@*S0VcNeU>FKMYz7NP$tgBR4YfGtm39}J@rk~U2LGhx`DYb>-Uj7By}K zjC>V3Ju8X3H6k`0I#`RYY>}EVb1hP+^1c`%9fDk3;jyu4t6$lG4PEGJ7WBP}LD={D zZW*uAj5fLu6JKfGPZ4UKTjho|rsvJVjq33~7sGPRJ=bEFy8+0Q66x%+z4Bz~ya-7T+O{&}tu zwAjv6hjJQbqOJq^E$0r1#G}$JdXr|~MGx_y+1NyXXv5IVG{RnZ0s7sTYN3TZRTQkN zRSF7L(miOWAQ{0io^Zsak|t6{yBtUw+b!X=0o1R}>5il8o(mw8mkQ%tPUBoQrpsd< z8dr!WdD1F7V~1HMjjN+^ph#DnV?O8AHpIZ*12)VV@lP7IUhuqxDfq{xp1TWa$5jBW z*h%2=P_dky{18|ZMAbIXi(zKE103xhsFnspiXn#Fw?g^_foNe7>vdgFS$?J%e}ei( z$t^_SwQ#zA-3Uk%u%>N>Sjp|UbdpHFJUlleIN_2a5Mj_LU-3Dgaa0)vi_d3Bc6j$3 z=N+4t`20PyG{(cj*m@~y(ulJ?Kz1`iNQde-hUrr&b6H*hS!~gR`{_DW<({yyz-(@X zm8@SfC#+5NF2J^YfhKP;9jaxKFrXHhviYw+hAjzX5eYyV41$%>NoQ{#ovp(SWzxx@ z)<2hy{peD*p=?iDbk_7W#%szT5Xa5R{nT|SOkD@uh(P$P3rElc&F?*CTnm(huSF%e zglt@P*(BOIsXW9=;-CwL2&>fV5Y;pzS+blaN){&Syll@R`gTR>iKlo6ubP zLTWvXv;>H{Ai9P_JcVqUlxq>(lBGL9-vgjrdMq_*;HPF=zp$WcTTr#olR!s}jV~8+ zs)3Z6Lw}pwSi7gLJHA3YIPwZf$8*X1R&|Z4uWp+>-yBN4$znVk{&cZwR?r?{WA4v| z%;+K<$whp>hE2cII(VTac^B1$4SJWAMD0frP66;+44)ivQZO*{f;%_uK3!VZ?EClgR`W_ou`0kjbBDuw{; z%Y2}Bif^bV15b~qciE@sW5aK~1_=(Dx#=i^50p!Z-CVyR)9+#2O91qf0LXiO@F&9# z3&1B7V9Bvgzz(scZE{yZ-#ts8%LK&nKymg($~UIJHjW~Nhd^qjWbTNB!ayA4AB+8p z^ZP)?aX5Y7wy#xGnoHNc6n`K~jm|gWK7tMAG5e@u%iyJzlnuUdnynF-;~Rzo;M>_ zn?VKXwjL-oLiQDh?Tmi4$@9l51~^K15;awwhJB-Ety02ij=ttf=}vNV=QGN@72s4o zU#?5P86f_*A;b32nrUjp?EY9BPMYmLn4FV-PEvC*CLi~oVK&evb`y_R%RyJpA01zT zvN0dr127UPfy7DEcpP$`dwX(~xhBfel=_q&ie$djNmGOGK9+Slk6w&qs#L`Rm<)5J zLS?b$RO>1=YeQxNS#_A?SED8%S%5l3@~dGJ_(G#cU(??AsHyQ9^EwgB)l$FauBLzo zw%c4IG@Qypb4rh~%5ax%}Qc62H)dJdL@c2%F8zV;iLG!;-NC{F2Y}Lsq{_;I zt8Y5ZS=gF*DY|2787B0H%^ETY-hx(BWdx`F48U@`fNkoGVdGst_(XtJ@C>P^?vCK`O2sXphXlMrk@LWA9t@!0;pK}Vn*Zvr{r)*xA z3KsB6^;z=O#9%?QuG7L%!@^NZ+h&hKG3c-#;TyWc>OXr8ZS|;D0ek~_Con3du}Z;@ z__eEiBhzS}b&CC{q!-A~Ak`?9Hw)np*KCIugm3*Hs(?jCcpvIiYIp=HRQ5_vLRBH~ zY71vb%DAKH*v>(YR>{tW6}r2KXUots2L*5`4Mbjeh3$`&D3eNzk3iKZDUgKY=Y5Y* z>6GPlq*1k{RZS@y0c%y|(Zg&9+OO4$CSl0TbC<^W`rW3(pY)lXOjX((v76q|2FFhe z8N-0d3xajPXNd17+{+Y)Rn?tqSoI7x;9pz`sCjSgDI+Mv(Vk-63496 zOZ$|QKj##Nk1Qb%_gJr{ZEneD8IHBI{FMBr%sa;VW%2@YfI9q@bI_h9qCdDy9bot~ z(ESEPDFy{r6VX^P%I*Hx;8}yb!iT%TuAx$Z%GY3F{BODy5yFzSbPmD(wr*y!EQ>T1h^Mt15cZ*`*@coCAwUX!E{K zJ-_>>j=@Tf^GmJd`{`uJmVVDuH-&R9ANmA#4&V}h8lZuR8CNk)c*V$o{e<_ZqB@g} z0dG%(!Z9>b;w6`)?VZuUFM0L)#+izR;8f&;orEMuCyCt`e$k4?LqBkkoRjwyP4;+T z^1$L5gec3cfm-J?ljoVK#(Td5gPbx1v-#RMI%4v$+=02)%GLq86O9G=mjG{Vn$mP< z2{kk(8Yh)+(?2gTc9;^i6ux3?ut_3PKrrRBqDg~1?_p9E>j@cJGx{OgG0c*=X_u;y z)g`Uoc2}uQjLBR6E0wE8*WnA*$Xk}L*5{io+0)Q%q(&8)7t-Fq?pdyw3$( z&y6Cd@v(x`5R%rU8A3%fv%FpPCTeHsqG;#ZU#_7PFMN3b{_YbKeRx&C#3)N?{!2OD z!b7I+dd*OqY@GPp|94sPJbls6D2IX=54!f!`?zK;noyTcq^+GqSnqSJ&8Z@e*@!&r zng7G)n5VRYPsfwhaBuPD!%qA*zw`@$FfK4f!JVj(LPwr4{7(zrpkF_&q+|P2H|x+B zcMp97be2CLX_!Idd$X}^4@4`&!pjJkCE1$;O^gTz0dHVLpqW@TcbMG61TO@pz16$1_NU2l&69#hN=!6FA4HN#3?H>Y9D%J##gT6AKZUF{VlH zy%oV859qguVUH6@i#SwSHkO6XMO#KY?yj(l8T$k9O=yk>Ia{t-Wcy|~i`R{R@b8@k z4*xy2kIqww=|tF&Y(FfQn03E8C@5+x-NuS{djuf|2fA-XrI5bv1{5uAm#K%$pZvpU z27b!{vUyMxw%eqa^dFVW=6C77k;hEVPsg1ZkD1G_uXihgKP0jeh=Phjl46*2u-g}L zdPj9Onlc?(*JoVQcjU2E9IA$vw`p)5lnO$nLpwq8?p!$T`d*o z?A)sCP|6XP4pLBGK@mhxO7ld!ZrDudf>5d1Y~fH5WLHHI0f_2DnEeVD7&v-GCn-IY zUpkgEpt3BN6RM(=MtB_!O~Wa+LhleR-Hvb!Xn~p;le~SHLu$j2dKDklu%#Xu6(}$}IUp6Y*IGELK-Hzje;8iyg%8;z~!S#FEK8pTmbv z<-k(rUJj2@mBt`jx7e=cQs=XSHlOEPfT2HHPE=*JjpZHfH0h}@#Zjm-V5~#HDSXsF zLvk6l&p566Sa;=#w*6)?I|gL{u!wsV~dn#Uj*F|CLt}L6ltGbl|WS_ftE0HoqWo! z<=?^O21$^*iqw7}>0KNbO!`U>jA#GxP~3=xOIkR2ja zUj+)G$X(*%FWiO18z+LX8HmmiP1_t&zK1}Uq=-1?E=jzl^*`$ZAt+By1C$dLNN?j& zZm98AaPtU;uqX>CqolP?fVza97!&AAg8yCu*Tuws1HaN0@gRi(VKVe!qGT%YLLCk{ zYF)!?mL9=FeLwnOB#1yj{y<=UK*lyGG?>oa_2pDHhlBY2=4}$KB$T zvBXP%2$Uj+%HCEU?qMoy(vih#O{>top4FEx@#mklArqr+YMh(s!I+7{0ogak`pLon z=sFIqkBQu4p}AHwSKk`1^3Js0rfeu9BFDe;b8roEJ~jb*QqG*z=G>|AsmZu>CEHGl z_76&V=AkHGsvCpG*!$evTbKyzA57bQ6TkDGN*fiRP56xHAMMFw62W!4Mc5E$0Hc!Sp>XA`se0eqqXR@E@GkYLAbIDAJWva7iJV?S%aVJeV%cnay5p_B6NSS&qHz%xD`y5Ds0i^Ly`8C z%=IgVT%V!bT&kk3RltYQD#j#0}NAh{Swbw^u^x$ z)%oGGRS;bY^}RU0bD@cT?52+?ktyYu5ml4`_T-t2O{fdjs_mZb*{}YhH|iGWzJ}fC zK=Nhy0>=6R{x5mZ_P%`va}JSX?RrXStzYhsmJR(ZiA1(b+C}Dl;K&}!DGj?2zrHav zo(khAZH7DEF?;iLEzj?Z8NRK<=8?%CDo)Q7C0^ISS^DJ_?!W&%rjd^w1wVJ#HbMWt zqZMR24=JPuz%yu_)HouWk(P9>pRon+r43SKREL4>_utYiihQoNsZ=cPzhNlH0}Vp&A{o^Xwmf2^rY z9s5Q5LVuZJfp3DEoI($!^^sW9Nst)OSnfunhozVp1H!xH5(gN?Wp&#e!HQx1MyZe_ zYN7-Bmj+4^V6}{wW+|zoyq5>qbjukF@1;&3s5D_YXt##wn0<`Xm9fY2PaKN=B+NgR zxo#=TMFq&@3&;Q6d}?YCUh?V_>i52gqd?Eru_5*xT-9wdJ@1{~M#JYk=VHdT7K9zV zO6YJ71%S_4W2^P_4~pfoE;mig_0V>FIt4mNw0xwPsq0m(+#d%9k?@i%cdC-!VGh#>+ z8vc}Q>nQ!*lY@#On8lfHK|~5POVc1fYyJ5QKqa(Gk9y{ssOrvdE#~s_Yla6iMwr%_C*tTukwmPxJg+&)A(+&kZ7SL=3z>n4Jk}x0U$E#eVeO&UppV^jJ%!P89N;%Z zM5`>_qG%nHs(5`??P9=b9Ue$-@F9GYR#hY2`djLc{kd(AS78Sy*#4*wK*qU-*!l)Tz4MYEV76bl>%Lpl8sE6m{KYH;BD)FK5O`<^aqs+<_fT@g z`=qxDl@n?67bH9-OL;4f8DCvVWPw<`&?TAjxq$y&d(h}CreL5zK&asVtvy5vNJL<4f=T%gU@5R)1*(;^J*Oe`dWdi~a=>%VtY;{{oWrD>c|= zu;9%hDZWOfCW@f&B#X*`sM|-VsvELaBmjz|WUxqBC-I78CE-4N?PIf<9Q7yC($WLM z(*RAfiB%;A8lRe$_JJ$#IlYkO09BTW$Pn9z&Qg_OS}bCU{1I^quwM^QsnyfWU|k@* zaz%y^zBGqwOzP@b87I1hZH(3`-Kgtbs*RB!F;w&&q1>eFg0$w;!wqB&f1TX7sL$Gh zH(&)rLo#-%Qp$fr)z<9dx^H%-97x4Mw*s6^2OZl2`Lwdsw2W9$kzsz#u3csm-4tb` z<39$+Lku!VI-{PHHd3&*A*4iHlf*?_6;h$8y*N@oA(!gMsrH+`+2&zV+Q$>M2fCmJ z(_jJ@9j3a4RJI)(njhjpmOS@8&;I*>oaYWNTJhx}4N;8pyzAXfv}yI#6oR}oC<4Hv zMw;*tWpMVb*<4~>ub^QN3+Eu>QJcCmx@Bc-zMrl)1zsQAojO_l>QC#0VI`M%Cp`nU zqD^{HNJ6ks;VV%87vy)uJd*r7O}S^^{~j*oUKc&N0)^jZhOLH#8fI&RLlU}Mo>4FX zA+cyF?`wnu$1($%t}y#WOM$RcepMd4U*Zuc@Ovab9Ep-YY*IeGvG&?CO__VD+>=xF zEf!@?b2BM&Hkj(Ls03zVK6bo*{^9>v=BwpKj9h-6O0%Eal_b?Mx(#xx- zho27^*O)yLbKjDbmNcFim0+MRUh(ja{i#QxVEcZl{Gx0ky>>ucNNTG?@hGltJ7>V= zFiwyyIx84UBj`gQN@NQ~rt=aGP*kXKIQFFLDio$}t;^e&73_J)`2$ZJYSomS6cG z$(Ua&O)2aAPggoHt`j;WpJYaN%T)FY{}c%_Jtk^V6tSE|DrkvHsbo48V7P#yNV>*i z*`#<}Y5rQhPuNW=R`ddN`0zF^1F!eQG>RtHIwkL*)9^Av_>O1k4T#e0Vg;lg=3}N}r0mu}yhY>|-tsi6@wTYh0`#(Z^ zTbA!D^^yj%2(U=5cbh2Ik;(&srdXdhzA`Lk^ng-t^8Hb>wUXYgDL6cNFz(?NOvt<0 zHZ9F3c;vL;z?PHN%a?++iivZdnEHrJO*SZP3ZW~M2qudsRq8b@Lk_RyTW@3I=gs78 znnmSxFy6zV2bD3;7@|UxNX1?jPy$JPE(=F-7i{sO1XvQCcQs!ioboQkW{I`}^L)ZlLbdSdVw#s@|ujSLM!T{L!ya@HO zInrS2v|*$u59@ct9IP;6 z8bo!GY9C$Bl$~+KeDH>^OK@IFQ+oK0K?sg;cfAQ^vJ9>P+aOls?NT86yIAvI4yofK32U&C&PY}8%r)#~*=&&1@g3EY z0609#+d#*9TXSEj^1-}l+(HNw_QoqU*!u1c%m~>qpj)vZJ0ulmxyz;Bj|*n&6YsU? zsIcx)jkU>VHo1S~B6C~j)YPm)1-Z|#hg8ix+(V4XklpSMo}cf!-akJ+o9mQ3%(-ub ziblx|e9Cj(=G1;a$<~?2=Xz{A%%!G`XH9 zr#dPo3alx893DRvAh(7;mf4_@#c^b`?VLM5tgjkh8y^0pv48+_`+-BH&&_;|{nzcP9b~QNw=o3-KVAtvIiOb%fx(k^ zd1Z740s9d#G#{Sk{(%I7S1ML86p3bv6A|$w7N$ZQMVee$Gv-o37-BC+ig+?;sz3h{ zn0D&m{v}9|AU}41;%)jeLxgrv6hL~ZqCzh;LvdD?n!|Kz$wh9V)bA~5`r5D03|ps+m@&$z*O` z8soRtJn3{{4=g+SULZ{Co-~0knxlzt@}CV7qCvOm=TK=FzC)c?*Fe1j`#-+?Ck34J zf~QL590;Gmf;;)*E9;x)hh(-Q3Gz7gT`J}1;X!Y zAMN$tf(3gIRkSqQ+Ht!4-Mu)*i9gr#R@MYvG=`Vy0e;4__Gj)N za2r!}u2qeXSJZ;gU%vyt1ndpnBRUhQJJB|RvNbQ+jRULEiWWAqM!q0hon=Ms;yr=C zXo84X;D2<8%bj0XE&y4fSTFzlqoMv3C5(GCl*51UCY1DxBhab8!octwe^{eI_ zX~Mz1iyvzezSRG$p&n)AzJ8~TWq?LttdV@_7j`1ozGS1bheK=nHugq#pOmP01$)XW zy7cHjO**dzP=KR|`E=VJm}vEvs)E4>k`Yb|+^{SsL3rB~+6Txr<2D6@2nezh)cN0$ zxH)5CCDK|8VUBjd;ZeM0hW16H^0K9jl=2|=Rs`Z94R*xvf`R&3OFzxBM1Fg}Kp*L} zuljg@6_|TFEQCI*F;5I(aLGZJlCNUDO{jPygo17O1t9Y1z+a~q9Th?1BAM|H^ghyt z`pSSPo2d2L#BnateUO+b#=%(NXu9}R?S5Wl#PIyhQgyYONOVpB{!&~de_QOkh*EBb zJ~3NKFXJ>f>A0Zn564xV(UjG1noSYs8=#GLNx45hN-g2T^@2Z~1x=Lb_S~(%WPdkI zHDHIBZUM!PW<7X>c=E&;&blE{zV}tYt`_Y05TPg^vls;ZHwF+MSl%ItPECy&%|!-3OY>@CNjDVVPQOtnXxhET@g>GbjtyP!J{f&uc z+E!(q@F#D&y5o;^Yal z2Ef_stQa$Q-1(#oHG1sZu<^dI-W^A36#`7f%ufaqXTrKQ^<0&6fNQ;;2&x3{wToW! z9B~J}FU8yDTa1d;&8@;kkm-2=LMuKdlWxm*IFeAj28uLkhreB=ybst`0v9GybUp|6 zwF-3-)(}MHf*z(+u`uY}7clb`3IQl}HlQ3acY_p3$Tz>;s74-F)UIDPER-ILneUFJ zibBYiXb*)z{4xLJE?mA3ZHP&aE2fn_MC8;g_mzd6j>v3>Tu2C;&a&jlg)B0pDOjB+ z6#qh(=oBp%g~j*>QpEcoNKs(9;rZ?EH*^N^O^IT37eqO_dNcx?WSChG#zPq#V9*K4 z3ybL3xEO)Aw9i%UkR^PK^Zq%jBtiKw_O#T($)w?1TE#P>!tp`$n=0cgpr{_GcR|pf z66_~*jt}Kwk9Kpq1fl{1=5C~}ECSt;s%FYDaX$@6Jf&?r*;s%Pw(Z_p?c>;g$LF*a z2p2=jZwXy?IQ9k|7_L8S*c9Cypcq^0+1At5$Xe)k)8AqR$eexX;W?otK(R<1 zVhfmY7PivWAi_eojXYovfZbjZ95k@(I%AA3D`vt~A*Az=;8u{l%5uCFdde{?@w!g% zZauj**_MXPq8k{`(d`=rwjlt+p9Y#PBeb~<75eP~bTzkTrRP+_$wTDe7%J9?I=%_v z*B?YtOJ4CYlUsxV%W6TZPdat6`fcJb`RT$%@+~1dOQ_>Nvp_>D0BHYHRe?uEwDdSn zgruv`>|eX!j(v`JYVSveyFyrgT�aP+*;a0SIEE8bs@#mBd(gjJjzh0@lRs0A(mX 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 z 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

35v&?R%|AV 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®*daJttr>#r(xVM|O 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.z5=DMLeeLHNeOQR?+WQrz<{FnLqp9S(|U?1Rki-Ys8Zv#+15 zB8Sv~^<`xGKQ-dHvb7?mB$+a!e&VfWvT$J_+9Q!G7IFhROJan{tLB;_+FsQqPYw0- zLCEE4YbIu$R5~qDlnD!Hb7bLpIYVoEQX?Om`9;j%RgGe+ zdXXKToHQBu1{ZOUjo1%~7gb=HVrFIH#Cel!l%y~~?IxP7Q7zY+uWFH(mKl}I2$29PbNbAFpAD7A7}DVtH82hUM7%6 zfy!fxRDrFIn;a&IWVvDuy~A{=Xfo#%M znFu7@C0>U5f%ZMg(+25Wty%AvB(1j-tRBVLKuU~xko+&ovoNetQsosu*id#7l{Jt% zlkavr;q=AofmmdeJ?vO;(`*`;ky!LY`E?o*EHo`F`GUNXa4U^=rdUGvt|NYx$-*vh z%&rBfJN8{>1mh|)afIG?4h}DiY3(ar+#0i+Tb;RN(y3aV?wneM21CAIm}wPW3CJCv zxq>niF@A|!Q(AX?_77= zBu@*NSW`l`L@*-xPRE$02D58mXVx52oba6}m1udmiHYUXO365~!1Lr5+BI_Gc0NGI zN#Bje#4R9P+PM)=1bMg>%@;(FB(DO1s_4Z?|DqX|O)saVm?gBib z0pA6@F|WtnOC6v*zY92GHYb3E!cV2F?3spQwxx)0cqj;pLKF&^(dEAdy;@0H*)kSr z+WMPgG!g;ptLR_D2}nz{_(SsyqdNH<_Hho*lzu^J*GJ8+dKalFNvB+z&>iYxS#{>` z!buO=I^pWa_<0kLN%ns*bdb0LK9}BbO@f9(1mfayj6Xl**t1{hN3f85A0gczbtRu0Jnmu2u)T{UbrK@45;Kn9 zARRiDif&x%b=%$AZbIBY*C&gq3X`n^+K!Bz^^B^crP-xALEBdq3Bteysxby>t)G;$ zu1disnK|X?=9`~rYHbujd6FD8VKot6`M=Nd?T>Qr=aa?qU8H8taLm_w3~a`72ObJL zrAqZ->xyhLerLCw*0vv(Cf9#OcpM#^TJwSeZ{=CmdfSclfTaLZF7)z&OB=FGB+M1R zxQ4o1jVY@&2zK2WbqewW!UoV9hE?nu8in|waF2HO*k8Igt9L-&jqq%WKHvzxUk}0E zeLBy0M*F!q=;N$OksdGI;gAHN@VuY4@s;7GybzcQ>{NW8#bK0lE1uQdpp*m{mA>vT zliw|*LmR&Jn#8d>BR@5}_#7JPryv}chRSrI#p;48BJjfEt7H)g#6&T07@|e4nLyi5 z9&xUK=JhoGNg>Z0h3T|RL#siK=+<_mXWtQBL21$}F@wk>%)qVeHZ`+Ggx>Ul;WR4p z$qJH`JHs=^9;+!TQlC#2y~cCNx$>z@vtxkx0VOtVy@2(ZmWaMH zMDo&5h2<^8_Qp`JFqgAknVr^j_E_&BMHn@IZdM0D93|8gBr=L`2g;AGi-+w@d zPahR_DT+0jeDxz~=?bJY=3ZsY>BH86*}ar}u+*FN!J{w~19muVX51!Mky#dziN4KL zq(AxqEXtp;ABUh3#x%lX=Lx%bd>{_crUuC|Aq3Tbg!tJ)WyL^5b=C)IskQ1pe~UTW z8H&Bi)#sMf=bs;OJ96I%z-qdNhh!|1)>4~Rt=0YEsf-)=vb~eq3wIz=vM}gz>DZj8 zz-sVYgTB4F28j)=-1mP;?#tbFR&p*uE4w@HoyR1+zg!(SNEVkdsKmz zL*bu4s?>z`1AwV$XDuChizLbH9(MExfc;Jrgx9yJyR~F-&YDiPio*4UH3*XRvr{CX(pg-kDzOeRnysII70EWH{ zHa-LCn~uxPu4<$2=?9AU_HdjpX_h1)A^no@0*_HeUNg|T)(=;upuadSE#j*}Jo-^m z1VllykMEvMYu`hzUJmj)CmUl@i_6=F=e-$kb5F1*+)PVJ)H0Vvkvo_1+0O|#6oy~a zx)H&?-ns>K<;pP1pJ)}0#!6DmO&*&*(a!@zx%w|D)I1dUdDfYi8#4JmSbn}3{5dq{~3jttmQvFfL3F!$x zuMoKZjK@CPh$|&abwN+B-R<(!Kuff~l7H(O+NA!|_9$C?L|4iQj|uu`m#rVXBAd~HZ^W}f2IZSXiXPe!mSi0>0G2$np2 zXJA=n1IDxW8giRuY|we{X2~%;&mw?~;w9h(8`a`HXPVUW+8(c&u0@B|j`& z8kf;bOFU>@(D~y>(s9yBZ>_3LZ6wF<^E&wuLEb{QzUCr@Tni{YSAV|FEf8U7gM8c| z!Rv8|MiK`!ELhV$p)+xnj2@JbFVJTs;D?jE!-D$Rgpd4?-ED(rZ3`9oW77jT4U)J; z}JUW4X$ zYe-QRtoFHQs`rW2E|Hi^SI5q`48H2Gk<`kC`Hz^a@CUS>GH7vF5j~{EGsF(h>E_y+ z+R=qo*&{XT4<0rNl#;y!1-W65e5>W)g%qh;-$t%oV*}#qjs{k~p*E=lF;C{O1h~eP zK5jX3s|ZqraS814mY3{S4|Yf4M4C-*KhgPhMxWXEbw-^%@Ge6=WSbhRvFC2^E~_F9 zAHebv$0Qc!x-vR5hL{bqO>JrAq#SE)^3K;Fy1ah)KTB}oz!G0R?Z4T(zyb`bFc1(7 ze=or`cLfoDMP&q*=zFZN%d}v%4E;nr!Le$Of&G!!M*~YrhPOT2h+M7WnYqTa5pzeH z*V$u<5girv3IR;H7^_F<3(m|+=dhgMTld_{dU@F&WPw2P!jgPv3{4)@!@vfS)&#lvmO3 zJXRIMyE%@5f;At>eU=9F4fZ-l5>tMjCq?VH+8Sv0u}0BD)5mctgulkHt2j5-ot>iJ z>y_VN8#H9he4~M$?R%MfzOH604?5vzGh-c1O#OUV>C=c=39IStxK=j;)139FtgEX! z;rk>;-rk+Z)RLJ}Rc9q&(s0{K^~1eF1HHD&VX52>sFlMssaQx;8f|=Oa?T8jfT*q|am*a~KNDFo?cI@yz77%Aqsjq=L^P^4lRDx_ULc?!$)#?1nq}`|KKnI? ztswdrv{hlzzqszPEwX**Y(zMrrC{lGJJ1s7 zZos8Uj*&F&wqW(zx1!paDOpj5-p2#2VT$^J8z zh{={hNQ_}dIt1Y>y5_MKWgmwuxG>qTvi7XkkF;yc9A|Ckb9XbWD2%cG4gjEE)vcH36hN$r6b=V##@fuz z%ou;D)2-9lRv(1)LD=W8K^*$XpmZI96i-I8{2Qa4o~&ul0M#Yj$lF)lfa6DpNhF~U zMln-2%7VA-88b%910Nq6eAv!?9q5XGb6XUpAgunX9`#Vms$+|Xg+4T}Ty%}FGb55~ zH!7ryQC|l>o}Ra8{Hm>~e9sh<`jL=21%Wuyp`jLtKhyRz4bs)q=@|dZ>e+RB$n3Ag z{SU73t(6LAfMtiK-A7{Y_!x`(j}b<;px=`>sU?v`;MKK^cW z4l%6wL_#`wDSCf8uggNAR_r>c(28wTYLd|JH(56_9bYHKF4bg$tD5B(ml@0Ey)Twu zQkM$^(*pKtVdn4kB*RDQSbq}L+K^z{Kz{m3v8Mqk`LVBDr$_O7o%A`RQHvJz($L!{x=-T9#Fw93&+C`VRMt;SbSxS8~)gCspjD2S$1b3ffoAd^yat{n- zfFuHWd`G1LCKV(+peOf}Y9(bqAf%&jz&4uo?VZcypC;I6+PT-BBzy}B_8~OCK`lRG z=AIL>t9U{$D)9IZD8lrCSE6mPS#!u`A$X2vx?HZ(am zq-?VzO~^19e!B(PKq3CSs@g>u4s%A~1oIM|957%pF++yKojyF4dOh_a(zo2oapFl^ z?W1ynT5jx(S}SPg3al>iM3u8%Q{zv3&PUj2^i_G#g1t0z?^q@c8Qs)UjVi)~{>M|SL!JCn1o#OS4i>AV`a?zt z8$|jGl?bT2F@%6OR;&j_j*EsuMK3$XML&Rs4v)d?AU2C(Od6|3=}py=e4AS|d-vnI zm}4>B+VXKKLin1;oqx@h5zA99!b<9wkninr)6>b({bVQb0i}x~4kMDRTx=RmJj=NG zh+p#5J54{wqkNV5Qwh@Q%|qty@+P?_{uWZ2{R2=QIeGix?NM0Yb^Ivt<2AQ+ds;5f z!BQq2)l|3#HUgweQ2utq!#6&Cw!_uEZd-$E{DN)FFb^tc)qZLe;sY~0As#{EinRC0 z?UoivxsIjF%rsM<>!V3f+7C=+at}um7+P1ay-%BufFO6f^5*nZ@?gILV~7xBn+vxH z*(YFi_-GHwonq6NzcIm2C&|`j$w6oNoNE1_PKt}n=ZGKn8awU%C&OOC!<`ja`xx8$ z)>Wp2ra#M~a6YNAE~ zz*x$)n50O2%eB>#N+Wj`vCCF6wOf5xHe{{UpRt&x`@Y0+#%RjJ05#K|Z&uXJ+XyZ^ z++DOzr}jtrwlg|a)g}VBl}Ly%p+T2Tvg;B_NDl$wz(fFfQ$wGwc&IszYZ*^d)7|x7^@REQFQ%P^QBdZI?s8e1YQJh9q)zSw+XVJR z!x+E*Q0IIPJKNC5&&u$cD4C7NR~3YuXp_$Wf*ysoyIOcbt$j6C3t`Qiywailycea7 zQY|2k$YUE2wbxAbp;RcGo0gNR(fsNYkjcA%tCW743vRsH{?y`q$$nJ&5udLStDHjP zw0~L`SkhNvJ2+M6li6O^nW)eFNGYLbh{GNnng?7-n?W6&0s zj6gU8ldQjs6WzBW)9E{-5At^`X8h=n?FcC9UP{Yqv-m94wE0Q*7%cQDQxg2>z^_pf z1!_;xoRT(%$vDYV7Z8u0mzuH`*LNy6!iM+$3uzp*Bxx!s zFf|hqDuzNon)NWSC++ZR9~K}T0kun0Bd2laoOI{T-&+`{_}?9Uc}X~v#P>{8VpjbQ zFjLaGvP(#&a2O>!jSr=JuEV;0)OAb5JB;0k+*zC!a2w)6nva3X{6+4AOX%g*N@NC& zQW=R=z#c}TJ;2^=X&s;$Sxxj!)0}})u{j~9k})%Jo%NPlsLG6zvi-WM5Ev;yH*{V6 z169O4*XS1DhBVzpDWo%4Fad?AbAe*h$3K06r$3~ALCB<+`i#|6Z1$Ej4cj8gx)rjVsvVgKhP^V%33}tPD|C#$|NNWdm>#vaT zF6!!EA(B1RYLq`x4=aQF>cQ{ktsvtaRC3Vs9_qlKh^B#k)JQ1QKOmZgOuT>SsByr6 zruI>(K~7!(gr?{tR6VG_kVnU;d4C7v&QMq2{))A~MP2?oDF1>A`a8G>4fxyY6?1ED z5F7-=IV$KJ8bH;Q2M0*`8^ntOz<~bCiV_+a|5tDs18@!fr_Ua}4xD~qhulHcYyc|I zlrPwycesFXDD*$v?Yk_jOaZ6Xf$!Px|GHmK`2o-du(bZj>OYqLxFY@c z%O7?T!0LuhE{>+=uCCS&mj6%dV72AHk3Wd)plmJx$)8mL>f{0tKp8@U*gRk{L8n{* zr2i8Q`5A=A4Iuq1LVz1U0NDo8BbERvnGK2r z_1}dB{h6c&1twsDoX`LWAOW8Lg1YAA(;1lgXMF(Gtg3`92AgoOt z9a#SOU}EEDc5<-%Kkf4F&vwb;6dR?Zgn+OFpXmQ$)9n0{&Cd0Ip%ZIp`rg1;8iG6H zH}LuI-2Fk2d;n6?KU}=mfOy{s?kGs$-uG`1BIv_^K$4Leldb9y5MJPJ@NZ8}LH>OI zX^MP4aOoF7Kfo+%<$XfhBHKY;vCY?|j@)eG1K zPjKI2`4{%k{!c6`D2^Y1{3rGry8rhkF9gJQkH6Hl{sS)x;&A^HOA1=%2Vju>Q9LHi zfru>x2nY?Z+a&)1g0DqEn%_al0szK81>vE_`T~eRq5=SHD7R+Nv;cS`(K2mTG~H@FmB|FZA^ni2p={FzN`XT5zHxE8U%qe}i?AojjL?2&**1p$~Knm%YE z&^ti@@}DH|mM%4fV9Rvia{t@1_{e`r)PF)zi+>MTfb9=}tB3qw_G`xffD(fe#-ZUD z|NlJ*!p0c54{m)SFqPt8G|kyRXqce*b!bG8pAZ1^&uordQaR_rebp4~)xYun^Z&r> z&qKq5tQ7t(MvJAw-VB%|`9GxO#ea~9g#XUOBxiX6YF?ugw3+E9BrGT>pdr3-`ch zQu7kbvjKNRrhheN?a@ED3L*fKKN~aTRwmb%8hp=Jf`B0V7yj(@zjy>ti3kAW|7+{q z<8nUxIDUt^J71NKccr`J&?3h<#G>R*2PqQLs1b8YH4#D?Z63_I?|2@@mc!T{F~jCi zY{Kw3WO^|kNv*p*g^WkvbPl85;(bRCJBYjviE!D&`dq2+ansp;|5RCo} z71&ndPg7<%>#itG{$x`QgI8-EO(%bPq)>W2oV8T+dGBMk4fi#gl)g z>G{I5zhviH!lbWrH}$->J57mTA`HmZ&wcWZRDgDI@mp`<-1UdyS^t!_i43q~BezX*41f-OuU z=rDt$?G>tU#`y=|4Af|{OH7mTwgqJyFms(EnTHJzaqo!yT}9L}lDSy~(27W;AT1KB z9~WttJQ_a*?uDTY1F8FmBF{BSveN>$Ashf zI>XcC`>^$!eWtd~o5OKW+K_K$MKR!&)wb-SXGkTD?vK^BCb$XqRpw<(a9I} z#V2F16z+p(j40}>Khr7v{**8lhcxf%XliP}Il=cfFgFG5Tz>4j7xGf|N{@0UZSjd7Th1;GAv}Y9aP|#D$eG{sH zW&)M9wtdb~A4;pWa-{eHYKZ3FnVQgxc19sY{p$r#9mRb7`Ic5&b=0a7;pu@H6Cw?J zLZhYZC=^@h0H#;inh~ytPJ(S=#@@j!RoG&%N?LmSUhQ8@WdoR7(|T)F_;dhsR}}5Z zh@SYWmqxQY(=^T(?G#o={i2zR!d80j9C-tV^}s?W&rzoV3fmm{)7qJp-P*k653~rq z3j!rCK*7;e9?jlTcK@8M74_ku#)Fb~^vSWR_7*YB)0&6M{jjAIg~c%UruPQEmRV6& z3~Q|bsopE!r41aIKln}H9RA6g*S2L!P6R#Tz{ylCEl<(5phfSi8_l_kqsJy8uurjU z1xkrnFohChS!X30e&Mz@1t`1pA1yR3B}$j8r4u>YKsphN&W77-6=d~2-?~0U$^sVh4PO`}Pme8*Zjovq;sutO$l2N>VSVJlN#+ z7f^oBOnKAA>IF@Qs)l%Myl43wipQZxk`1}NRArwGRM|7#JLS)WA$ic6h+>&I-a>GRdHAU?oRr5Jd*zQ*NV)8&XsDLQFT0X zRjzgm{clAHz2aAoDt(h!n9N+2?5wj|H@?D4qdAJkPA}OK@y+WCY(+E33$2yYhGRVS z%iyfPbb;XvZA!ojac&T6uIzzFmNb0w3_gB?%*$vBB_^O3^h-c%!wi#LFsNJMOM1zB1gq;Sl#jRN}lVUW(vnw35E8F>evxq;ydI}c->6l zgv$agyM(H+9oo2yL@ctu1+}A*Y1x4ItAgL&sQTL3e_7?hiX5oN&Sw0T6lUEJ=%0yL zczFb--uS6odr$QHIDp7IU~n}@y{X{3){54lF2s(xY|G*MPNPJp??LyTYwc;{ zV3i*jy{Ntf{An}3tU>U%1~X58Zi?NG_c8|Pu%&l1HRW@SHQj8`;_1y0X0I$eFYeCW zKnX*bdy_WaG$;vsI-mDS_G@!aJ3YpT>ydrgqpoC;1c%NJQ8V!9i-0*t5vE{7RVLH* zLa9%Zisshz)h~n6EpS6d(*ii!UI|Y2f%`|wps^vlB9Z%{BvuNm} zIi;hbWYt!it9e@LTc--f zeRu>BFu+W?zzgPaw2Km_1&b%IuZ8%@Ak#HwK_RDnsC<}u3{Kh*zV|Tt)6R&MzZBAa zTgBLmN~|3yW}3RS#V(t9_96@@f&qGo-?N9phogh$+m*+x)-``1PWaUOjnXf+}c*6+RTv@I27Jl(F zrH??Bojoi>dr{Vk=-QElSF}?Rl?xFsK*gYr<+afrVa#AN+jspS(2gl8TGV4x{4Cf$ z8TJH9!SFjS(77pUpZ9q2_$v{J@yITw&B-q(II5$wDQZgkR~|SY1C4jgA~NCzS&URe zT%49@yBX9`vpC$W=9D)bx{kOlO;+P(JuJhUVc)r9X26fXa$ZOKMyk8qtl5>tbbch_ z#$HjUR2(VlN1|2cOI6UXcMN~uhx}+kg{jzL;=wCuM4wZ=e}{p;AdUf2a4t9HXh(&5 znib zeQT!ciUS>Kq_%xsv9%J^b2Dn26FHAkN4%^(=*JhNg&^g|;y`msAH}*VKHgkos66F@ zJ85{`L@wD6+;}8>Nbh3v##*#(@r6@Mpz$AOW9PT!yeD~&W}b@blOM&DECR}JD+fqH z9uO?hNsZ{o4#O`e<3N;(1CeZnbBI6>jK=weXPHF~N_hyk`k(^k#dC8cJsGW@_%G@l zuC~C~4QA9C1E)MGDNS9}r}wM-_BmyxVNq`#Eo7fTrVK_equ1I)%@Z>jJydYg2Rh#_z>RL1uaky_LpOxkf z73iZx8&9*7$S)H&eUygFE?~)&k89Ac_P#z;HWqz%fU7OdbF$Ubj~l(t*TzVFr> ze(}9arta!&$>3od@LFTQW5eb+XncrF$hVxw_|TDY%$272*xJ!`Pg@r=f4a6v{L%x* zzJmx$OUasgKjXE|v^H0@zV6!AKMQc*AtTU~PYMzIf^oP5!h^o@#?uV`#B00RTzBis zQL&)TJ`v+E3dDAVL%tcfHG-VSvtEj>uGusC{SGr{BIbI@%!DYe%ZEN5uU5prc2AiY z32b3!Qws}|IqFFl#xpOa1Kk^1clZjl`69@230sl#1dw@C|0ZM+-^VNt!WB2ou4*++ zgy7`+jFDHiYEaxt>%f;7r3k#7o>jR$;}qC|-QD;rDg41sp!X&+Uu8;ahKEjzCpHNSalT&28hq@WC}onmWIFfkX>@0(H^k0`{%VZF=RbD~aPE#qJ`YW*k>)-B*0(tyNbytD zWv>2M-7^Qw**H9Fkx}a@0{wR*dZ}Uc`S9Ty&E|)u(ap%ABblr%J;=0kBz>lujoX!; zIb)DQ{P*>mD9MT!KXJYT&CX=46$jhI>9)Os>Z(%HY?N1VG+czCNt*>xNNu!(MuQF6 z_$w)N>O=)o;g(@4?qu@xwhEZhaTuzs7gCHs7=I;&o4a$gzd{wi3@f&~fQ9G0g~{AY z4Cho!vd&WP=Xaxy`LRerHpZ84Pi~^+S?C);(Ousa9ehbA?M6ESMO9XNQ+hnsymhejN3pv6%8o*>?FW zCq9zqWut6A%;7RO+L6s#DURoBTGY)%TxQHSJv}++3e++O-4Y*>fAraJH@>~L+`^<^ zKmL_Kdwuygo-1F4#$q!HF_RaZwxh{;8a~@snu8MLBN)FQ%y6PHW{Ov9YPvx2HDU1- z=JoggOiS?k1digBh7Z(x-_keZB&{Bk1&U9|H7CChP_5jG*I)WFt(ZfZobRttrr#oJ zR9sRxDTh;fDxQWD0WU%R&NP)y!+c)yH5a+k)oCnH3IFT&OvUTeueGc$HKNx1^-~{3 z72an%M`^iG_0K&*z9d&&8l-pH8uj4MlEV4b0>vwCVrdXh)$4Nc06zAPkfr_VXiZ(F zGdCfNn+}=&?i;cNM%j8UyZWZ==jqH6l(|s;Om(;0 z_ffB>L$O>OY;HQvSqs`V8~ws*Tr7sD;c6yYi+^@%#vG^vd=#=ivmkqBYm_x3ykTQQ zS7xd~$ZegGbsqk-Hfw?pI;-Q%LbdQBzfxs+$pG{fW~J=<1y_OQIWb4-FxxoxY>Yk1 zL&#>}FNzxDYdeTwYpLjxy*b)dp`_P$B+9)7r~IhQ3xl1_Q~d~PW)pf9@oML0y1f6c z7yNH;!SAAc<}L!WF(1bHwtYi(wk3dv#^f|`z|g@6IKB>A^SQ^$W+D=M&0GlXCioR| Nn3vVv9$1t#{|6+zZ~*`S delta 588077 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 z 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 Ri93n`g4kXgAz!CAhht;N}4m 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�&Q52f)tv)(6i!vBi~c)2Lb`AfC#X*RTDl5oi?ai6!7aI@)hRnX+PXvD zPe-b+;Y*9sWzSUc%B&&h7Ja2DQaO)!&-@Ag4yoPEBQJ5+@+8MO(EmJzekodQc5>f# zM81FXDfONd-uZx3l!1aqfPnb?8RC`~Ud@IoyeBVB<`iB4_}f=pBn2NK9>b`MWh;x! zQpA96Fdl-kC4xIi06Vo*cbN8mkd@&Q>hA~me&QO+h=oT6SAW;GNA=9HxEX;byqU0S zTF0MWOqh!IaoQlLKU2Iaf7)phM$WL{>_GOrX5T|@U-?QG^e8N{{Fo;mNwf0je5x9L zWh50}oW4jG_*O%@m!MoZ6rNlv)v(g1q@>!k%78<;`{~R0S?ewg|i$hUt%uKWA4Z z!^yd`K=Do-IE{Iu(hy9ymV(dyN{zg#xjrn-9X;N~%>}eH|sr zk0d5}H7v_1kPo5`D$NB4&AMYr2c}`f*AcqeGeX#V4mn*X6v_}P79|Nv*~aoF;>=^& z;B4bq?l>5**gpDoB+NcbWF*}mwMv?5R?gp`7Vz3&><*&~%FCa`Lk;IB)RpNEm|WNLXY? zRP{a&Yc7-g9_C%I{x4s8+;j;CAlNY4V4&bbPwl^Qkwxl$7!~)M=(lcKW2fSxU&Z2M zrG`(P_G>24N+AYGG8f&q02-fRF2dtUXMG1AJi*Ac9+-8Bfgwg1_d(4QtT>Zafq+n+^Dmn4Mp|WzC>B(fFyD$lczt6h%<#ni=q^gKq%gEMU z{c1P->L~l#eaFa6D{;BjY;LAfKKK>WW?5zLlfKi}Ffpa62Zc|l10GpMhV}AL(5sl% zxtGQLzfOjb`tg}Ph?*bm6}TGj=g`_~@gEc5vy5Kz<_FJqk!m>t?GMAVs_CVaC&i@5 zA8fj^v)39#J1|^jbx9)xi2j;ueBD2t)p5GLaN4mSAWbP7m#U7U?!po^U9x`c`g}qZ zM}}q;8oONJ!x}#_4AjFO$}EPW#;D_2^g6~Cv~{SW)1;vENF%~A$v80GYNwJ(TtK4* zJa8#o!1tM6VP5}?L`t!^UZeR2^N?S`F+U^l=UVk0wUAw}0#}Q?qFbnoFNK{*7eA*q z&qNZOG1qAU>+^IVp$-(Ujg)XxUIkD+O3DdtlL-`xUZHo<0^}9R3MSY%Omf&|%eBR{ zasn0f8X#+J-0B^4F+9+Cp-@6Bw{Y06H{s0MHHE|$*`M-eHw}jc_vRqb^3S5|zo^Se zdQvpo4op{ixOK6f{P^Fjc_Pb8g6sOQe@lu;nnI3AhtW`azkmAQ$tXLGxkO0<0Rb~7 z2?2qd1{n*7k#=?o{{@(D{pe!lborK)1tTmR3LQ~tl!z)MBnKS=frkVM`9oJb%=Blx zDb*iYP22hMmbuOQ3%76s!aex9r?^0euSNscB7R} z11oq>u$XrtM|)teBCAzE5|WmUhI%$Cee?z6YQmCbIp#?(LAB^8JLODP<#>fXA4mHyi1CO-IH-GU5HN^DV-TyGj$ zMeoa5#`#%dz&Maq7-5;lUoXbRfWtAwEH_5)yy0Ds`Ab@hIhQ6|Ya086Skg$DZ6?h^ zE1W7_)lLan4mya%Ok=jXYop{{k_=alA}e)}7w);Bb}ljCT;H~fZzd!1n>#BOxPW)n zctn+A0oTmBtlkWFd?gh^&RDyFJ>}TJ-a7JDf~Q&B0t{g2+|G*fK!fux>o#`)ICREA^+TlT;x7FdEj1D2Mvp8C@l%x%)HuI5bPCW<$JVXsqCV zt}M(m@@#h7Js)rX$=~q_44$mE9Y4m9R5G3zY#^&)pg>)Flx@NW{kE1eQ+ku(BxVI= zXc4*esKb(GAYapd`p6ZQ4L`~wpr*E;%6$tLTDMnq8xmIK02&mtA|^w3w|$pBo9M$O zW^-eiLa&V+jqBuTS5;kW$xv0Vpd{W>-d1>M-YJHENKj&oucEtc;oV~G@0M*d?d2-) z6F_sH8KdJXW;tS&truVMY3ynmG|6gjMxr3wS*ec8awVM&M*408yS3prUCDZ>wL;;2 z^rs~|x5eIutc$fy3PNdDbFN^#Ap}&^%$vcT%teUh#yW{lWBaph+hdC*6-gQ8E_2R8 zDSD^>Qy_mD&F2B>qD1^Q6`hdWu;U4KD}Wd2AYW*k!AdC-HXUI*%qnx1pMhy7fqv6! zn(>o2HWlkwTmXAN$-9d)rr_ipOB=hFtq**x#tOq3sL2KP$oM%>^RSMuZJJNlXqu=E z{TnUrG8&;;51+=T{dsIX5d&9~olsGa(ZM=jW+!&+(o-vKk3}t4{&fhIi)4#_Lx9ew z{L~#|-F7C8{<*FQ<}XpbkeSPckaLA>C%B+yv?Fk0!;^)UcinvYtN|y?)P-*vCqYDc zao=hx>rg)G9Ni7;7V(O#E$f{5NI$Ae{$&ej)eM3{=}u6RC_?erJ?0xmNO+-dGq}u0 zn$H-|8Oy?9@Ro8li?qw9`jM|e@2v)X`C!fQciINqFRm+2B1eZj0!#yc zZ^xm}}eZsg#${IHu=01itXM@#_+585O*bDhq4L`kvKJe^xaZzy=R%tH3*i2%_$ z9eHoRoS^~^hj=t?2kl##=>VJ8g~y*U1rA!b9B+8?$^PU-32DkGoi@`Bhx}!XZGI#( zS$}?%x^jdDeegaTB>6i`6CcJM1=W-`2>%@x_`8+0K2p4{)7JQ|1DK6}Oy|ixM~MN& z-N-T&tHz*1Y%R2@=^8l+neVE$h*N^UavJC_BTcfHg@`q8N&TR4CbiRwPhlO*e2CeZ zUxu*#g!6(?a#Ij{b4Y6njR6ui_N=_ z=zkoglI4y8-_rRecb+aSIKr9x+&KoUVPOf9!&(xLP5+B-1N${sOgg0hr{^WZzothGgK`LO$200(+NE!lra|Je&*}oPO>GsSp+7(eFq})4QVM%@CO?YJO;!}gZZf=7 z)_OAZ-}=i=r|TWn=6^}y@6ca?^D%S%^6vx(;UA(=GIVhDL}g%jW${=~Ez5$jvYXh4 zbNtyTj$dQ|VVmCgUzWO|aN~NzlLEzI%z_ccIhix71H4ley;H)*I;4d&htI>A%gcxZ z@)j)z^fPML+DW$4!A|GR(@s{thDij<-%C;_bn*6}zsbpK@%8YAVrd+Oh-FsX=6utU z38~WSTd>clWsA!Zw75C|Pf!}#5HfuZ<2BPT^o;> zG(mQa>|{O3{7W5FkVK)*eKYn0@8}e1Q%l97o~TDTBx(HUkQUtU^bH&FkVb7mv|tGO z4icqEP2MT8((_K9&qPECx+@%qnb<^@lm3D$!#>zxDH;B#&pfpV#t8k3C@&to`#a4X z`0VkZ6Vh)TBra=p8tHy7 ze%d7RlUV$`n>Q2by6`o91diTcm-a+zXbGE!h|TumHxJrH9F=lA)GGrORutT$)Rwpb zTO<1h)>hCj6c$K<;N)Ew`F3;^bF*f8AgL1+MR+InOwoyaX%vB3JK>3w&E2Cwjwa}{ zem$7<>6Jcw)ded0+2om~G*J62)>61{tZ&4{d^}e-OTWdjPM_^*P7KmtzggILT5H6z zTas7-`U%E=dM}OMUn>)B*)Mio3i(gsKrxv0X&w!xTMriQ3F|uJm4A;*-&*Dv5I0O( zN72QQ`*Pd&&0zOK2ofy#bzx0xE>-zdP0)fKzhviC;?pX77&Za;?9+{t+m~P@Gc{bW;gLMzYWIbV z{}WIKQ8c?>Von9{;c3Xc3=3MNObLFXq@JCstI8>fsd0)^Cileyip~G=Vnn24&Tf{YDES>_^hcc`)&+cxveEhG?3ghIwAV zn(I1R#J#3#yeKhq3-){VCeFMjCs)?>@`W;?-9P3WMU-Y#v9$PWn$$AhEAcK&y^pG2 zSHK4?4y2N6R3y4FQ?S`UyN>tc4AcFy=Fh)b>yNC@3O_WPXx@$tN2$B4w$|KR&#t8} z%(*{hHet?aR4J;+jjKzBTJ<>fJ+Ww{u9k4B>G4du5R(zzjtx~W6GanMF>jC=5W99y zhLdn|&eLD+I&EFwU3b#zOeNNarDY@5y7S0QL|4`E7HQiDh*G5j%T9zyX9SLoH(Ejh zAkPaMsxt%#a#24Y3Mty=fYRLaYSU_?wGE=RhFLo(Qc=4Y3RXW@gB(YDsWHJDCWwWm z0k^b{az=&4A3o+9t~ip09*!a192zh)@UoFVvp7#;!y~eh6Y%2#z4w^V2O?9BI0Ga# z+9tPT#G01w>TZ4kz3nFH3Mw!;_bgT4kRkk|Iowt|Z4{)rcEHnJ?{oGeU(VQ5tHsy% z&RYsKp0_jv#nvOaeE*E%2?*HoQvWQh-bAWl)j6&HrK8WYasxKzlES!7%Rq%pop^4s zb`#^2*z#}l49eV7G~5j&yzdnBn(MRcJPUNM{mX6^BD;+RxC`D}&N79hi5QKTB%27^ zgWksX4=K^9V4Fo*!LZ*N4Zbe|X3g^a+O()BA^i&@r+9q0>RQy5KQJWhcxvw60(dTe78MmpJAHUyG4jC_2`%h*!%wTgjtLV*O}jk2|o zNys|)9zIl^zrTtELG>6VnT3=ECC}wI%yT}U?(5;k+=NiJZciqwrZgqkGPH41C?IuH z7$SyL45?|I`^kGPivqdZ zXvxY7&dlr;qPPd7TVj4Aye7x>bN`we+2z{t!rqg3%b45y>JWdOPYA{4>xbo}`#+y? zJmGc)O&h_+pW8YUOj#m3;6e@?l%y=nUH@hPv`BUeCA&02l7edSzNW)*@Zpa9aTAM+ z|8|x@^%xT^iJ-Ywi;Zwyq-YjG9~`_IO@cD`@njKYQkC-2W*I{jLDG@Qvgn%RuPXeb*np95g%aMEhJ$$j_8>$vE zoRux(-B&DSU6q2m=s6*s=QL%w| zF{EIHwEWnTz$e=w+#1g6*`L;u1J5sLZi-8?J}V~PDSh9rQcw~R_GoWE(6MX_HD~me zg29J?0*Wn_mO5H4xRyziybW{Udw&+))j3{AC&H?}47)3#T*-;mmvy1ishG?wF%ArX zaTn2U@J`YOPIbQmj~y*DU3UJMiygk^oxqH%W4Rbf8XMe-w8mSMhby8NE0(GE$Z+k&VlcDno#vdl$|HOA6V&XJARnNN^Kbitf#+|_(K5IU%wNKpE&hFqWOQ$l+D+3~Yf zVtFw~YitR$$Aol}`S+P%wytp;f)^N5>eFPJ_)gYhYDbQhQkrC|yU&yW7Xp_CQ^KPk zZLiw|br^B5_rjkY%`jGCxOZB11I{(vg12iI8JR90#9uGyu*5?hi)D95RC`p0cR;Fx zvz7!3i}>U9QZ4u~9!@}q%PE3oWoCsu#3D8p$je%wa`<|dAS{NJ&`bKHA1284gk&9Z zvW?m11s$GYO)`WpDzX)zk?B(QSXFL>&=C@FE8wvb)$|MG*thOpCa=W1{<~;$RksF? z;y1aLX_(aFo75sm28SKm$hKng)KM1&QB@@ADMkp{p(|F{AxIjjhvJ+5=}Ce^!eGG$s$?dhLJu>TgNWuSbN0|IY#nC#+B9=Vz!zbw$rT zN^MgN?`#kulHkba9(DzlEh+DTW=rF70Ur4hxny$m>O9ZzFLXSTlhy0HP+T23kYOWS zp9Yv&xaCb+^2$AV=bZ!19TVky-QX`A1B_Va%dy=M28cvl=7bwRSE?&%=0sZT&{c8F z;(d*j@}m`mBQkvlAeKh2+c6|!lXT^fX1d{%CQS*HhGe^t{GD4%pX61d^zxcO(QcqM zxsuvEq|N?nM~+5(p|e4HYm@pV==kIuDuK@6Caz$I&?4g{*tE;px!H3a&BCFVvI6}$ z>-{e?h&B(@WjCGAQ0J)_&>T+!wqAnrGf-0p{+W?B>BO!;P6=l9%+6tDFIrVP6-b?Z z4E`%NNTE#i_bs`isk$|&e?200Da7jh-%azmmhGEvYD38RwiiAqQ?3Y$)$FE#E#bJe z)wBzaWplDGfNXI*YL4ZSQMUuxwHcl$Koy;_?I+#$P2?64 zzs1Q|ChQR)IM4rC{p*)$z-VIf%g>+>ElXZoJr*(cAY2w*q# zwpg_|RfG&GmQ6e-Hi&M-dFjeQa%Xha49;0wsNNP(@OW+i)wY9i&8qP9SqAwjCbbGl ze+T*|;5oCkAdK|+OrJ*}x}EeHgW|Ld1PmUwr6J&1+=#zb}A|D&2o z6hkq<^3(LYSY{x^cSblpRqm6w{6MIwI1!^b$TPmY;vBI{)}8Kt#1F{tzQm=^P?<U%wyib9s&>Gd@dSA$Ea+4lfSI%KPb|;>?v^+3!vWk z4w^$8Hy`#*pcO7T3sg4=fusz3wQ&o)>lZf&VHW-Hjg2*R?Ft@sjHcaI+I1QfnVNwn z`RnA0pgiav99&QG=FJ|$Q4VU5k}I?u&TFo~bp@3d+FYKBKWb}VtR8Yz*$LW7{K5h3 zvRbk#8X4ew^)*&~2vPVEn;L38`G0%De2R|a=o7Gr^lR9#88*;k-u}$jKe6N;A4!zp zTeac7gK|WEAliMxb%ijr9612Mp*3XNgrT(AG_fy!R?Vi50G&l$hyedY&;zipv$mFY zodGv8{piZxZ+k{1~^UiXe;wNo}s=fCfUh-olg)!0&EPb_GE-OA|xQLzD z=0p;dz(c5LLBiBXnqBEgPO;FYs|Nb=jgZ=DCZKlMPU8nz-iBLay^Ss>vm-!N=Rs(C z!rivYHDK1omsQiZUqMqeF}mWL`0w!VmO8Nzq`GZOs!_$@s3j@ z#}W-xVn_-)o_>*{X7xR!wWduLmX^54;4dB@HGEXOiC%wvC59YCsO-EH%5fL&tkQ*_ zh~mgxQdMA9e0it=;#pmlY63v{gy3AA*U372Uw*ECxA#}FSKQv7c{#rI25i~!2!i(R zn%>Y+Vel_7AbX&~w+^q3gLD<_Zt1Jct-w7ni+TI~#Sg=aWb$g-g>5N6p;gI3Yh@le zM*&`lcn2e6k1W~>>752)%AH2&WcFWA(`xrK#MWVxxW})+$E}6@aR)em?~tWmxv**J z3D?gT&sBB_*?p~1_OXm<%U&p_JM?uc_QA_ch{%gkg6!ZtHT+(Xu8ji4#8NMIOpq=_ zs$-*iKqhfBtxW-WK-2EoPD1yTAwG!qN`p$hWu0^&-A2{xTasM%bB&U!8BVO)xDR}hF;jE@qM_!WLe_73+>i-~PQ zs?C;|J|($vW{=W-qnL5vsDXQ9tHn5FjQOj6$srg`sWe zvGiD3DNIp4tI0fklBkHVl|EM}q|3`|rNIh2$nXj?OHBWupqtQTw11cdoiOHmf>wRr zAMrgJZnx+Q)$14eG2s_ykEs7NYJ;ZBe#rt9ohMD;qxSV?DOVlMrha87(u`OnT#a`C zpKm}LvUY+XL{rC2unYgQt%^L?7flctJuJwu@r4GJCG>Gk!kI!xp~OKX)imXt@joqI z)}5J91|N3>b7Pc*8t+@WYyj&R40=)M*DzSZ^Li)nkD1Hx+m=mvjj*w%|$f;U|!q_=_A56jSM z7o^U&S^}(fXpv1m1d*XwW6P1;opPWEaS{1S9tFz}i?+=TlQz-{XCt@Ns2?ZBa_RB> z##YJJW80T*V>otK7l95R^*bKw_c|U}fFlj%lMC_a4hyea1eceoBIT_GQK`r!b4-YU z{4Aka*BtV6hCCh9#g6VDUbf2F<4bzMO*i%LPCL30V=i~70BPE&N8M}Tz~2VZpt#2& zq7;H&Blr>}RK zSg+K@#3vPaDd}wTqnht~YgOhNWf_6<$T+GHfs{Spu-acroY~(Vyl0IgxIp4{Ou%f% zmJZiIvxjPhPgy~2b~mit2J7$(Dqe(UY(*+E9@!n8BvYeGoF!uIFAh{ELzcN7(ge23>UOvgijF? z7++iVzPt`pJ`(8c_(iWu){&x~tmjG0@Hxeh;@|hHZgjiA$$d$AJf(cj5c$m6?I*q6 zLHs#|Aik8tg$^G!rFTYzCU99Kyn8_G6{-0*xbfMWk9cZv=t<}K8CsA*<6x~@+GQKb zMH1I##35TqY|yuy4UjL0ul-pbgJD%LEvphOHfNeGjTi%V4Xw>yz^kwda>91QJE1Yp zmS~S5Y8yB#u897+ZaQ%Er7(|(qiHrip$I1$(tCYL$^j2&`XXB9$Zyw~Bbu&dYNH(j1PP#x0e-@?!Z(eE(Xn z%KY6i?3|#;DWJhw@UN0IC|8-&NI$;cHL4BwCel;DPstDdhF&1Yz5IJcjUuzdF9vD_ zrB_K61C7g>41m;6_g{)t{kK%%F|w*Jw0X+KF_P$dMK|b0poE!9P@5pzF}S**;Fgzf zhIqqA)*rmLShPm@99|h`ML-nGE6i!6wb81zt5Xyd4m1)Y6yY3StkQdKe1dKrd$V^d zNcx0%92X}-`vAu_xC>F_;O$oz58yD7#VL{`CPm;*`UG=}te0D?m)NKAcG#%+P=4>J z=M}osfAh#|Lzx^5^v((uQhum-JN|+2CiuTH1REUFZq(D#M->RX(x7B z<%P7-5&i9<3$-gq$t&JoRTCtw#u-h88S-iT=m_F~!(wAe{_LT;3@e^?mdZJnnMK|p zAt?Bz`KQSF(L^RE8lHhWT~?nOY|!%Bviusk+N3n5T}w*AL4kDpw*}_IzwUN<7d#aU zyeb4hOzu2E)m=$Bp_d<3YYZcg-I${SWsBZC;kew+8Y5mVpHhA7DuZ845-n+HdI_u% zdLA`w;5mq7Rw3;(27)+B8|s*XD{02$u-@UMMKWWW9tHwC&~`Q@eUS2s^7YBt+esDk z08GiKc*SV6G%6d;b_%EF@ZdS`;4GkJy^STeJi%F&VPF@M5~F}^=ihF*vQFayo=SB zEmcj^4JFTfm(=|ejofe9%re6mM+cEi*tc&y)(f#wJb<-SiHr#CDfiA2d<0ySB+y~u zA=96EMnd15DL+nhet|=Z5JuP1GXnU@BxT#APtAl8Jr=_RFh0fxmx}i-(cT)yCvbc# ziCMDPk!GQ%Bm{qiLFIJ~^|s`Pp?2@$lFw^2dv&UVpQ?C&(9JLhS*8DaNFM8_&vCKX z;mhHi8~~b!XLN-9Z~c#pILRxf36YyeCRA=Sl4o7_bHHA7W>$hd*{Z~$CP#jI1Y?IL zuUX2viU@eipX#U++n^AmL~Eh5>Ku$D3DZ}x?R5=mwn+B9{ZH#f6hocM zXYlH6dKKB$_>A+vp{pgJ;&vAb0zw@Q0)q5Eq08C9#4HUF9|0+C#0mu!@KZ%}nH5KU zXY`lkK!E>Ln%|K)gSi^;RZ^N6KF$!@X=e!)?pr{zdedJLM~cBz{xgGPSDtg(b(TL3 zg1-dIXV>c!%OXlMTRY$G?H{^U_0~5(e4i0}I3F2f(Sk99*+o&Y(jTXsZPeTCcztjy zY`FCY4QWvI>IheTNSHF{fezMo^Af9>ROP!IwHs`Wn`MCpj`YjtsJE6|gMryN92ZrC`!+ls@Yr31$`k({vqTa+%!JsXK!s!y``nz=RYQP&6;P+wG`}{ z;s|TAOlZ?f1aR|TExF<_r2>YsW%fQ#!d_zZX?$8D;Unx(fHy$gvIwq$y+qi~fSADO zLhGscd=oc1zY7?sPQU}X$@RiM_EbMfacZ zU0H0*Y)7LhpY%xFD?6dPohz>h3zT17B-hP$!E^!cV9^s z+87T?T)W@B-^hRS&w0JJ+`Q#a@QUP25_wD@yZN)vdF`~^M3GLAzhXX3bU#i|ItzRx z$uiAD&J23(#4=g_nQal-C5@qvp~Rzm2Iu;>mMYxce)oP(3l=NCuf z9o!X@AYf--p8Ac~KFy;~w=1qiWh0?6UOU-^oIOP4&x!>7-IpXcyjLdfIaJ0Fk5967 zVYnaa=l(a}{~H(nBgRhO{i(2LscO{FZCRfwgZH@&oUv2$o=dxUWC1lL`=5Fr(z*)~roab->F;RQ+>!&epY81My z@CnUAfG)l2?cs>5c!Y;ZvY|n_B&A01S(6|}#-(tt&bb6DF2%ZkjR#w$AxsJj0S-{% z2=60P6d)gT^xYmkQg#UX7_HKVKQ%bBhRiE%LV|@TTxmEVv<3?8i&$m!2S!68NE`M3 z?H`pD-kt(IW#j?@*&1YB{SO#8)l)VZ`x(8MT-dC7$hyGv58_0S{I1XjZBpxf+Sb67 zPn{kLH+z?+kwDVGQ4l- zkoQDoVE{4}o(;x0p9&#E%Wr2J#1gBugzUB(nE&lm{>jM>*?+mD|IQ~9i7O^>2qB294x1mm8208YpNYseJ~}O zveanH3WczY-4!E-O@OVH43Kr_hnj6&t!EgplshQoBY%K9vCJh$}`5W zA?*Dp)AZEw2|}8v9LgGbDY2lS$pWV8UW~}Nh zTEOUjPI|{T7$!Jl5J-M2*h8w`ZVU0i#4e6L`naReTz?m7#<(wvE$B;p%!)Jli)T-r z>`LDDR=(@*li$KXR~epu{twqr(-DW#LP{=xx`J*cw{1>e75ODrM2hoNhO;R=z#Ic*c%3~?v?FH^m!TX-Ezsj zNf$m1f3<-kX}ELUJ@EH29A9|(zSo3fy#ri8_SKxGs_uTZ+_gs1->fhUX9miaM1W+n zL|gzdh7+Tbq9tLA@@nkwUZDvc_yLpSN6YxB!dIS&w;g3@+IQFrE{tv2Y46k+$1cz4 z8<19EEBU}MzBp^1eI}t@rWdQxkuMM1vc*bd{C5E`zHj#(odZw6_eZTA$6v54xBL?` zD8orH+}7Lw@bcn>M9^?*D-tqJ}<3GbW|h_-p2)=W|$&u8Ks zEyMF@rU;dsy1o%+@Pq#T)EH~OyXtsKh)d$&`530<7*AY|h7o8jecUr+ygvBEFCOBL z7uB9SAZH}uv$0!^FmWR_f;aODdCB>|>yG!7RT(=Cg#>{UxT{M6WF5)AMV^UH1TEDi z2|=WB#j@^pV7^M$O6?TI58n$m38e;8n1oH^xHUJ~+F6Y?HJoI&TFt^CeQw%COKik1 zZm=aZS}!y@(H3v7LTalzBkE;)nMnC(zXG2hl;?KwvF0=RbnfN*p#OOPJ&zA@i%@xA zjEI1Ui=kx;z@~3u^;PinV5J*P)yRaB`injx z+G81{8ho=0&%1!3*Ue8P)4UpV^j^d;tYG0y^W!L>WI3rGgA=qOjHqD*c_#MU$KTc` zXdYQ-Iv4C?1NU{F=5K9%Pa4QNEbB0PAw4KiY}_&q>X>mM;N20?|1Iya}%|9$fDa<<>)^zS>{#zuq|KP72{U-{5{i0 zd)NMv*oEfVMh+6?Go$OWp|AV_V>az5osVif97R&jSJw0!`vkg+Th3W3F2_D<%_d98 zdAhL$m1JT*U_pBl8PqqBn27!f{(V{m~i1@W>u&f;|^1N@k5w8KezU9jPdp zzp!nN7}M4_jS~SPZqiz^f9<)Ds^?`0W--SH?#J0G=le!y(yAMrb{xY+PC8v_IkSecinMg+LLw^bu2;f{>&yfkRsis(@eK-*S z9(1@2?{Nivxy(u*K&S4A9%9wX!PQ!;-cIcA%9%0$sU>I`%m>bY;k7%gqlkoE5kov;gT8xQqsuu zLtc##iF=_&%iiec%+luTB_Lm$LgIEzZfR9&nAhfIPHgBH&5WuEtu2WfF5!`5Y)EEu z&KY{%JQcwxT91TS?LKlHs_*gFU?s%7K?`V@ZBrKCBIaB}0y1?$T20+$5RvIE0-$VC5{0bB1a|J--6vsdujLqmmiq z^ac@SV7L2Hv`I%6SB>>f z!qUv2p4m>clK$)F&sZ2#KLj+rV3yc)#`Wy3C>2@a z`lqRDi>wUD_%K&zwyWC@hoxjYXuddx`|j*F^17_cobcD~vG7&-)WX%6;jx;a?`vCm z=L>woId*Yd;ZFd*sx338R;TgB7v|bIB$TrjxQ+ygIjm)qlzHQ?gwy3{rHEm&5V!Ah z>6T!uuhvf`86DJ(9b?|U9k)KvZKI2m3+9@rOsDmrVGIfAj}j!={PB8tIrOuy9 zk_xwvtIKF+*vLDr`-i8q!IrJBm$yl74#DP4v2SXGP2UC7sj=&mVtieTZp}Cx@UY7> z+hC>*%vnFjpI?)-;9zGzOYhpuf)waxuaE6lN^E^dRyPvt`j`KYt8)y}BzU)c+nBa( z+nTm*+cu})wr$(CZQC}cZFled?{3`Py%B||tol-sk(H6B&iOql_A-n2x)vL3np`)5 zCC9c&?BD5Myq~Zz>+bvdZyzX9*P($derWy5ad}Y#g#r(Osw8b*sF8uDg&N3J75KvE zhh|?ipSlnLM1cKC2lqc(1{*u_n_9t+T+OaO;Lw7x5Uuurt?$t{0#GV@^#%Ezn9)?q zqxvBb$P-x_0pOM{nQD*DTQ6&74%BRx`-5hNu`|A2(KMu}j*RPnddV2kM7Pcu(ib-t z9$8x^6{@IdGS{7$(}@&bKNv}DE4RVT9GPc~sK)9?P}jUEvcQ`KZ~FP*KOJm0d4;NkIWuS85_aPXz;=?xyA}rBneOW)Xf=S^_V8PXy}LMk zWyC+~&Fxe4LDugpy@kRbko3*oAKbI_332b3J^1K4{6Wn%hQLLE3>h9cHD!vKwAwje z-H&tv?IC@7ZD8G}S@5r&5agxa_SgcDCNgWoDhD2>k!Vcn8dEG zJ1d{c$vE_6ZcN-ktWOnEv8IPznj+7WWxtX=9p?+yj9cwc(==w>9Dhcc$;t`vqLd|a z>>+9L1Lr~>6J>RA; zA4u0vS&;ma~#8Eo(W4 zpsUv(NfYuTi20Vrgzuk7BZZS%3MK3w$_Sa2RMA8 zKU*HJpQvrcOQ5{+h`A(l7?0oq%bzs|ox*|;oV8G}!(?)YeG~tp6s2!lu%SZQ`R$|! z=KWl?OqdidWV+}QyCb}E1W#1VM61nAb%UmwhRHkplC)im-$5? zE384yHlIv$$&t7z()B?f!Vr?uf1A5$%lPymww)3zJWFq_Pr~)Zmc)A!n)AfL3iaiU z9aa=G+mokbSQ_0*W{5sUU;5(Uy2eZwuhVj1=}io}ep2epbma4j?TwO&E3&f{TR2Je zMfE5#iz*9(fG1ZDo}d8Aa)G4R7%1A7r(&$r32@f!h|0!oITg(Yl15=?5^Q4g8nh<| z(UFy*iGBu5N-y9!MI*2}p^?Q-mV8lTOm16T41ycmhfhxDb~)n_nn4oZqte z)o+w{v|0;C4$H;`!fWw{|M<2Jo_4(xkKCE_mrlU?fOi;Sc76iva?Qs`aBWcQ$Po zI4@4uOh}op>C~Cjo$0LHzLca)o33gY?Q#3e2rtf@V8jfjwr9IU-MTRc1cpAQ6yW7r z;{v8PVe-K#MoR#>e@8v<&#%Pd3CNVA_iyAFIn4B2{WvNV7&++unqU(I@O_7DN5ykJxP!^fsHJ7rfTdbO+B#ltTUuTC1aE4~+r zB{am_Crsbt$N2tk84E2^jG0vPRB4%PyNoL}E%i|sa?;BgbDQh{*u`px`uSou6 zafDVy>T!z`@X04Yjk%wd!{E=+9CN)_g1m{iM(NSyHy^HEZd4Rx5@bUYq>Gi3KT9bPnFCfHEWoBL+Jr^Bk~{V1$kZLn9xLi;^)LNrw)ruI_N#>{zzF zLaDy7+KAAW8Q+7g(d+*Z9<5#7Gwd6~)PF$4o_zkNB)wx4Ew z@O|$-^eGeYy1?~GMR>(QhQb2mf_+ebb)`Z)Ls$*^j~UpC?-uuelja-9QX)&$kZ@LD z*wO{z1k-zjXy_IPf%_*0v|Oat%P^59)eekX$#7!t!iJjFik#AFk<*DS)nqWu4XUh| zJFLiZA;|vw8l03olc>ypSqJ~*0|&l31*0`6F`~l3BaoR|77uW7rZQS`J}}X&(|A{+ zt&BOk4{6Ac9dHLfn52p@!jJ>-xD;3gmRh#*>J$r^2{$-G610*Y(CFiqC80rM9^c7> z-R3Q&XyBaFIGuQ?D6e z*a3=A#%XzvHPG3YAJJcBLU5_Yy(@ZsgsQFg@;=>g(7{C-Bb!?d?cRqoBXrf(blE&O zU)v4s>V~;Ca_4{TEbZ@GW!H9U9fH4G$_uLt7h9;Z1j-$XB~og+V3Bjx+N2byV?>QL z3ELf`2X^P{+M5;`p<;erp`0LPyv88%^A~du){|K<4vqdPN)Bhmd-1r?N;5& z;<2&k>$D{^PCnZLSn;d2r_LGU;Y1Rk4ZS)C@Y<9cR2kcuP$jXy=V(ZKiyd0y9x+d@ z*;TPsUt2IM2{EA`g995Lb%VW4$JzSY#cJCfa|Z;%z$tLTJ)FsFcsYYUbTO4*`2h%x zgIT!7GQ9X(qa}ng##hc@`D3X{oW%EBJRGd-V*`OOi04J^#od#=`Q62y=Em~wkx;K; z1B$rDsv0T4bW#EFOmuPi_OK4jE@a7&kU+ZB7w5Uq z0wj(cq9xl%agspQtc8z&yNa{xilTlt#pEcp`aIR~e1qhf4b>2J@)VC-R$uz@D-0d2 z%1vgtjs(XPi)JK z!_mXd#`8fZ@A@!5bOf?9V1SBsqqbXi!(&V7flqkb?0yj!(j9`P;d)5>{n>!-8l|7Y zTa2z!9M~4j{jEjyj4hL9K#qck{!$v*pWJCd+v#B3kGKy3E;XW2_FNTnIt@zscwu!W zuCiE@=X*4?v$51}X#JjG4opF6m81BoLpB^nz`#)aS7=fJaed=o8-S&~-FZ_3Ycl1% zRLZkd$~BxAM1bSq()}{3XmJNaf{jBAE`u_wEbetw+m(enGd3a|MB^iUAy$Oh0xbf6 zru_z%1RiVGqAc1Lv3<+idPRlES%kqdRPGL51Q=vW7^^vDMmANl>!f>zsv<1A_`J@( zT81#=n@3Lpi>>Rwc!^#^yMm&tTK4qLGgZZWzNOFRQoW_KIL{4TW$N~DM9R@dwKjdH zG#cGxv$tFJWlpt4`?cC))R#^6)uc(K-uy&jE9t>bsJYzYJ0Jv;l(NZK=8$hdy7gBy`&{*7IIpxcnrc)W{wo>&*MG@mM&Gm{l_hkv(X++6H$`ND0tb2Rk9s*q%kk%g8I>^w9_#o2pjE)G7 z+!D94TB3I{FbU9{r^R&4-B{}n5&{)lwUVa8^=My`SLa6>icj(udZUu7=aSbH2#(;< zU0ExzVX!ySCrr@|d=Q!pT6d7yh<6z|$CQ*BHt640w4O+1-^O=*`pb-LDPeQn%r%GX zsOp9RAVrSi2nG!ga-g3~_ht%Bw8DpKby#rWe^Mi(xf@W=X zeu^vJT^p5KDW*ueyEM5#t*`mbxe{?^9c%Q(iH-M^!yMZ+As#xfagtwS&Byw_e_;wP zQ`R*#Jj+ZpM~&FayCJ3t@&cUd!vRA8KqrVc?gToS^V<%4`@A%RY8e zV4LX^y~OEU`~K3HQ6F@!&$Q(nd&V)+U=XEvzQsV&iK46>dUbQd;vYX`vd+jAxLZ9KdNfb(X| z&RCPdX9_cINu_J-mYMF#EH$U&bw1Oina%QQ@i%{ahrOEv;X@&CJx}*2*UsG>YZSVF z@WJ0AXz0Ml*rG>Gd^1+3;`LYZLR_Ra_ZZec^I7Ec*5ou)yR0lPbK%DOPH%!EvxeR%>X8piXE9B1Hgg@uljK@Cs@vq5#J&<1#T`R%n9S%eg2AzWV!~$y zD!-x6M|o71GusJABYe*|^LD^_8(O0y4yZHFX?W*ckiF#_yk;h!>|6K-CWvqiM2bcc z!{ahzB5F+z)Bt7UYYW{0EZr{{OO#nod1Y@qr#sxEYf~pkdEpuoj`n!mqn^Z{0aBI2!l5f`mD#?)nQ&FQbD+37y#cz2&I9{vishf4bhw-cTBtnmwZ`B1`%=u z0;Z)NA>glADYv3rgIy~lSwy)*I-Qo0$%0wfMKDC~V5F(c9%kq%NpI@_xBSHYD|P zPN3G>tj=J#pkZzaJ!7b!u}8huesz<6brB5bHjP^*?T#R~j7RO@@?ZB{?doTaOD zulpjUfK2O29`=Kl4WUlTJlR{$CqO#uYUcU)RVC75uE-Sw?X@?%m0e^;=6k#C;?mj& z8ymLK+>rb=%P)r=hG-el>3Yc9BU?%@O!*g?w{xV=%Qj=(;`sxac=XbSl7^ZKt@DnM(#yQ@YQ@xH9=Vqx&0#yZ^J!;W}kwsnsYi9i-GGeFgtcq&f|?E2B_Y4B z7tchN#lIFbIb~3krtPe%iOg@|GDvG6vNkv5nZS8oZ?b8X>FTMp;40~dhS^e}+?#2S zxMdNLfsrk6Cp!AVxbt^EbB^cGgJW9lnzB%1ruGT4$?zw&)E07Y{~WTAQvOt4KY}v* z-QzmTq8oOvNS4-w2QbkdHhT$pJd1yPbSY4J8`?;D4hM7COHIK=1NT3Z!IAG2-#NrKsYSL&;lgeq= zBqf6F81hwW48pOhnh|8Qaxjv?#uFFMKFNHlrc+1CNxC(aA?t%Nl-_*(xlu%}3QlocKd6m_gIbvB9+slE^kqNZgfaOTunY3UW48Ub*`K>!n}Eb| zW|)e4rmGse5HNmjMk1=rg4M^(`&C5A(bN$V-3$61A|W)kryR`#;^ppkY)mNI2QQR-NUhhK>xHy@Gb>yoya+SV%CD5O2LSua^F z^+dC&MB5s+VWokn?9>XjBcA9LhG$28U1s+;8{XcL3xH+N0aoiw4eSizvbfU`FZw|3 zojx_(+qP~i5s&UaK-v97ZC#~5T68gX!aeFo`n#t@iN;87V+mFc` zD*BPJ6p$>w798Uw#TCNOJtKOcC~_Veb!hxb%opByMunSS>KNr~bRid$xxWxb!v$P~ zQ%+1@D4K&J(<`FtNJ8_2XJE8xX5{@?JL;A{(jvEa&%>7F3Rm2gw_B{Qo;LR0Z5MsX z^&?<{p*N^99WSIK?;O~%gFO8YNrEB@1twbgpX;~+3mMJpsW(9Qc`3ia<~fb9%@`-+_-=!S|LnTGP#^epddn3X zcKVFMb-YmrF0f?#gnj_4vXiH-s8UJ{PeFH(_}ku)ScK5db!7@OX{F&?9Wo zsHR5aSK|6X1{X}QLQEPv?i#eLp|_F9(<9KL3h1F{tlRt|hq@TNy2zkVUAE5>^;haJ zPjC+`p|P}9;*!NsQb<05U!)8-pd)RSHc|0r7#RXLLq9sVtkXLYMA5Man6q2X*PZyF zMgnTCSai|{GHO?fl>vi{q<@YqqW!VJc7BCvuu?7Dvlwo6VB;%Ij##yleBGMZ|=-ZW)hh;By4_%b!2q?7c1V%)tv2OluDu zCTG*J++G$wjXoVTb-Se4{w*vOdQLEFqkmz?TYPDctz1fgaRpFFmzpXgCm17e&0QgN z{7Yi~Syp;O(KrXYb8m_;AgeNIx}$Rh${12`gkL4YVH=7D9)uk_17|LdHJHqepIR8h zJKO>gt4h_qNHii6X_ogI{w7z%=MeUXvqOpqI%ChL6ot)iOQH^4U>)JhiSjTJj*T?; z>SDdVqw)M??^iN*JgaAY)WG-XVtLdktgTWiT4G8WLGvY?@r_wi4RO24`7@(mn#B^b zTvrj$?2s&!{9O@MREIRtFh|P=_#b%Af*Eyl-P8^tm`vclRyARmbzs098<^Ck=&PhT z0L0YUJIutn(_%+hTy0%gsjGwF!53vG4xbC3?su{1&>3jcJaWewx7V3)7Zr)Lz6Wd} zvlF&4Zsz_T@yI{FzSHBcNhvpsc-_Z3&VQ_9@5d6z5tdz};3ov%1TL}%7QJe$?vVm- z1CeRdB%{)ejW11{9A7{^OX_5qkZpA(QNGxPRhlZ<+(Im83325Z@r-KKzd|xXklTA) zUumJAC~(S1C`HCGD+;8b?CA{^&RI8%>W}OXDxxP(@6>HWm+g^^w+J`v`Jfz({XeKj zWY+Jg+e<()D?oF1Kz+}Rz)8tS&C1ifzo}QtuLsXmBF%f!drJWegQWmm|D*3uB2ppS z-^5Fxq%Ws9ad6>CM3M0}j0u}jMNx@O;f=Hmae-772J!sCg7iA~w`8hh8IJg2sDSYj z(u{HliA`6DO*l&}p^6nEF8DZPg&aar5dhH_2Yn+MKs&$?D`5~+M08%j=vMI$>Y!0} ziwU~cG9^;3_pG;0XKB?u7BKqHX9Zkn7M$NT~6MIcQLnLOk8 z`a(92r4!HWUrBrTiykFS^z#3)xc|piI6I^7{(t}k;j05Rp;`)L`rYDuW#F67hq=a)CNWX4D<5UY;&;)Ehmfa)%|- zDD`lO-ii%;>6%kVY5c~*_?}d=!u)}sCXA|XE+xj{H8rFor98-2+DgvY30L8+=`$|Y z1t`vonH=t9bzvQKdL`(XDwGer+2NBY*}BmCXgDgwyz1J_iD#&C>4N0oX`iWplEkYE zWbF;)D~$k-_c;vKvaAv2W5e~4>hzfEvvk((eSwL3hY^T$EkgyeXyb{|rN+YS`4+I} zi-hy1SDbDU+U@i-=jXo`B`oWF_HRNLYbbCT5{XAL&n<@nW~;mzGRnNH%XyZp+2x9p(~onsfo948w8b?Pdj~hx#Q@{1bSZI`i^YqIQw~+}w5-M1to&qN zb@r+erzhh6afocAYdL*qla{9X8hvLDz;B z25_z!=@AyXhoCfxO;RVG#`7_*={ZS&o;Qd5j=P=?hqWrNvKM34aq?IVl^lLl-eI}+Ge(#FxYnvDf3LhE9M=lQ&)y&QWC^|1sJhQgfa_9 zhUv`Lo%iF$K>m&>dJYR5*F$!rbNcp^W0n-y517E3C7V8BwOzZpW#Z08&=ImIJP2JH zICt{~zMMH^z(8KMk!DVfOcP6D80?K#pd0jT9F1wpefUs#NX z*wI~7ug<8K^5UoBYlSjzr<*E;duQDy4-0pL?d|au>yEw7oAo$rgxHpJ$2-(od2%sD zwrzX0FgI_aNVz^Ugps%B+t&+93jjaU)EEuvq_q|7BSRr*ct>(?n2l}~y_*u+x`vsV+iCI^M!u>4`%_sD3 zUIxikq**p5yCUi_m@6!B5La(yFJr)N+V#4bztLwt^Xu~NFgjQ1P=3f^Jd>>c(?1mU z+|6n+m)fkc(!A8_S`_q!7T7}_v(b&E*Ip@_;xUmo*iZ#%aQn&-l)q57UaZA=tP=BY zF0HzQ5A2cL9e}13F$SSbAIfqPF+5qY}VUi9^$@wf%EF;uXclHzqkwPX17vz516^@2}#tQhD^#c?U+w!EB8LE>vV zhvOyEAzKJ|qYL!4?R^=G+Qok4dFPu!x{0!Dv@d6LmtG0(7&_AV@yRwB$c2B0{X&a~ zgD(876qniLcu4I%Gq7{o6!~f&_+8FWZ!Gdp`why$_=^{~lYB9bQoLNe@Nc~L*v~-@ zxRP!h-t&V|5T+F0v;h0^Ef%~G*3Hk#1?m=fxn}~@I_r2LyxArL0_%JrKCo!eNH;oL z+{phH;LU3=FOtv?bO_NiwkbTj4vQd{G&Dz_)@bfDRn+^+F1{yQ&uX+b)C12`^wMu5 zgwExx|B|&GuA5LC{JUBuV0@Kf3ST(NbFpCL9Bf2u-O^$!2-$&icW^f5BDUGdUdpqtBJ^X3R7Pw%eOpBP6FUZy z)W%E~E`#cVd_UsKm{Ov}vAm+qw)5#Yj z%XLt0_jMUxnwHim%|YvJo6t|Ukl3Y@N!3@wTaL#@%!rzJ#El1GQ z^=Txr9ACj(mi}x0LM}UrawitEg&#<+DnmZ}NK`It+ zU+{ra7O$f=BU9g4NI$cZEIlarYI>9|jLmoLlq4`qiL}Y*1vc>t$_D>u9F* zTa9(Xtb&x6nC6K%oFXHbf>}jDDuHghre)L8%{yXyW#h`Iv$|2+#IYlK<3_^MrE}OW ze(S7d+xKPDHh(*1?Mn2STYd9F$GUZl-=%ZXF1Kk@{ObG5?IU2@ch?Sa^J)>`=G|xa zW7#^pafNvG{BPY5vi-ebr{BD}dWoK1Vz;_^<=KHZDH@mCuJQ2g_mZG^0~lOfa)R8i zQ)JICMYT`OLqy0T59*b{b>ln6A(U^Uq_^#P(n58EQ#c3K44yP0m?FD8D-xYMvQ&xq zz?_7%wL2RHf z-sh*a6+wzD=$kEx)Uji+G`WG!=mX7Z{0vy@*_0-Y?aXhTJ0l{(fTHKIJ3 z7x8kqejkb#-CJHCr?tx7;Ma*AySZ<6HZD1>XvJ`vB?}AeBBplc6eR)>7NUSN3eP<= za%#`9Wf|rkiDem}L$lQ3<{BJcB{LF-jWyXdRa}mN=n((4O*k9_WfyQb$}alK;0Oxj;s*ZHfe_e*f&i5tf# z;CsZ}j?{VMe}{Bc}X8xW=rk{xK6TG%B($peUTe|9)P2iWe*CXya#E`8V3F ziVaJ=j<7=5ZeSG>06*h0PN3k9Whd0MC(sPH z`MR)-737eAgAntEEVeN>3jz3z@y`>!)-MOhE=WuFXe7q_>oc-JN5LV2yQjrAKiVc< zEXEBtfVdBEtM7Wn?&sH|gehfD>hjukjfA zIF0KCgFBauzH$4c;a+DS& z0DKZb0eKBFu5b=S4hd%nuPd**1Kj$FBU_o11ZVuIKaAiEF+Y|{u^)Npl_hsgV@Xa+ zJzunZ{lCNM=334OQUYQUeh!edF7PdyQ=B~b@$k9q1@4?+k1Im-8T_Hf&_rg4L`Zkf=tDRGH*wej-s1vhFqYmL5yKt)+@P=p=#9qO=mk== zRUqv5u|dxZO$zbai*!3nf*ns(yH=jgQ^=8RCxqMhIl*;&APIgk8NEX7ZxBV^i6x8L zteL)r3~nH5_^^--Krr!R8p)ASs$B|6<%l*(jPbLj+EI+*f9BrPa_yNsF% z57OD7yAcxp#YDD0>qY0&8J_D$crR;a9XFi$zOknSbqfULY2RS9Kbo-1hSk|9rq{RK z0Sz~3-OvAZS|a8VO`9zBcM8lIPe}BtJ3!R~nTX6Dc~DaDTw{P@pmXO_HP>$|uE?5g z_&y4$+ua_d2t|BOu*joN0#x6rm{{LaH?sM@R%ZAtCRbCjZm(w?{PxY`M7kvf4F(1f z$E8L=eEJ)CPRf%Pc)D-BAelxja?S5Lh5^PXfD`ONh94Oy&uwAmd9U8jC7UIysoR{T0wweIa4BQsuHwjXhFWHxwUYqD z8NVqdUOc>PY(^S)7lD}qp<&QKTR`f~tKd4QoHNvu0IWTxe=AC(W(1pke~~6?O@W-g z``&988Gp@ym;lR{0VMn*P-CPxv0VW3%=@zqr0t{L=QDbbG|ci2#<;1LP_ z3BREgl+h`rA#PKnP8d<3Gy3_C*kC`#P0>Xrj;9Of4x^&j0F%vW@o~+<79yTP?~@NQ z#-;tpqBaw|7Ae}3Xk$*ne~zw8eQrnC#V0;O@j2ktt-y-ZW>|wbf+IsW4KQSdEdS;h=7WoA1buFlGlEd!Tk`#*BPpK9A{4&;Y{x zOhbw7ex(j%0QqB0-fZ;;xSqJdE^vFie`uv6>Ykj_+fonu7biA>i3bmX+yPMDT*Uiw zBhoP9!(U9eUC4XWrO|Qq_$ovbfudbf;-y|mi00>Ks3ncAzAC?SfBz|BA-m3FX#-Y) zI{k#Hg*b|A1LE4oRv@eU>TE|+!6IIp_F*pr8fm)c0<4jYVJr-LB|Gg1o!)9G7{5tz zPj95whH7el3=ldYT`<-*lB^i&*^5^V`qbdnBRoLx7~zSbmq%kRy={aE_S1x$qwIjk z^;LQ*NuCOV>WhA>!+T)^R#ryb^kA@#yLk5S1b|e_rr%;wKYy{yX0;~mhMr3WkU#6P zP9PC80^mOe-N#wLBw=E%hFu>2lzBFebW7I^5TSmU65yG5!rr0XkTlQ_E{?AB2)7mQ zg+C`jd)Z?R60ktTud#u_qh?!J>)QVWe_L@;x+bWe&HFA1=`FTHuDL%U3u!QLA*z_| z&!IS6%+O|e6+rCZeB;P0Cw@2X;>m<&B;M}lfwJhOo^`*Or49G z23-Dixll|`0xDIy5hBXvzE&t^Ff2Uy1*Ue~9*ogk};LU1hThlV~|jeYN*B3Sf9VpMuQ# zewhyCm+No(n+vEl{k!a08=&>FoeFRdj~Nky_Ih9?OF3FpNkkAsbHU-bFklU~+bcs5 zdpM)sA?**F8I&~AC{Cge86Fl)CPL%`M55%$NDZWL1i}!0WWi@viOG_B5FrTYMeN`GeajHHr%&47D-r;}V$RI~y3ffl z$Rpg7UWy79=RjsdyFDZe&v5iN$fH$cA!1}_B*MbPD3c(Mh^VPbM@=IolNR&@Vg(BKt}P~)%(wf;?Wua9t{a#G5@ShgNPA4H~Gzv+Ojjg69$4u@k1jptxB{T&f$$&tM#R$375PblsV3G9Dq42IqYg?fyQ9JT_Iefio*lx zhC5gLO*Q_?V9pyUu&^7%GUROXV?QjS`Nf}-kGT$E^>20%yM|y3uMyk_%!67rK+Ks0 z5Jb$U8S_OsKjylz_6mDh@0(GZ5Pf; zkKkh)dofGYbYmT@cw!Z;^vDchAf)GS*SFizLGVpu7cF1`O&?W?I{&ZS1Ic@tjr{ep7AXccFK%58OpVYe#BN zX811p0kHkIwaRi{xvBT$2`5aDplczw+(@FkfccNjP%(1Bw(Rni-_%6LYkM+C)Zc0ku^t@tjgvmBiKgdDYP6*vq0RE=3-DbjoYYTd4{tW4W*pr04 zLN{dEZu_-3o{B#y>MwdlG@$wPD{lb`sTz(rNv{;3uC^d-1s=t^j0xu(G~1CZDweg6 zU{RI`WlER)_-2hDXvJT$MRU0XxB;-VTqB2T&`n36_dMCUM%@UG!4$h24c=u!sNYcE zSA)Hyw>Ni!*mL@T=HL2cnl2u32qA;{(V#9CKqP}`c`S%Go;qw! z=15eGuMcGrACBsXgKWGJ9~+^Iykbb-$i(BoTEnq}lsS1%pQO5dpf1pef4!l#3r?^I&4p!5Qw^d?*+yLF)gdkvov zmg;8o+J<~711D1GpArOE2_QEpneVOGm!;TPK4bVkBAF#@-dTJ+ghr;O!3)4%TkqHO z$5D)zrc&Z6?U;Uq-`py1v;i|5ak##aRz5Lu`=^#%01W?gZx{MrKbJRAkJVHQSU|4U zYv|H&tpW$&$0A9}+ll&W{+F5TbgSyd;HERRs4fN^nk>lA`*i)vj76Xgl zX-L*oA>;%_j5%&eY1B8P1mJIJIRVRGdrUU3F&3pTtzuN%6==E2^@Ik=0W~fwg)MB- zX%;ze1>C@c-#@?T@R8~8<8wiBke;HMd;gU`3j;(j zAF8$iCUfUWec@~FG0K)>L0Ec4JfFB_Zq)mxal-yFI@P|}wvO%Ny1vkhmv7D_zxlc+ z0Qrco1iT?X!A9q{dP6t2+`g%WpZpVLh;7jVN7cMTn}*h!CKDXg!>!biyZKpN;_a;0 zDJ-DG_B9&kcw&Tn2XCZ1ghSV%T8bZbpW z{V`bO!Ok)0^hGbVVX?>;aVL25ywxiJigRptT+^%vyUF^z*UAQLR73QAtD1qa>>0%O z&?Z9xVs<*3NKFC^{U>>az()ZRv7THrkY>GmN&+nETq#xHXvJVu6*5-!WTj~8!eJ{o z-Lilt$z)}v=wcq#uxoX+M_0CZ-{O+F-X)di@^fC<>7#Tj^jYP`c1=~s$c#Zi=Q357 z`t)h(Qu$|7#j$-k_-Bk(kw$h&N!g-mb%k=}vQx8Sc799#c8yv^RfT%4O68L6Us~5v zD}@(>AyBL6_b#g?gnd+}a_4wxnK~z`r?{(MRw`OJ+`obzZkG9#^-IxxZ3sJEP|&<#ZKj z-gdt(FZbxOBxl~hC0dcSs^7zC64Wlwr=yfJbBx!luTrSW)ZNzf?i6@Cm)v5+57rk4 z4=E59LfLA%{9v00f(_pQR9#VA<*vkoqmaD!i?7!nB0c`N>1p0i!B6V(tC_NI`|s0P zgN<#Dk=|9^^f24DZ>67cE%R} zJQx3ts0>w#=1MqQb?tMr=IG}NJMOZY0`p}zFZe5*zu5299Vy=xHHUE<;}qrpDxzJq zt6d$KT5;5>aNI(;qEIYNXDPN4Dz_znEM0x(bp#S9=FXROfiJuBNCi}hZMtcN5z9xE zX2xG!FAOiHFIkcRo^X%a(3Kc|6V)k`JXx2OQk?CkvBT94gzu{=3_l)H z0RsW;r{X!o;HB!@BEqJcxWHfooR0dKpu$uH!OCzs+r!a{HQbWh!oIN~`Tb&rsuIhD zpnPsURvURbAKsq6f%kC55v<@wCuPKmXO)vZyr@)&yKlX`?j@**$T+y2=L|6EUuj-Q zDOR?9h=>R0CWG(VlbrFp8CkdXTt*o4j+85mtlWDO3QU5rTxX^-^3Ndv;MD>ck`+R9 ztKn*JuB+tY*N?3e!PD-+5gbbm3#$`ns%qc10SK{&SkU1dm5)A_krYAw0)Gg~sFBsn zvm0f#b2YK~>_zSDTJsuv--eg29_;2=&Sg`}D3=#CE!|9~deG z_&>}NtW+IaL|lMvT)o^N|UOa-kaQ62B6e5QOsW_+UC-B85=6;+YRL|&kl|J-U-Oo)mj(m zQWrwWwMZdBcVbs6CCPIy!y%I?zfg6SLl|Y$AIt~vGcf?+<+Fo$ohbrPjV@oUcN3tB zmb(!fjQhOPwGTfEJ(pDPGk)2PF~0;h+|}7mCb zFx_CQhirw@p4SkdjUd0l8vKBWK8cB=xVOc(&Vdu;5Wl)_#gQR7N7@#lOA44itDxlu zkNyjvh46oimfGce45ePW!DIqr9$UQqSSYcgL_3A=JUAO%1zi|X*Ef3eihGD~;28M~ zByasv1^dVQulm8i1g93aT%F2z`unudVuDbtF~b_T@HG1fwS^EQAl|xl=R@{t6s8EE z-JU|dFzcp+W)tIbLu$i=1Hu&$_hHCTk!mbd)>r1Jf^rD+N#S*IV*Yv33n?ViWX?cD zUQjyNP!Y*kohpKqgia6?F)obeB?|bO5*ZiCrWC+Lh4OP+<_wTi;rTh2KtmE zw1IDnI*O%06WSWvi$Q=vRNVvV6opNFpzW|=-QCEGJE%g5C^GsWGK6OM+)RcA>k5i_ zU+WT*ReF#VCo)%1*^mMp);xZcEj*bD0voruqy{ieylnrqh=(_nwnpq=q%j6#1?1KH zsstx?O#Zv-dWRtGw93;mvK3U~HXmwaFmX_UNpBE$!A3-Af+WD246H1@syhGdx2y|g zLf+CLDXYTBrQMNu75N5%YPVg&T$WS~JUsb3rDt}Knp6sPI~`JlOXvsmJiQ?wkrRY5 zB~ZMGaTA5eIS#2!(PNi~zKggvF}DU^l7t9J&<3p`?0h1Ddjdz0_obU$oCEPbj8a>3 z{_P6C=)ELzKoDR`l88get2GE;O8lVUE-rdaBuo!lJ3rRn-I|tj4dYtuWZGto^@X(q z>+lI)id`x`MA!hKl+rKL8XWU~ z#;SBB^t8ls+-Bs&U+%3+t7yeXM9`a5T=v$z*uWUQ?oxm?QOZ~`#SKejxzeVp>aUtC zb16>g)osqDT&RnV*%Su^GU@Egs83Ji848hlu_(JYA!vOE43~^vjRCR@t>8J+Fosmg zS7MzQDbn%Ozq+sTEN1^4I!c(s=`>_M&^=L0?(I@ZQJG&f$UPMrzvS*ym1^Vb#On>b zIhzLM$SVLnnO|s_NTSthi|Hf&JtBEeCKiT?h4FbZ_uWIlnU%skAjbLhC3mx$%*uXND6B}W4pCm|;*GZoLz6&cOZ z-zCq%L0>UJJW$pu>dUy|(C(6LnaEQeD<>sx1)l(X=ojQ;Pom<=#2}Pl66EVZP|iE! ze7t=LM9Xo<;p|<1CvtIMn+QRUvdML73t&vRhs+s1z(1J*Wwpz>1*QjI1+Xflx1cq*~lOUri&%BteVn?0*4VK%>90 zofoGWq@LwTmalA0tG}wYv#zzO(O8}28!qpR$zcROUQB`v! zD<5T=llFnlm24h49A0hd$@H=Xk}Y&6lG$a8C0kOy9Uxck9iKw$j9KE4d#wc`*WK}ePMu`+ zY%MuM+d_$MbOff175b_{)Xs^OS?pMLoQE|?)<_JPG)_M9EQy8Mje3$bOV*;A7z~mZ zMy<9=)~2+`pxfbM>m}=OamC^5M#(lQf0wu|&{W^x*Q4jJrA}>;?0C}mg~;6ml2I3q z#qBX9?1_?fDr?ZKyn2@zV?oKfl&dsKta~I2F?69P^ri$sPp!qsJa3sJ3{SE?$-+t) zNJDOo(cDr*8#QMEWFx=&B^zK7(naxxXmn7`UR;@|nKvleDU4(crMM-$Gt}SKe;w=( zDSRE_6Os)vv@SV4vEUA8au>T5o}={`+bP*DWwGPCBHh)t!ln|`)zc(X-cO#(`?FOM zJ5#c=v_XsL5@d(j*^-^3W=vAgHwKzI>jDk!Hj~bi?0j|s(vFIyB}j})gkoVF<1%NW zd_l5{(rc)y*EJCO63H$lbY2p@f1$OirL&DtUzF_fu_!f>uaxXd$}X&LY75ji`D;6? zH?{kTqN^nP3i~RG6jG$LG!51?hgmMS$Yq?_HInUN*QRp@$AZ=$0UE#SB)gv7fa4d8 z#e%zPqJz5_98oq_|7WrYMAc1_-Ao>lTB){2n}W28sX`-3NOYH??Caz{e{9L@|5B#g zCELrsfj#cV#@nNg9Ly*i)3Z^Y2m6*}%9k>$8~jabvV2FfJ4h#Zw6dqPyCl0?O_6wT z`>5G-k7W0f^vZC&&RHyGvk`WmhaHgYe)iq8HF$d;PO=^%)n0EU;}goC(c+^&nYU&+6w1y(aHsY~)ifkWl|3WbPn5{TLZ>u2 zzA6dFbCUg(J&!pD!Vzs!161A5BzuwCoQ7?-;7knlxEBh#U8?#Qf08M$X+o=i-FozV zP@J{(3beOTO~01xH$<336`|^=4ky&~d`U9pNli?ZbWEEr`#Z^ArLuWgRyR$h3H5u) zUMCfoLq3$_Z!-3#WPc!KkdMm1Wd>E5KT7sC`xApwTazkksvugwH07(t)WOye<-G_qYnICvVW)rX)B7RzcrdK6mD=RLhW2gaKgH2gKmh2PuDH<-9Vs|${)I0i=gXE0ZSG+ygAMPRB zkt&6xa3Q%tq#WilADw}wn&!rq27fzhyY&t2fwn4&WpRspe>~hPc^1!3n=x&>;)&1z zN>C`4TD##)Zb1hO2Mswru+q!X@*R%;Pa+%{LIdL45l-~^2AsZ8lAg{z**uTudw7B5 zg}ex9&rl!sa*$&ED4->7O@?T!%GO(ag5)Kn6eLMVY7NEsB*`b!GJaBWxmp{Jp}GsW z)|7mz-s* zqI+02u2QFRM@U{qrhtr7+fbLb281b>yn;kBuP20_N+@aYaB;}zp}PbJDANMT7ZRQM z38jAm@fus55pJ>MOQ?b(yMj@ZgfEl4lF-FAdbHH@f8~-Nm2y%SFHKHb5@o(p@>L|C z#Ti7I3a^p;XqShZS{f6wO7iM74>uiME4g1StL?HRrOi! zE)#a~Qo=S$-lU9mvf%*E=Z%X9)gt-2v8d&QYLmQuEJ{__A^8S-FRq`29*2lhH%Y!( z5s~x>e_H)D?N#Ir683n>Pv9rwh3lud@EUIF*uZsbd;HvU6$-l@iM;nI=C*2#O2j{e= ze`RG^24VskR9c2?UVbI6uCvjM^Dj$&75@qj?#WTI<40wxHAAIilZbm)OMVS;uS78y z^}|*-|EOEnO8zzK*5p*TDBA#P7&{YHbG_s@D5s;t--;sE*|xT-R@p~>ljJw^TWBX& z*P#VuMpXid?rI>T5>~t5 z{D9>5D<8oj9I;;h09KOxmO$CQC;3B4m#A#*DqUrK80R#mH3kQ%tshGM2(?v&e{HRg zgnOg00e54MN&a}Mx3-rT!wgjPN0L8DYCRi0nd+1_e@b$-(Uzl%)Q6%S)y~kYzu7mH`jI6H8fW#t^Ethm4BGi)?U>f zsOhAQ6sqUflK+PPmg-S;)CLnlf3=A|)*#wzG5)gTukhcY=|@WK+!Iq->-wWX*NTI` zCi(CA>!?N2O}r}`X&Cp4WpoX1O8y7ZOZnQrOv(Y_{wVp|YE6-JY1?t#PKZBC{ukxq zClMQB;Y5fwI;aPKll<>W;dTW48(NxMY2SvwBl)|@-B|QMLR&+z?UeqWf8_rnODbto zo1ATO8wl}l$v;qz#!x&dvy}Xip0JkV~Xk>TWir zDF|CB#gR&HYpkslh)G9Dv4ZAAp`H^dqNv;|+LlHUy;-c0;%IWPy~)`}g{!2fCQmp! zXS_xlgPf__gDe7s0=cwI5?LwpE1h6(+a*mUt!Sxx!@!}{~6V@Y|?R{nXaw^tI z(Mq3|a^vphUAAZ!f9pM>gDAW_xw=UI(nMJ{(lpsb3TfPLS7M74$16Ui`F~XUM53kB zrlp#)2BqjypPQ-!^_{p_M9CF!5Dp6b2lxXZ07GcWMV}O5aWZm&zDL_OFg|L(<}+M^ zY|$?UJR%}RRNw$eoAyv*!TMJ8sj|t7N-m+CuBlxYbQ1Mie~pNU5fRvId0ECRnOgRU zA=hFp(CpvYjl)Pb5=q)2#ZGdcXtTR6+#f2!4xcK;Y2tLGV<5OKgtH3eWCN}WolSD} z$>=|ES+d2M;w+EYEydZiV4N~$Pq*IrESyW9sU6CSaAZy;(L7Iz^NHsL#B=SRC6&Fn zP>L@QvWSq5f0yH+FD5j0ZKftxGduI>VE)UftxG6$xfE9j^x!6Uqe=;eBXR9i+NKJf zZ}NyT)G}wYN1$9!N-Y9nXf<{&XbC1zUq(FQE9vWVRf-zCT8eALo-}7P-7)US)SONl z+tA8Po@=IV7XcSvqtU*O1UZwBm%+CcH!!FuJ9^cje_IyLJF05l=FZ@}Q%{&vHakA2 z?C7+#(~pmrA73`dD{ex?v>lfZSp4*$((Xg3dBj!X7AbBOxbm^c8U+*N9*^72wC&GK zvi2o$yA*rHH&B?nqXUECe)}uiczw#iHm~@W?ZwbC$Sd~IK4|8Cu17{Ve?v>0P|Z*mR(qHFgx^U5tG4sKVm|{Oj(Ekrs0ccHQ|TkPM)ZZ^#Hj;P+%LXM zR`8UeV1Inn?n;s^o4w*e2GgQL3Ex1dCpEvK}#iK|Imhy_n(R$3>t`}fP*^i`ne^UGyOQP2q+DXTQGH(0?DDTr!JR^RB z6~~9V;tBh6<3!ro%sigYN%2#G>i`eRMt2{19826)*YpKrZO9KaBB2bU+GrQTntmo; z^oXBJ@e8HZ#>uDb-(Y{RJ5<%*?-jqoFDAm~CX+iZAh2D|kU2*{>4sEczFO}szDgH%ebNa)PZ7J_n{9B3- zh)#>rLp@&c5$eU7=um%;FA`1oDAhM;e`jCeqXM5u@hMSQsJ0ChB1NJB(qM`qHi;>h z$q>>|Tb_C3JOq^YSk=CsHk%Dg8Xm)Id*U|5;q7XbF#hKWBU>6dYIV~PXgbbSSFSYj zs4kfzFHCN|Q6P;%+UB2#!qC0VwfEMR2quPTNoEvFV}f$~+`F>LJz2^yQ5usde?y5o z!+LZ+>HKjUFh-dQheSKjcxM< zkIV{ z&YvCe8l_00YoFRTgbnwGBWjD+f0!MU{4PaXzp5uaxqr4Q67?q0%@^of#Qt zH#@bP=rv{`Y2gS>3X%_>Ev5tZmtEsIMwX(;c0#yAz#HMcfawPP(yf6#An)nXe! zRmC!CRDRapzdG<>Cwq@ggw9e;=sM25G1R1)dInD-9q`^=4_bkc!GuAFq@XCayACrO`&N zuz@K9l(1eJ9h8uhK<%{y7ns3#$ZKrGa`v95ZJLeE(%51guQa*sEixz_-%M?$A}30t zllC*Meyk_aM@d04jc<94ZU)Rp2_b3pl6Pyy2m8YbuhEBy`CbE4fB5n9vyFaZz+*(D z5hdH}Im<6NRM#}gF{j|nuZ3tLa{m}aH+KbvL!B!gfV2R#`@$&Dy@~~ zY@w|_V}~?$s&f_ojqT2CI2G3xovvZ;j4Ey5HPF=Nb=unoowmL78fW4PQAc#XxYyW? z^s7W1hfbn!D7Y2*e|!!aIpv+u9My%0%JZagKJDZf;kX~$zYuLnr}nQpBZEqWyi7X77zSdui;Q6+gciZ&y0J!|Zf#&_(m+(9}4Xxu4{yX;L# zd$&>@z!2@mereo8+X8v%+lJZ3urcB>?vus=<9_$iP}&h_j;YP-oQOIXp<@$A?;EJ} zmDI)q(s9gOcw<6(7Te|?)jf4#fP^Z21O9-%HwPVYk6_J;A8 z{(w;h+h#!zb2iwr8+Rqfnmz`TM1uBO87~} z%aV5+f3MJCCMr>F`(v+4<2Cm-blY0mX2o)^OXCgWP5Q2dYhJV#88j=K(V^kl)4=2B@cqbWQg+S?oNj)g)IR}SLxkWx^`hgzdDoAhaPsBzp1Jk7fLoMr|xtjLza%it^e?u@9 zQM*@9nnz3X7`7E;zH&(Q9sDaJubB`J%l(ZT->XMZ6kB$MdBzQzMQ} zV9$;qW-7ylSPw2>L$Nvk^F>^?ag%w11P?DFCU;8nByQO)y`V2D~NheRtbESEn z`UqXuu)b|=5?|B2UY&+9e=m^cg?3>&)Y{xcByCg<4`DBo=EY9cW3ZP>^D;WlT|#AR zh||Y52b$VCH~5Kg%5k|guTUJJ@~#{W{-*l&wUpya()_X_kLpk#iEEl$HmN3zqtAM1 z2j%&yG_R(1ird;-n~x)JrLCo*s>ZKR^q703c`Xh2x(^f58ClE26!nOxH>C zddf6uRHoJtErW2?XWmHOPI3>CHXIlGk{{?-dd-{1Vv}Fq5qm2d9=#c9<7h3>p2FXT zN@aUA+~XU-#!yq8<~8>+nCSjrdlpUCy#(qjP-==lT}S!P4Kv+I?wNVqRD4 z-^SI}8D8@{3~FbFe|vjEy*`|U{KSS12aOk;``4d~~80xV~b$f~uD0VUk{VAs>`FX!F&}Lx+SaiL``Z;mPRvz_ zLDKG6olZoWdqUeo{n#wl#Nd#$6+vfHb9>TZe@l*Bu9_l&TFg`L-D zl`GcihzqSP{q>!V%^m*sW*un=G^HZz)>qY1B!?n3>#GAb6w6YvhUPXuoh+(qAZWC= zu16qnkxKV%H?wl0Y)}y;q)l`EO)wJ2)iaaYwOKz^MRri%Ji9F}dx`wKHEL!hx z^0!v0&mQEJcdk{8^3+we(S>3prHOoCe+*>RlAl>q)rt*T9sZ_T5`oEN>8SRGs;2t& zwCAXI$gv8&M~RuL8Uj^q$Ojr{q^Fj|3iJD2s221;+m(BnL}jP$nUL9cT^+$;tEt(* zfYZ+ee}i&3JKZN4(YUk(Hu@VnTdHb~bJB`jj(AmjduyPYYOdYXRMn_YE~;~kf5_R! zQ88jR#$4NuSTOndqOFR^wNwwV!fe$`b!v?yiXsio%@{T*Of5P`+v=*2Pg%(*qOxk% zH{cAaA_2@(_r*J_nrb`gDmgkOEzJ#^>YJN7o9pV@{Oxp64JEu_eUs`WGP1sj7=a~6 zCph=ps&mK#I$`HdiM76$~l(ETlzTuWF^MD=LtbbA6MWT)?#SWOfUE zH-A-o>iqnoRB&-BxMcJlz*aTy>;%+a#1b6)($PsM@NEI|20J%?CU(swJTCX@3!P}XWmhuB}pY2Mfw$s1SO zTW}8f1VN5=&uc+IO=HjT3k^lBOc19v}d-?r6OLHM+Hl2*0;9$ z6=5zV#Ne>Bc$y|l&Q2VxOqsMrMn#$lYtP)N8BrLn^^a4|9<~{oP)#(i8nE8laVS!1 zkhHC6ZXz3Po1(0?)|#Xp&8lr{Plk&z6W!Zg-`45M;Yy{v>i+$hf4n+1%atR`l|I=X zM7;;q-i+x;u2R+c8kI^hj`RCl$RPXG1_mYsnrg5Tqt;Kr3N%qyu>nd}^PC#?J7KfQ z-$8vwyS<@m6Nhtwvw><|DIp#A)T1d;?6K-~k{3OzWKendRb;5`AokV?R&Ass zArx$-#@cW`t*>rxf32!Px^h)|DsI&V+SgJmc{R;VIPIDo7Nrt2uP3LtIy!GAlrB}| zj8Xx`KW)Kb^>92}c%N5?#uvM58^;tXj^Mjbs!VLF?ukEQQpw!D5$CbaVY zQKtf2nUb2Y0eOofG52$_ISSLZ)kW?rqPB;F@|u>oR&BoFe-Ngnwvu?^2tC_k>gW3)$|d)JnoVxRr6FU*g=B&Lru(J{Y}eZRC-Z5FBf z%xy!l-XIC0O-5m6+3R5qt=*#I?yGpBe9_gTqG4uw?=FO@BtdODbvM&4=#G2ISL6p*X zvV4yIZWd9e4vb)ID`w?gLHdc&&sO^BqN70ee;XcIq2%Rttdb54h3O#{n|6UBh1qvd z=^a#h2bJE@MRP1PFo>r~Mls;eG)ox)VdedsgqIJ1v>;pq-WNHTF&B*iV-J%l2Z zqoX!5C%yxv!oI{tJPkR|G^8C0)^9IR#a2RR@F*^*XQQxd1aa_oQVXt+rRtp*TkP$p ze`@H_0reoA^8^9Sadl!7`GOQNWVJ}p<8k>tu2HKdF6F6|n&`k_G=h?W_BwgNg(kn9 zF+iu9Nx`_v71{R^{R4xEUHaCMecn~y<#y5vy6up2%bO0DB-CMJ%RZ<^C%=2tYf|Ba zmOjtcem$0Szc56Hy=C%d?-nJqR#I(bf9sFM>T$fBved0#tajr<{Mkf58y8V%k&=L& z8*G4j-lY3$8#Uad;RX!}kJ+daf}1p?s#JWDlE#?ABiy9nMxCzkR8JjpSzl^U7p!94 z^coz6^x^3wR$Z`CSUU5S#2SNxTl+n9mCGJ(y3S|cNLI{B?zdCRHrQli)dba8fAw@m zoqBg7`Ba4)Q>|VgNxkcV;<7!6vr@!pbPDXlL+#OHQFyD=mJ^S4(PIu~a||k4~Zozry`E_5;`n z7IMGs;JV&}no|tL=wY7p`!5Vue`Gk&`ybwHrW*pugMqo*)9+eWj=E^`A6IF`QGe3& zP*cah(t-`^K-LRU9!%Jt+n z;wr0%Q#RQh9iWp18fV7)Y_YVzAGGfpBm&}EKCQUEAuYGNE+-+&d(*BXe<`0toi)eC zB0~f8EWlteMzf#xj8a<=o_C&nN?-1x~ ze%28|VrKYMnp^a4B#|AYf5%7o7Lw?p!Jbi1P%bFTc%E!a_2$e6&FBcwI3?`aNM~0m zxynApHg&w*D(~QsJ8vF6)ZiwrG;?8fq>c18>DDkRI);6t^F+nT!)R&8&?aU+(M3GL zp)a&~l2&3-S>_^J+BT1KJdDBgam(0z$yHY;FkN@Hblm(ZH{B?7f91|6)}+xmZJhGz zI2y78yOwWv&Gks z%eWpZwB0WB0pg+l{$PUiV9Pj8>nvBU8XQAM7}X+)v-tohFIW=Andb zJeHT$WV-y4xoTHQx>(=aKNRny`;O@EQNW;ceD-2gjmLKNfBaD9L81}L3a6g(^kN}R zW{x@r(57$H>AO{q8=kAr=L~hF-g3zFx{*3N>|T1>;nWL!NL|)I(!aMaV2!7y^PGIG z$fXd8ZXhsz_MD-JtKzI)x+_7}N&9HW($fL$dlpRat=5_anQT{draUHJGt+HbS z$C8xUH`P_sf4zF~M%_!k*g!t8GUSD0*nq<9KAfpuTcWD$vz-p}^K`0O`>6Nck;Xjt zD+!BK!}i2VLoDu9FB#U2#VqMnuY}cQKrQW6k3-gJTz+~>+ef7=9+R?UOv+M9F$UCX z*i>(6sYT?Fn$PYNmN*_HzItwFsi$V^lpp5p9zq3Ue{Y8jM*DYdjYgWaXO^RUUwU6E z6sCcq=LKC)Cl>02)B{>5adeX>MpLoJowaoAQ-m&wos?F{U0vGakv7ZqV5Ge&xqVau zaiuivX5r{Ln3udeV!K=R%CCJ?oukvJTAaMj#zaXhqz)w{pRQ1MKx59;(&}(TZD3Vo ze)~D&e^V^#-e>Akr@i2*Qm0|<5ofSwoGX(VuTf_5)Qf0~CH*ZO_uDY(7hvsMsx}4s zO`O!*Ba6eS@Df*esVhuV$jR>tFL8xwVq`n-nQTu*7P})$+>xd3h?+c38FyrfJECSw zfsQl=v5PxZW_km3^Z2roUSi4EN|xI5QojP&f0A4zpdwC=Vv+rN5xpAS<9Ph@{+og9 z&}-kcOUsj;l$PYl#X5ZnpJdnl6ie^+v1!D@Nu$#AyD+v53uM&vNf%v<1J&$`hV4n> zaKRHt!s2A$@@#cn6GaUc+^UxDb!vAlx${#uMEbwj6>AIO5=w2{X6e*snyXIOg;%=V zf36`H)qAAJj|**EwoB6Dt}-g!E>q})Q}}F^rgwC*)P7E*+KTj)ZQi^&jdVM`*cD4v zlRxV9Yb@34j^&2qY1o-tL+&T0tDH-&Y07D8x&x3dDtX~}`n#1=)h>1_C9Nv;qK~sk zT!jW%|ACYc{iTd-TiWW>TMS-0#6^u_e^r=W6^LlX+Tk6hY`wFfMbc`nX@Pm(GLLHTGUINhX z7&rx1c)fJMU?{RJ65SEe2UW2Y`bm|kQtFnmb6AjewC4M0zr%TSbUqz+j7K9YeDttE zAcCg1ray=SNZY1|#GU$!CLz(A<35GwdBJ5Cob6ztdWsD?2O zhcw)&;b|J4so~igo~Pl38eXj7WpIpwSLpbcHN0A-XVE8krL4zJ; zrE>I^I>qVlA}N@!VUdO<8ctS_(euYD{tXS|svd*>`ip|wHQc4)=^CD;;W-+fui+Oo zyhOv_=z3q)@OceC(6Cg~Gebd6f4)e?E9`W7Z&1P8H2k)PyEVLD!-q6{Ttm$l`Wr?B z>A^4sXKPrd;UOB%*Km=Be@ityQrEK>mZ*AP;lD#T&3wlE2{7|nqS@RB>RC4dV((un3fBr?ozv}t>Hx2);;XgEdN5gk*NG}7b_&+s#PwTHQ>G;1ieBXwk z^_%%`4L{KELk&OD@M8@>(eP6Z58BWI4Vi9F*KctRg@%TPriPY=9u2)3W@(tMVUC8n ze^#yy>4Lq2jT-LM_&goIO2_jxEYPq}!y*lfHJqSfi4D2te>XkmsnREEI7!3F8n5|i zP0?_whNT)#({Q?mGc-IzL!X9+YIv9)&m>(lHJqi#?QRY4(CM=^JY2&gG%VBkUet7M z*6DLJEZ49?!?_yH({R4#wp?FVgT*e+@6!`Hs?Xg@!9NT&3Y^4cBORw1&s%_HWSe8#=v8!)o1MEvH6O?rJow z)zGhDord)quGKK0;jtPXr(uJJT3)Rt4VyJ=(QuuHts1sz*skGv4Lda4py5UhH))t0 z?=2c0ui*(Ao~U7`h9_wl)cpRoj(2I;tznObAq{&qf845JpN3%#Pu6gohW#2Q=|*Kmi1Nj)p_WJMTn*3D z@O%v~(C|VHzo6y*0S$ks`Kk2<)AOC_dCfF`A<1to_twQ4UZV49z0b8gb1kn->o=Cv zTY7#7e=ToZ%PZG%$hDjbEe~AFA=mQ7wfvcSJ{npt8d~oeT0a?D&lp;77+N0~dR`lP zUK+`Hmz-D0`J(5wb(w}=)G#^Euh8&H4YeJ!zN}$Vzkfx;uWFdoSJ!B`N5gA1{F;W> zX{haprSt-;!4-f9yuhp*F?Kf4%MSp5D!&gzf4LZjEc(f%p91L2HvJTCi@DK|f~Bx=j}T^T>6Zyp&L2VW_}^NdH{ov#rXdUNMi=MXD4zQu555D%Xm%#U zoiH69fy3ZYbjF{B1!!WH!YgnT{1GlkF}#6Ifm>0`zsU}TJK14yFIxupv!mc4whA6$ zN5hZUmGBI@CC{^~;g{?hc$w{i*U@=;f1BNH-Hh!@o8{Im)~x_)IG(VFgSX&ta7^m_ z|IcugR}4d_{9Xt@K^YIgz%ZOrZYmho@q~suG(1(qGc??-;kg=Kpy5RXFCB&}bo{Dv zkAhc|2nZztci<`u*uDRUA}|bpVM=dEFXbuQ_~<@)%O&x1fF(@rq)V(1&H)-3CraGS2H4f9YtfB93d1=H9!)wl^vbKlf`&d^N6xd7}%BLGTX76uc9;K=3YtU|4r!hiyUvnve-7 zgjsta55Xy71a8`kOUo2B7Uf~@xLTiJcTcsBv$p6MhSlzOs@wi^1d*TyuI6W@ zH-8vSA^Ix`pV8dI|6y}WvAJc~T;=C9XFX_rPdE1>W+T0IO2re<`2ak!3EK$W2ah#W zP~cwpkqw?9V}<{o!`Ao13;W^c82J_c`|W;sMg9LZ{Qn5NQDKb0AL-{WRFM8vjKJUb zLQ#dQhGF<;#a#~Vf8{vZz*iy{RzU$@4M*@bP>ZmhS3v_h#OrtsoP-W24(BJse7+5q^8q-954tF;a#4o1Z@CBU ztM3NTunv_u%)&nB)SDJaMuVWoQ@w{$<7 zv7a5fd-tkxA(CQ{3YDTbjIddEj~eR)NInD;_;#4dcfex46Ds*GsOG2Qc%Ke^e77^! zm9W^N6(n^k?CMlD2>CG_%|3)u)J3PTm{OOISdZ#1f8L5^4Qh}2)>b|}sR+o`oIcFT z%4ZIY9`PfA=c3*$wkx4ROA8m*&koAz~FG~cG0_t{N246kt*USl&n>G5P8sg(AQ9ZCPb zwh^1LZ;P&lBM>aT7JTK#2s^S|j<6NwIKx(#e`_HgVMp(UMRwLnt~`iVsEKy*{A8g+ zF*PMRm5_^6-vxO%V~hEIn9T2i>HJ=(;KL~5BXA_Y4_5I5P{;3wM*dxBX)3Q85+WJ?km!X}uaB!bFr#*jGMt*6c}0UUiAN2aYO1eX?|HXK~m})=V>F}6*MY=vzsBB^yMroB}Q|#G{^BMRL zaZn#Y_B@L0c?{X}ILzfwAZvbvta%c({!rj`~^6h z{|qkWFTz#)m+&?IYq*{N2ENU0r+=-@e;Y?g_F2zpA=zjBM9<27*0UHAD)bzN3>Eq* zvfosp=P_g{_Gf|l5!4=Wgq4p&@Iq3a_@AK=Rr?z-mA{Er^euEZ{)j^OCs>N3dldgGRPn#z9Q_Au;P1c|{vLGk zf5BG%J__Q85JwN=RQ@rX$v=T}`9ZiCW$BB;fa`?`cM1#cK{z73@Q}zte<~&XLgc|K zA|L)D3g9DA$g)Kdn<$EzPfTD(h!VC^OlGUa6r49xS)C|l4PqK=6*JfdaR~dSn5_i+ zcofE0V6F8tWd{EOE36llIDZ6lt)G)Pvuv1d{er|9U64ZSml!hHYUoETi6z+4aI!@o zeL33zt=6yX3BbPP(lrwyf4k@-SX(eLd(B61e8DF$k+Bb;11100WTi;*%^kS*EJRk$ zRno{`!{ORNVkDIO;Arwm|5Kq+N+?ZoP$Q9=A)B&?p)=1;eS-Dc+cfOda)S~^*crC4 zuv2X*R-V&-wp)1|=h~4A-I0sQDNRN$OGSk3z>>3jJcakOE7%D8fAW5I^+OM4ufR3? z)l;kk>}%LknY)9_Ju1c3$>m;^;_he`rKFXNvXEEpRf{Taq)sQcm)e$Yi}I zUs9Pn$&2v>DllH7vHJ4^Bk3U=-;$uIEYZ^7;Z?8fHv za@gL3R}t;EtWeIRf9j{rE;Uh9kEi5}u-n|uXEKY!65*I}$AVMR@syOrb&bt~b8jz{ z+Jl>e|BV{j{p_0~Y@b*y*0^=SYNZR-kSQ^i6k6N{iyEC#<=0_((5=n%``BvA?5#Bzv< zqhOa<0cVSqsApEe9`u|nM#OsdGtt3*D>m{9aRQ$&PUK5OCtoQ} z;&q~jH;NE%7QK9(*vdDGK7OJI^B%E{pDgd7~;>19sE~fCx2P&;=dQC z@i)ck{9ob>{-M|{m^fQZ7w3pW#kt}Lah|9U7b%_ge=@3=7T9Fb;TOqHf&iN1m5|E@ z;V3lQD@J6K%v)Kr`PeFD=-|DMTr56jb|Re; zlddDpQj0&|-vhJCXQtG~FzS|>Da|nqzuk+g1y_ax?1!WBsFdGgU61X-)xrq-(P~sH zf9&aL2iUX2aQj}{0lqzLvyGgb7uM`&KS%g0%vWjbXH>&06gJCg?H5MFCMvBG%e)27 zPHMms>wm?>*^Bd(i7QXvz0uC!2z%{33r)vaj#Ut(Bn{G+)SFXA*c<<;!#PbU_SAMk zxhOG8%;_WSEyVPx>dr`2=lG+Pj#lE&f0+I^3fk%K=;-bH*?UQvN7%oUjk~jcRBj|2 zLiQdce(vY|COAwF$JG7YEao{QoZM{owDPG*VY`-5HZv+cC7v{^@5Q*==4WBtZSk{9 zJgG=d`J}8#*^_c6d2Q?GUYI$~(+Dpn=H{lXg#}d@+=p}O4v^wbC>3|XJRG;9f5km$ zB}QPQxDQSc2Ouo&hko&09EJzsEb$PWC%z9?h=<`i@k6*xJOX!!N6`~~44x8?!!N}X z@P_yiyd$1ux#B5yxOjxk70{vpd8a?0e!(fA)fSi@hfP$lgHsmiRM!NBoWbTl|B2#XG!Eyvrww zfAXo~UwnpmpC2MV;(V;Mt{Tse+(Qz<~FGk;({Av%c#??335if6rW0f7r;$7%#lO4(CQJAOfNRCpE zm^3h(5J%7vZm_E0owc71zt=S7R-AL4p zX?TpUA$3ymzu>D+n?6c~iO=HD;ZCzyZdAVi&T~X|@Huv+b2pSTe;lY3^E;pfnLiP{ z#$?Dfra-YV4W<~=!Dq~XdB!2I+Bg&%jlX11!(qE|1e|M>!4<|FxZWs-{YC}+ z%$Ucf8H?Fr#u8R;EM*IfWzNRNJT%Yms~NBYTcjh4w1!)#XFx8SX?=jc4TDDbz0P+6 zyrA<TH_dGZ54DF)zE3wK%e1<0i(_(fBTU%&xYa5MBm_T_9wf8 zf_8K~$juu{j6HDaw1UYu!3EO`yf?w_QksQG=3aE?v1=>La$}0A&C(Q88zsy%%`r^; zNS9&S3nhebC-N1_TJhDc8a}d!8Jw@ZZNvge?9AleMS%5ZG_=$odb-fG2iZY zY}>YN+dH;x8_(F@v2A;1$F^;Ic5Iz_-|ys0PI8ie)26-CCT;JgynbQBV>d z>hm1=H%xs3bZvC{YuM>cSBN{e+jO8z7~b;3gjU}W%`2f+defIBtl(}%EL!=8S)*Qe zVJ}bsrp3T%PgKPTHryjzcE8bM%V!0aWJ_ngwMaJes&e=i;sW@LWf?oUx<=? zVgG2jwPd$I0$}+4iKQp7lS9#PUHETimU1CD2_9AZ+lJXjJm$5Z{gvk*4FhU_7FTbu z1n95`K?*t$f|6)xsdqR;rAZZSRQJ@ws~1`T4^$qQI3oo26eIL-9id!sOj3>}!a&$U z~x7M-Q;i z?_|{af!OllyV!>y5^)QXX2!d30b1-33UfkiPd$ZjAT`RI69{}@nP$ri;vADJn0%{qY%jqcK`ko5d}S}e zwL6v(2rT>^f4s6*I!y#3g`)pRU);~CjxBU=qZeE-|Z%RIBN+z*u zKA~=TXyQ|6dZ@aSDR0;Nj4%)Ck`K`!0$KOTGD=Q^SdD@3pdin4Z|i3n3hGD>W0$?1 zO@L55qq|MPY!#Ff0;2cmqYBYfTQGJNrKuJ3-KdwwEEu1}nfbOMKA_XLqds~aZVV!tu>gmE9ZYM6HhbUZ!R z!7V5-Z7bn&qLu4Ipd=wA2JuUTtP72WE-~tRl4zdttW5pvvNDs% zm4hrp-u}-qbsOSw|MU$4Z#m2f@L{-EQ#t=@lXlA=|Ah^q9nU9x4&E zmtm=pCOfmBev!83BoC?ACmZ4(qAF&|sTB*rT%ZB~HcI~N%~Pd>B7L}u)Q>GCt;ST7 zIrq zFB1={&K8^{jtjT?5Y>l}X>x)&OPfg9N$E-XNeN-Eof{-_LGd1&P;!(~%}ZRK z(|oVxX1b41!dOm=eoY0on_kj09&5#*2)CApcb%t9DDD&ve%d7Lj=tu z9(dF(K|9gAZ;Wgi3~B9eEHZ3XZrZLR@?>HaOo=X{qT!D^O5hpymqhQ1tl@PpgQ%Tb)-@ zk_{A|&+mcIx3#daD&v;{+yF|FZZ_(G%{RsCCa2=<@e#<5p%|wwLkA}DIr}%EVJ7)C z3`6smHo>(gflir77!8K^WLW}O93Z>R?83T^ z8vHX0%Q&ecJ8qw}&l%C0y4NiAB-*g@3mBS;S}Q*$yM(=0a?AGwV7(W-in$egf^8V< zjoGpFOg^Qn*Ml6ZuPz)fUAiB$UG5w=XQi*)(%ysXS!|C|WN_S`9an!i++X+vc=G65 z`2`V}`u$l++c_S|*x92y&hA|4jLHpUH2kOD_-)R4Chbvb&R+3M%o*LcdX<6(0onY(6sA7|e2P-%GcS~e^)kDQ1^e3uliX*h? zbvT}V2Xp=yM`Yc{STfTd*781vXv0UFx57m!fBS$Pp@C+O4~+dyfCp-qq|JoA!^PP_ ztcBPzYjtCt6DvJtLB}*}@L`5YzW=#>SZdM*i^7o;n}7+hz%IY zfkVOcAIE{EIxIyiDW2?z95u!{)g1FDEvJt&!nDN^d4d^>B9%<(eSp(Catg#E;-7@f zgKm>3LLQkHBHi5cEHYnk%IUjB1pct+4dis4#2hkTXv(Q$lc+#{`wgj9LFvyIF)625 zKM_IznTLh%05ImnpXK^qgP=^`+cg~`cAjo55Vs~yUf&&3y^ok7_<$@sRG5G32g4dE zlf(uolllf}{ccZ#RIJdOeU;)k>ZiLKrD^aN4@?rXK(4j-%W%V zE7f{#&<&4@xxF?ne+%eDBP{zG^O|8w7+rH`)%3U#of`XwjnuN~QA2q0OlTD_pk;yD zh%aTZtBelG&F#F%`}KS@R3PYNcWy9Dt}074QFQW z(z8q8hOFZy#KH8n%jgItUfB*8u`(w~PjZd;;u?>#m_xJmoN057bfe|uGxD?6MnvX){?q{;|*blL0*`Tqq*1nZSiN%)BQSA zi?(A%C!~kZJY{}Nj+^eUH!F~0U6l}Joe|?)BoC;pC@{L^FrHo4;R9;BieQX4`USu@ z(CU)+O2CJ9S(e31`kfk1(K01%Ve(6RSLQtWXG-g!sPFf#MS7-jc3V~ zJ>7M=xuqk&F^>9JajK`Gyic}H(+sY8nztz*UNMwVf_CJMG1 zEyTX#gj4K7D4HB_ON))>h8b~b_1ZEDbcL5~oeoJ~_WW&@jc{KL^P8O^nEZnHw2nR$ zrCNs2P8S+OQ$JXydScIM@*C|!x($C~+e#N~r=c6zT~j~gy}ELb=mOhgaUB4{prs#_ zT6M9DcLDB!;7Fj!!4syzZ4hA|p_EJ^9AaLsl+2R9(-9u0rjKoK^0oNQZh{ z`AB~*a~j5=_=+D$qRJ2RFQA#4;7Z>2l1r(pJD8|BVNB&zvv`}!=Tx(1(Hp(`6pS?_@h;4_l+Djb*`t*dHWd_ z;j8wJ26N=4dNcl2(3PZS(@Dip+BPB}?-JaNwBl^#;S%%YhBKxXxn~C3g%xlcZt=Ay zWO6!#IhADFX}iA_^J;)koif#H@yhKWwJwZmF9NN{ow5WIf_bt9knxDGuC41WdupSKA5 z6`v&>hJ8Wl-s(!)<9O7zAj}0eDj@QG->ba}jF%2@D|465}-QmYRP*bnW ztjLG77Jzsf7e5yP(KLrlhXG(B!-Tr{B8FaQq)<{{e0(INo22ky+tU;NF#Lad54H#e z>fV@Ls|vH$d?9-0Jxte~l3%$LXUk{_F04B6Ek`@#mWnv`p9_Rai+#t7T}p{|pC?k- zWN;cRcrUiEJ@WIU(K`j-oKl5s?X$78P0^f=Y=9yoz{+q=O&E#|$z>1i9C$~R+pI)W zm{0+TmMet@ZAY(?BOL9(y?Rv5f2y0*t5+=nghy0imBeY!e>5mnjKM?yA)t_$U^@KE zVvdhZ4)$Y*!g4WUr{-_PU;mqmVUi}2Xw4;D0df;<2qsKfCeUC=y&?kob#U!UM%a}u zz!N%p&ASdvKnrAcX`E_vlWHq?lU=2Zcs+jx{vKFY3+XV}7KFxhb~M@g9DS4*aPh;ZnY3X2{ z=Axaefr^u0D`%nE`H#FM3h7ML2{nO-4lxWr{zz>4o=b1x3B9|p@$Qn&28`g8uByNW zO$@XozS@rljF6PBbNAFM*J{_T+MGi`7)iX}@mIfk0fQ!7iM_TH>m>cJ+-?Z~fN?@l zC&v_T^%pTT zk~odnE$_P?#W&78U-B~0s2=Ajiti?4HR@}apOg4$z>7SkV&5f{O-_=XocwMZq-9@N2L0weusfT z(MIu2cm;gu(#_8~+7z;7hF1xL*E~=!7VYwd*1pRp_0l6xcFl-ii?;xI+cQUBG;>#H z?WW!~!REx#L)YKVZiI(B7@c*uj*Pc;xm2_CBR9w23N3}^QTuE*cQ~tmu8A*jLp5&k zr!B5U=x(7{F(mTBIH5Tr0mcqtobW6|P#P57!4yO4t5Nzq_6THqOKuD*5W0`R)Dnl( zTh}fwJ<4ZaQdKl@-VWr;M*4r@v8KD1qu3k}oMue??Q}y$OO5?k+H^xL15ir~dn;?_ z)hqR^dR3qq$6GmEDIdeGtX`kc1-luxCyQ1fj2|(g9z~iWE$M&LmpAF3ys=^YgG|{)zV2VmS+_;f#@fMO*R& zU-CrPO?N&W&kB=uM8bQJInC1#?nX9X%wf^#z*S`*AzF;ejv*aI?^4vXa}oQY>$ov> zGWw@J$9qXc_!Ms|0;&XKjJIAS=p$X#V}}gpQvD8%RMo)liLLNeU6Eq+^=sx(+MR!2 z!M;K0`IdkA7fgX@fUmhj=*tgpw|M^SzXzTaH7@(g0zD(KWlH|Ag^3Qs*3|dL^y)AGpz86v|`joJooXYmEkpiw>hq z|8?5{T{JFQ24MJ;mtF;3ZNl7?vJ_~R)-nydpa%Q9g@2EKh-{ zqlJ6sHdkHF;+kd|kcX~wB{MYqaVR5aNV^OmdU1tQDQxzBYZoM;FB8|HUxM`8P+SIA zE(su8AX3`Li>ZQ9HRUTKyATO|FuXP~Ai);Y_Eh~X0$AsPvt$4-4{gE#?3K@pYIk+J zh^!|zK6%dmJb~1<=$PrD({#$;+XoqVQ0-<&w*gmT593@T9_5gAACxl3v-&z&Z$680 z`?NV?({`KM-l@O}E3yeZzL;3Nod2+YE6lw<4uSl%+!L=yS_7wvT{Gy}vmLar zOV!4X07UM_RJ;y}kNeAM@l94MlDD>uKN{G1rEhw<(fdTTcQgO!=={q}^HxpYluiB% z=bV{5)}?jCAKqR)e%PYe{)eemH+?gfx)s38zyddRRpq3;->f@+=%(6UocPBbYs-Gk8 zjCYmVyDzGNqm%x<7b+b=f1*3%=Q5$v(@MnzkQSb2_OcrM{M-0N&=b;Q4+~YZjvljR zrXVYwfAq3aHUP?lhiyjFZ+m);rE&ID(dG~xrz#+V93W3zX#teqYE>KCFwS7(8T+(!!y#g!SZ|M9vu6{{M=JhT)c{@ zY85lVlsui4;-4+i<@2!^P_(?$L1(JznUq=;6ZQm+zfR<~=!thCEZ&eOCNd{yn%fjj&u7XrC`%014{x3l`~@0csS;JOXif& z4Rv{d7gP>=;OFIP(Cdfgn??K;hhraS?|?z7RVVoI3ZHhorN|b{(=! zd!$&egWssb->3uHs6*QL?QiP=x^Y9}ZrigEidF#!_h~B#*eOftflFgI zXA91+d!8*Dao`UT>c3O-c4C443l_2!+0P$Tv%p?P2jl3pjYVpLCNUZs8}Awz{1A9S zyhu(oV;D;$&O=p8ysqS#I2Cg^G&hIM>$D*ObhT3&POUL}qBy&SNb{VBQIBCY z?n`;;?B#Cfd%SI>?qN!EGDDgY3a8+bvHagb$I?Ewg3Lcq!3#mj4U@IHBb9H z?j|FFm8<1S)bzBeL@M(lPqg_b0@lldAJz zhfIWOsZu>P@*yuYzzGPfJv>kc9=Rx%L~@Eyh`84U^tR4x_|yEb4wjLwQ>1k>-ehct zA?&H5@qAQ^GZ}G1a+8dP46O$Mhh) zX}|t5*lB#Z=|@R-TkY*41gw}K@KV?qO-s?a%8(AeCo4J?kO$4Ja^V3D{e1RB0sb(R zNk|UCw;HW04zy!6#aG6jY-IVlGJ`Sb#aBCr!RB--^NE?Ck|c_t@HNu_%R!Lk#K> zgCWSb5y-m)=%fxAMp2cCE`^DyHeM%9#oUmI#v2;0>19#TlQ3fw(jJ9v2%_%)GKj*+ zPJ{AsJ`Ew0-{V_MJSh`4zP5_j`1-O{m3jE+9YFcZPy^n&gxp_MwF{SanfNK7GW&d% zg2_-GNI_j*>D;I4<6VE41!e>k_kVO5M0W|qtYjh8 zTKm1!F>D!wLA)tpfVHBhD~s9+ZdD7d$0Sw8rgKwWa8$4Hjvao}1u9o}zM>X{P^cH( zEj5!^1)EqA7I$=O8gIkz6=Z|LDkr2)2y%2G^p`qBr{E;DYY@Xi61|Js;xX8Q2BSjL z(}J)I&}aS_Fs#Pk)bu8VQz>Agy&`09O$b}}1sqg;Vc5ooIjkWPw9Sn(0apw#ZqHvl ztgop*sohP%&D+`JpBIEu0epbzD@y2cLg+r3)imFmvC#Uy=EvguP+ii$z7 znG;bf(kz^(f(IWUYP9jC;{t-KlkfQ&Z zt?{Z-^+8|dgRRE@8A;QlEbE#QjQw%5k($U`5Q1cXnc`wzI)YP9HcZiNlHwmH^B6$` z*qzX9OgKE*y~%`eT;|0^em2M3e(5a2wvk z{g_0S!;s(+Z7&>Qj)mOsWb-;M9RUFY_$oKre@%=yfgsOOX21PFmgWTvc;OGHREg|s z#tk+CHS7G&@EC**^Ds*x&(Sn;D;{*_7Ub>W9=s=O9HnCKCaBwpVG$a^ks{40jrYhAM_CITY($GV!6MDMlH?7Mx~ojk{x{Wj|vWrj+OH}$9K!q$OU3ozn6;0q2J3LFWj<#?s3b4gT> z23gc6Y0NKk8%Mr8zgNw5GqhfTyF!h>U2)&-cUJ)@BVXFZBi+blC3L^b>j5*#>i@1s zXUBJj#u1Ee_(^Z2xgZrhN5(numaWEoK6tO2r=w^@B&(?&AW zM7LQI`|bW(-KhJw(a$IdUG2!Syw4FK$w+Zndx&vZXXZ%i!1a*hLBnAUucJ8b;UjG1 zg1iAT4=tt)P-OUVP;>YkD)*3*_ZqwR9(nZ?uv%XI`7sp04Sb5T8z^ufy!DK$C=dgD zw~WJoF#o5BtvY~;^iLULrV%622K!8fX&#dnV!X7R$Z=TKQTWV@yr-ky6(W(P;L>_1 z=iXLf9=r#igM~#ESsv(7WTqqh5&!u`oLwx*lNf&MhCeI@c_{cwKE33HmI{S0Fl`Gw zWxsQOul9V8(>%MISRBRF-;ry0lB;c_(%AbAB{QHQ08~VIbAH{D65qyy{@}fzr4VmD zv;xk?0vQ#o!|$5{Dsoy@Ij-vL*MExs>ZVHdcmZ;Nyv! z>lAf#2CJv=WbeU^zTp0C(R)x;wTweKIYfnq6_2+XFUYn z-o!4Ne^cZr5pJUv;vQ$}sqTcHQmBKSU_Vx5uro=Tfa553HJTNb__JfFk_fVjWaziX3M%+FsqRD5vXx`uu9P zB&TwM!$0A%(tJe)2070E>GQ#jO1vu5X|<+tuj^Km8y&0{sSLBUxc7~YlQVrx0vID7 ze8nT3|I_E0dd~lEtv?$c!PMW0X}lU$eSFc>_%v%MBki@J?G>e_VF4Zz16&{}$`k^j z%(;-Kp>h3a5*+aRiRz)>&Dfr%GUkI19^_tw7xHQM@)k=B!<+Z*A4Kv!G(s*0z2G^* zV{p+S{mjVmmwJ?Jts;)@k5lT+3gbDBcxV6?BHa)WqIX$e8c5Bk6Orc ze((Lkwv8=0qx!%Tk^?mMP?YuQtxDwoD4U}yM3i!E!eUUddgZIQbcXDRE)A-^uRca{ ze`C3R3S8ak614LlKiC@agoU{A6^zy$trEF8Y0%~z)rlSnP`Ek1bgoYA;n$}Q`0iih z{#&8H&8#b>0+qWylvZcJaP38(?+B){aF1EJL3br_Pm}xX;RZCv^MAKY(^Yvi{w8R` zH=?@i#_wlj)qdfyw%&_Ktt6ty_ZDE@)&j}VXjF|@^Ww3GHfVvlOc2#hTxw9}0k_H6 z5xbQS6}`Uty}<*y4pvk`2${@eSSTVcvVSoj$$cO4+;+_Cx11aQGP` zHI=ira!NS=@&V-buBuLl3aR$}z5d!o)(yf~Ohqt?;)>$``Hgc2=1VpeC_gJpI1v~o z@f$YWqASP^X`U5MWL+hp$x`pYVqssuo@TxTZMLM;$u@LuTF>#;ut-jUY+V*{$jl9F zJu7HED{4I}Y`qhsnTw#g{a154WOF-ab316W=l6FI`(Hqmh|qcyuB{iYZK!IIT+mv2qzlnV`czv`dOfTKezP-$S0^IK6;mr-|k5cHJdJ#UQxcz$9K71N4u}kviGyiL>q3N1R!zGj^R&s&>5aaxYa}9?#atWgNDV; zn78b`|V>-l(E$k)`!z^XzAH!Wa z*t_ zBOb^wI)-EN7!V2tHd$2U2m+5jA&EN)Adq~E3QHtEsWMNecsC$f7b7Zmb?bT@*kS+X ztzMd5>!wRiOMl5X_RO>nT-tYAz`I-(`BKZh1u9KQ5bk>#5A@TV0zxD6{ zG~EaHt?SAuUyZ(9FM4tTrC0Yl=2x?`fJIkT3*B z>Tfl2Pc59Gy;`fbT*ZOUD(rtJiw**{vPXf?3>7zt&oq(UJX(7M!%#eMnZ!mZFD zTkup%i*%QFMPz)m&m2#SbOS1<%?qY&)EvUu1XSsECQZ_Dif8o|I<7f>QpqUhfL8tC z2~haTRj-5yYCb7Eb=8qEY5AkbQ5Egnh79P+%6lt|HQeQ-W{=V4er*Kqn(7*v#+fkO zciz!PDxkMAqV+j^BIYeDqJbqyse-dm@G(Se>JLpy{!S)F%vUL84}6WiE<)x`4${zP zDCTX_5syE(2Xcw7qaF!GMoE3_faZ3gccqY?vIq3@7w;h=+n;k#3{}o~c2bgcb`Q-J zwazMv3+Gei5iBW*=OqQ#E#An{cfrDls0p4f5!>FTT4F>>Rm58<+oo=MGY)TFA$lUA1`4q~xhGRMkX<=rv3m+Cfc zp8C<0#63i$#{KO_0Q0gBF~9(ooG)4bFazyKE!E~&rX{7_1V>-^qz0C&wQjPV=i}s@ zZIbvPjgon*VDu559blagaI6~L#KQ~Q|99_JgXSl5GO87IFbRSZ%Akw;I-4;euuRR2 zkb=nrJtgvmu!MRhQrN6lymNqaIxG+XK>jW`C5((Mc$p=>X+!L%JSKyr2qz5xLCJ@c zhZBX9g_DF+ND`I_$4kbG{!S)LCk!D>&chaR4a5dzgR(+eB$p%sNK%xEG%OZt@CCks z@(02Of`h_AVI%2?&8Fo+36Tpa2bzISL1`iC$jv6^p$VZc&1K}l3294POU&lvffT!v zo{G+<6K3YY9O;QT&VbAaz5N#F7t#;(OIpq~0)ea{ z!IZQNqI|*#ynq4+pupxw<503E?TQB)f(}p_gZ4>s; zYeSOH?uiC!pE)28*^#8lI`H(N2J%4uBTbWbz{uu}F>*(drFfy~gPrWHFGra+%9`Q~ zTR3s@!9U>3a$*=cVWBtZj9b8P@JB)-!GhsDLW&g_f5ALB$m)(bP+;UAdqF)|h|a`ny-C;R z`hq=RAHIqX$_io(i0+C+{O7-@^T^_1V4y5)=Z<}xK1`JQgez5P|%(|a2f z&EPaHgDWrycws)E$@-!m(Kq(VzJ(j+;Cd#&1w`H24g;9G2imWh@sE?9IluT1AhPZl zh7q`qNQUFMj!%m7 zKn~)vzEBRRhI6?-F@^ywImZwBSTl?{ro1EVCs+&sMm>|xL67v`AmTA|LuD-3(d31h zij30YQF8;B!>6XO=FtYxCecRGX3<3DO&YNyOv5bXjB19mCbC9V<7ty={b}PGG4g(l^+3iV!{W3js<`%(tHDfv>Zy!bhL5A^Fl)_h z##SQ%Oi}f0#yG<*(N~xoEN%vuqpK11EXM4{7{k_>wWgQjt1ST+w`3&RF*k zoy1r9y`RI}g6a?*`%}goomkiK39~3hL>Lu<_L8C9r#X*7+_MDC2ESNCFY>@3)aaWm{psn5IwYKos= ziBI=PI(Qm4!+aX70}E}(JRaL-CP@53_=5)6i?F|bJre)=MUv_W34@=Seg;hn zq9x0f+It4A!iruOLUx!BOyCJeT|_Lt@W+kVq*!Ur!(N2ga>&~l&UV6<1uG&{$@-?t zhpezbY|dkmE3{Se92ygd5;zF`?#prPOQmQ^-e%X0bl>L`1-$ttUvTxD>D^dxcZVWPK2iIykje4PwE6X^eCnB^{uTC(rHlMggN|dp$YA$j%Vk*A z1Qdi1u_b=So5gd;G#@~C&~VclZIUBeyP$vLCmM|o3LQIuK=wv++_s7_rjyCS6T_!% zq|g;dtV=n76AwIQh^>L=6VF>FoatVNr4|4jQc{3fbzU>HVyk<7gL`Gy48Ih(m{{tb=%tr%gq`3=qu5)u4@|CKo`EB zT-5b#CX@sz`6VuJoYHSvX9w;qbf>9#Mz*>*UebC+C_LD$!pgMFb!0+vHq1AFB4bb4iX2`#+ zub!#khD?Y*T2M3G$+?fz0zvbye_1&o@V=aObMtz*q62dIZFPP))|mr8Q<6IE0l(Hz zfG^srIsqh4X7TxijjH~!(lw1VewE$_kdvXZJcj;O8a$9J0(^DTc&x4ED`ivszy@*6v~Z>9`OX$ za%AHaNwS(#%u-eERnoxTPJ|O|@Y-ZmQ|oi;mDDvYdvXPmkS^YHDI0px5V^!&u~l zO_lR7{lauq5ZC24&tAgSZkslzr}-t+ngbBHdv3d3v#fou@3{nPk9jlUjuwE~O~Hj0vw^0$ zgACk27%&J^MC_tdX5nZBvffBy>_!E~25>vJ3NP2xgJl~@ojJ^Wn(=#pA%q{cyQ4x- zK1p1lp!+1`l2OcYZS}5{8buP+<}1S3OZt>u3`x`U)6kloLkgN?EE8zJ71u%vOLB7O zgB_-4RAOwFGGi6k01IG=3zWp&yU3>`o7~3A=NtqNE zMmtF)E0t_PO-(C6H3?sal>EF@EH<$z>fA5&Y(`xtb$}r%RUO3g-DXtos#&jvtfkTB z)Wt@X2xWpP(om~JO-IInsf1~{Fv>Cpv$mER66MOP!K-kN4;Mh}UPkF~^DUF?AX9%` z#myG5{9Zz4OU|n1=v$;RdLN+Z!D!p2Xt;1MKSVPMrHtohQ+DJJ4IlP`FDdA&gm_*V zJVUG?q64;aJSh`S&?Y5#mkyuo9Y1Kec_Lp+l^@Kk4)jM~j?Mo7NwDDTy~9<85^L2U zy-b_lzFF3;g%^NloIV(YId477{)b;-35KcYPn{9a!_+VJaxXe`gJSp_40kyl0ixa~ z*<%S8(4D3Yt7^Kxg$H)@)~5x_U#CvIiF(Ig4sc;h^U8cWx*`OvpKNDP&AJ0;+By60 zbTQODDxCnhFs4}M5PEm00{$wA?3no!;sBTr0_*rybYMQn#?5h2w)xb^URRGBlDt1n zO72=E#zt`J>?_}M;LdPBSe44jcNwn)E(`sxqLa7?K-~kqwP~6rUdORrgZ;1^Q3GSL zcNDZ{eiDF!Z*w2s^{g|MlbU0UeK6ZhVSt1b!b{e6?#=U@@|V14s2#8Q2_VAHXGr`t zZ+U&B{M&Wuk+E5g=52533oUL9l98(LHVM%+=yxbn1jFeyRB<&Tz*ytJ zJuQy|?XeL6^#4xbuCKXhEMb48R{aRe0g{dEkdY0X`{|ir-~&v9@(tqf;opIM$@+x& zW=|L_s}U@NKD%=qV0>3Nj@3fl!M(J6F)qH~I*yk_fMX?l7_zjf>xyoTTT>}Wkfh{E zWr_r$O>7ogtjYXh*qdy&N}fd}x2W}dF*NB6CKyg-g|X+eN8?8aZ32b}to>Wy08g)A z$J3`U8#93uP-ILP_nG{7h_b4 zR8sxuTJ8JW8;K$OscZzAD3FPjAD~Vm>NH2N$f~S0HO|GZyR=sYmv9ONC3t&{b0oqk zLbZ&LR$fQgOymt-zgOn>VXmkI`gF2JkaWNyKc7J)Rf^|pPWm#2OT&^CAOd@F-tpmV z5Q*p2oKT&i9vvS!*!Qms@ET&x9}CuCq^T2g=P6`53o>WDty&2ee*WdT-ipS$fB*~Q z_e=$JS9ESt?zICI<&Yy*Z5{=qLc{9Zy8y6EvT1YbqG!a0j@ImkLi!@O)5#+k(vJEN z4-D7`um~4%;-PxdttJ6f!0oHd`h%n=bW6bqRBdpqUIV}Ba<3O*TQ;!!5r_Otk<+m) z@Ee)Wr1lXEht;0sq?)UPK|IJF8HV%=7nbsaKL`6vC14DQfHh9)n`B3EJMw%^nRt~?a_@+w8`*8fW(n2H)a86KD^lX^3u_2x7{l}1jJhu&?t;wDfD!LaOeAAx zv^SHqJ313=-s^)Oz=wD??}PLwBlZJa0R)8?Mn9n~c`aFStu4Q$!OYk_v$VUtp}r-Q z!ant9LBzF0H^r9YrXb_&u5J3aw0e5r-twhl5RW&Pca-&F->G-M3;A6m%P4#Wn=D{y zi_DQ@f<>F}WQpCaRZXq-qUOA;vU00;+fQy^Z&PBtMagXhkm#${9k%bh@3+n-B`A&8 zrGQXBT`S`=P`9)!|Ha|zj97I=6cKg{Y0bjAWPvnA$>T`YJI;^b9zctmgvm5-BjT${ z1_Lh@-9Xq}n9fvQeO9x+syER=@CS3?pom8l%hCiBPn7xWxCdN$tCck8aI3V*)~4oP zjs4YWjh&?xpu(oc@*s72SW9_n0eNTGJsd~elwDyYygeY18tFU353P0P#kjcFt-ypITtqW3@p}SWnODTXJ>Uw7HUN*hN_tx6H=l{ut@nH z;jG0G@P;y)(NOlcxY@~9f^G({bla{3eXhE&eM@|WX@i2#xxua$-pkbvquYO*m$gn6 zq4|DqUXw$K;o04aDA#i}^!H16O!pXiHk)$lfuB^hw887hyF))+yjy9DSW^y6W|PoF z*}?@30{Fl~N}s0&){T>83p^3mCIRl9w;qAI~oczD$!#=1J;hhXi&ABTnYVI9<+I3^CgU2?+XPZ^T^ z1w!wP5i8tA5VWA{0a>m%i6vh0$_~H;$iD-v+7^zw5ePpqvbW(WkjEJz!BG{Cy7J@* ze^G9hG_B&Ma1YmYo<&nmpBu5kduiKhXCJiTXcn0$PGfN?sx)7=M1UOF;~t6*{(aDi zap`?TPt>s|nR$ed)VVflzu-&yyDiat0m9lAYt(fi;?fao*myzWp*!N3Z;iVFu3q6`JLoHaGCS zr{ov@*|d%-beJoNBcyv6AN!@Az=x{z&oF7>cPj=ND`aGP$U|*DX(aixct(S_gyM-= zf^U?u11cQEaISllqVZC}0A*b@KuhrD@MZ;bnM2bGv*T$i(BCT=gJC}`lVIpW13n4a%0{75>OySy6==DM}R?T9tV^KiBl6f_1Ung|!^krA*f1 zVY~FWw^pZ3lFCNi*)bv`jAqeCr&zv^%?ilw_Zp@e7x-b+s5nHv5pY)u;N_{i&s2Cg zFe^YlWT1W04>n>Sz_}#9FoMJ$Fj)BUCv9d&^u`4r_nmHA)#O^JfG4sWdOzonUJIUJ z1=jwrkW>0-qgmV1I*Onv5oEBxX@Puj^v$596*`CI3yOJnzf0~MQ>X<)oD?{(3vxRS z4&4I#`Y>fqpX(6OW#)I&0FC0fBFJ3VvXTW6!I*Fk!B4l-awX4BunCm(+aT{k8`SrR z3>zS0_KG@&`fQ;zmKk?Z#@ONwNOLb2ov+gx20m^u9@DEXk0vHVNu9rkMpcT_3R8$B z=tOF$3s2SZRH_G|UD3tV0?b_L*(=z@gU27HBdy`jLt>2B4x|G}06}^U!Q+ylx~mj{ zRz-3?f$1gsPeHPq9hBXiXENBi=@mi+6=IcIpv!3 zC7X@Q&wHhtp(>Zm09C3Od2+4_zXLxq35EZrnci?^`@wC%W@yZktz&i2f^d(3X6ol% zHCj|<_{S=B_qVLK^y^91{<}0)^s&T@%|d&!sR2b(0dH?|yCMJ#nR2kVT|Ut%*XfCm z3P1klY-bZpzUZ9g5`wr$(C zZFOvWa%a}en)`mKwdx1#s&h66uLLry`b(7&i4y@w#pK9&${LxnLusP%Wb*PR%J;3R z)1s8PNg;3(Ff-ZinJ;w0?fI||0n1R=j#OFFrA*A78qMG(=-gV0DD2gm4E|bAglWMW zhGieSELRtT@$G?ztt`kZUBsPe!5}_2jq(*p)W0UijfZZmYk5FCml!gRd18 zYc4>886Qd)Z4~lW8~n;h4b$;k)#GydmyamsvAt+*j#OP8Rk#;fk*t*zz&Zw_4_JX4 zL&;XAWzbrELX(VjwfH2XFMNt^sS1&s%ij*Eat=B1P&S?56q&@QJV|4Czn{&BVM8Wm zEwEX>Cw19jDM^{n)hMeyT=ILVRZ%A(V+qjIDy9<>a0Z5>z`oDwg1oK79--_Kky>Gk zDz#{nFTTa=VVln}%&35)#-3GsU61SqLk| z0s>kL0M}95Xl>D^sbfcB*r5$YgaSIJSs1I#P}bL*AhnhlRBz+jBK*QQ%&y0{7jJIp z{v?+Rzm4|+KFnd(@w-q4p?)koZH;;7c`CEv{&eO&=GT7eT>+Rsh=M5X8AiHlqYJI7 zW2CpWWJ5}hrATl);{Z#h0~jGvR)YM@tYafJz(8YNbiEdrj|763g+Cb~b}p1aNN8bMv8aL}((!=|bIRNx zc5+^`zE+geI(=o9tN<5X+^Fu5AyRn!mq%2p8M@j-C9@`Gm})SIwlM~W&Qqo>=Uask z;I`9UWY|QT5OjSWNkv{nz_~Akp?a)!ni@e3)+r3!cC_^r%-U!{q@A>8gef{%hm=n4l!5R0ewQ)8fKca_Sj}RG zbJt_!Gfi-8{44=1WzCbQAf|y~apt6%S>-3ahzx^Ug2XtwP+X=p)@i!o4Kn%-kPY62 zBs|IW(h_2>1dD{n_I&Qx{-wb}IEr?fmnZs#d#8vn3bek+!|(`P_{#I*x~mq18@Sz8 z7VuzOXd@3tK$U~2+`UUTbm&MF%pgsD@Es2RmhKwi9b3M|<7K`j<}SJw+~b9wqWfTd zV0nohxcF)lSeP<+x9oHx1^(;>XrWNCx7d)NOsu(~-kHt!788E;BRndRs!68g_Ou;h z+?NbLz`IJY=ksKgO#aIl{w9BqjR4s!1uP#E#LU%$liH!xM(a2GvFZtpc$Iv{{>Zno|fJH3Xdc z(fYVlr2JD1;7Oa#QyHY!;q{U5WY}3qo;q6K^y~Mg6S8?O(gJU1QdZ#K*c`VJwLx(V z@bmUO4qqgQ2)9OQpy=e;*y2f?e&2^=!%2*9g}cHP{jcV22@YiOP-a zGhrVQ@5>nNGh0jF4whwM4-YEYWO5SWt&BQjGm8!$V5ONDu|*UJWwkkb>ick|9RFlv z$A@uLFUxO7R_@o4t!`syP$vq!yeP1&-_QttUq`4r9NRZLQj+a@}9c zOwjE)SAq{6muI6FclFx=5hhV=XuCLfc)HA*fQp5r9RIZI$~!< zr`7`_wkP=>X&sY59}tL&RDc1k3wYH{FfbYc)3 zc2;HCmzpSne5`?K(z^Plz`E$Oc}v0N^Xh1+Epvg>gzu(hK@7O=sP7@_^||{rxV7=f zzfGm+i{zlzNzrJ4+g~2Vg$?S7*p@ojjWTj9u#hZiSN>e2_V_=yB-x_kV_Tf!VWeczTSD{o)Cd;Gdv zJ3PLY>{lxr@5N)4&vR?->-+LAST@@S50!5+?3|kyFqLlr8g|Zq-c_+%UOUSH9Z`S0 zb(g*yqkQoAeoOo-_0Ncap-oCo2AD%H$UJm#{A$}LV#m;mS*fm9t z$Z}VoY~6ziR(5I$KShRU`x9(mz#-;QFB`@r@-4R?cy$ga1C1f=3$N4JE^U+h)@&;x zZzmU1w1BFN*BTQit)n*vynZzrZtH^|Pb~ij?)?G_$7;%SLlI{BS?@)1a`HG@^`i>5 z-T@UCsOHt}Ia{}%-TXX8zEGjZ3RL)BqpVp=d39?6m-oi-fwyN`md~kjH0e&$t=XB520DiQohUfKoH$TnIB!5c7Kvy-R+-F zNx;F$_`fwR+B2m!Ll(YiS$Bw(wjd z<@NtvEO1m%tt7NXG;liwO)vwWCT+a^nFqAFltp*5;K#2`EAPCam|zaR3li@n`9naU{#OCrrag|Q^%x7&Hs!)eUQ^!=Pu?#Ek%agE|^<~elR5WvA7MJIPC~n9|K$+ zj?npPPs7KbzH&e6A1w&Ix?oDOMpkQw4^g6JWSX%u7SWWA9k9QBKx_#sPuR!W81*LP zSP-Cc79_1hzhdGX@EG=jJ?u> zP5PSUEgke1$`HH~!Ml703q*UMXaJtNYqKd=Pu_@=x5;Yq)}+a(x)Adj>27yUb)Ib3 zit0QW^lGWuqP8NI5h*u6OGLnKlhJzp_qBn?24RL{dwta~Q~c@2v&O533#K`A#bo9k zY#xPc#3YLg0gc@RHcylm0YYV8&KXcHpulV18x$o)?)i$=3YK_0T!7R|{pJ95 zB@sF{t}QBJwB43 zMkR~iBb1LZIf~zd81#R`PyoOq?osYOICcnj(FeeTS_dx#Jg0Yqj7itr;b`xPwrt^K z-kMhnl)O9(CCuJj8zoNOn&(RGTohD3k}JRMH;)N$@)4#_+-8#iEo!(yrStf3_`yeU zp<;%@Kp_hIajjxx9>(=zRNPEc#LN|jgvCj`Rn>1$XKZ*wn*-(;0f4b`&Jc$u;Bj=& z2WtVuEnz<3flmym&2#w+-IzcxV5&`Q#)+*6&1bUABVVB7R(7MhcM0v??eL~6o7KbZ z=teJau&vM4f7_(10Y%%P!otE!tt}OC3yHTPgZR%aFT+yKGE0Q&F^QKWpeCw0b9fh= zE#;d|f^Elvjx&%)*#P8m9`ZylS&HXO`72I=I1BjFhS-qB-i1?NIKt;&;hQr?`R}08 z4n3i1S3IQ-*F)aVyfpUk`D!0;ZJ^nD%{X`1l6G7nhrp^Rb!jUPl6#JBc z?${NO#$qE60#vpLSvV901~~nbV&l&Rt(({@{pDkpuEQ79MF6&4JhBvgfk7Uq5nR!> z_aEz8IF{pywkh_iOoEtADoywj6I(0-sdZjG*)Io}qeDYR0gh}=P>cBCvDqUhxV=q& ze9k8bw1y6~dE$BVS>|Q)v$4O(1b?8daDXaY!3X`2?c&cagw)qDa?7c)Xn8Q5{lj_* zE7xNFq*lB6Hvz^F3Zf$WWhpdvQ8@NGY7@lG@$)M?Qk}u&V{75|6iag1ES%zeC=7Ja zPjNaX%=!Mli2p9u3T;jx!gRRc*JC;p#@z^O1b=%{;tXirEf16^)L*)y(0H4_0`l}V zc8kqUiLdJ#<4;27@b`5E6o|z44d=3_=MBfoCI@Hr`T`K8L1@W03tCntfZ(w}Y~a&D zi1A<$BFO|pYKe7cCmuc>I$8qyRBl7TtE0ud{umPuz`qAQMWVc|is!{t2r>qHeG0P2 zpu9cD3FasUg=1`=qQ6aw=XHod;mQYv9}Eq=>{q2?&_|-fkM_GqO3>&I7E&01F7ECJ zS#g^;jsT2!SvC$tHdZd+B7jG}%e@PWUl8D^%y@D$Rn{=_&0LJsk2Q*#>i7^H&9RV8 ziDDt(4j3$?#1ZDtk@J4}82P;!aF1$v-2EAhspptB3=l?(sEV6My+){*Pf)jxrx@Me z6+gAOM&N4~mH8(1Y@1UVKn=OYSd%Wzn=3Y}X9UF8#_VcwLpX#f={J%Wc-Au@5^BKK zjHY5qRO+HpZa|_?TR|pLyhBLK>mb{YLf1Ly+C$kPw>RWh2+Epw z*aDFChsobQhujWk`T9{K+YI|z}rU`mEKXHlw~ zW$?YD=j^-R{|(YwaWLWm6n(woQ4mk8s~AmD_^I(?!JPyFmPt`H&``<_3hOU|#{!9V zA6zYyeDm{=wa=Frp_EQu=6KK;8p0``1T-dMYg|jf=ov;zO6wWc58C6rB`-TB+Mh^; zik>ebh$nLu$vW?ZeUiKF4vK2IhKpu6hpTAGhFOlL?FMCx70hW-58H-s>jfS8!ZyES zWHIQ8ZGM80b?g))|8r1Awz2P#BcDVzcgz`-e5SOv&k+rI2Y%?7A-Lv^px(ka1jM`( zZ|?Gj_*}&}4Eo^3bkOfgJd1pU-b5%rr6@nQTuHfaeWHFHc1N~ow|lhLgvP#?Q#b(V zr|tESldjGUyWhdXN~aPC0hiVqxvWxJTExVfF_D&PFlyUj_tZ+W+w|r(p{p{^9hd4-Quce z6NfmTL>dKdqnce}(@Qmpuy3q)G@k;eXEEcTZ^(DrpB`=U-)+|OdP!4nfQ)((fEFDq zOWP#Gm}-Hzt~rNen*yO4Mv`OE9Dy1p^r59un6^=6tj(~eM_iqPEgM}jI(EwVGZt?B z)+&|Kuu1*ED&@lPQvF7&t}UZ&63;Mi8YA2&?*ZPL-6nm*umPvJx0bHyhw#5hwWHWu zvov%bC_%(Jh?&qbKwy48H26?jAk+}v z1>yq4(4c^G*lA$+AammJB!M!G^&7RyXE$B>%M{V$6WU|%Se3|1b=b!=f&gNErZIMr zGvOtUx9Sqbtk+F(szj-BOlXrKT8vsun2I5r4kXkgQ(d67wWxFs9h&^cVvQ~_)*#N6 znq0V~f=sEf9to8&05%WujR_IGDG=wtlAG*In8$GVk%Q_V5*3r}P?vHC-q0{_y*^%( zwjoY$7R#HdG{aS&%|4A_v;&_lqD1p}E6fa3ihN$&a7~c%y@1D@xU9&D^_)0ol1Vl_ zT4`m?sCI5OIM@C^jWd6J{d$d(YKUUjVBLxjq*>Eb=9f=g08N!>PCxwxe}}kSX~nNg z(k@{gu>N)I^`U*7r=%xzo33_@)pbUjrgki0jsRpa1qXk$XcIzngS^_owr##6XS=); zj&PdFrdhgZqjChpeZ}!-vU!njd=}1qyVN`O)CU02g8WT18ckj7w}6{YyHHnPJU~(K zo=@8m4X7j;V0_EcJ&;4A`gqzlY9+qr{p=u}N3DkYnbYg_GXFhu?k-|s?fX3%#AIS_!7AX~avww!k?&Hr3m*R36eZh~7OzNRT|Rc_cp**jXki1r`UI5U?s!6Nlcj2`r@> zq4=sW8H+#Q?SYFneqJZ-i(_>J+p4}DYTJe$a7WfD=L>|N%zhy15z(IR>_v=n{MxeF zl`o+q4pCN>OQ~GR22Z?A5iHorBdz{YYOcChl-RF_OBi80|7lna<#O*3W-jl?FiM~4 z)03b0XnLH_6o!OstG}R=t|@Z`BB|e3-RwMa6|Qi@ z?q|&Wm86EAfnGt*38v->Q((nM6t21=zb>AeWt)d6l606DQP_!V;6YAww~$KkY!u!J z-Eg>7nvf$xe0w}bZ&=oej(sFxousFjtvS&noi9vNEN@Ea2hcDK!(xvT%9MkEYI@l| zSNbic6uQH4;>@p2l^nm^3u28hQHrXh^OVmJvv4VgjN14`hNeI-w`Vb<^oI83kj(wm zR?hE}q`N~)tBHjNrK<6$0_KN6iwGZ7;s2;Y<_Dxng;#$-*zPsY+C zK?|F|r#lZ824K9zWcEA|-8{Jr&2VUFIcPWdxC{P`nI?dqgr+F$S>``Bm?=;xfhHfb zIKbfBp#vtHjQZ{CX$MZZ?+0f=xrEc@8?C@6hH7Rpn*erptp4caPdpz>Ui5o94{<6i zimKmXJW($J^cDg651uJf-rVXfgbsH2&P9^Ketx59CBPq;;h?W|Nos|{E0ba{U!9vt z7R6LSp|kdHyc0Q|5mFR7W8Db|(}OYNDaET9F5)uctqZB_Z55PQCK3=9^fj)I(fMgR zJZB`*D}m{Fh<&p+M#{KYosci;%J_(V$p;x;V$6ZWD{d!EPsG6;q`^3O5N!?;>750m z3NP`$34qy<;;T@d1TT5>1b#%fJ5oiLkDNIyVcx9fyd{TTp)fWfuGJ7%U36?8 zwR&fW8XfMeKwY-{FZg{{hq(G932t&W3N78?6~LgV$%KQquC<|7VAxFP6xC4OseF%m z5eI3jM5kI2hmu27t8fv=eH?O1If@zO<4Uz+ri?nBBGu4ZwC9{an0Vc41Y~}KeAv3k zF_EMHU6dewvDE<|e}XFvqs;}U#-A9tO$q-T14M4Q*s-30im!+qT`VTM^OH1Y&yw5h zRKT>>{;v5bY;DHjjIzA?Nm60w1r+M9d?Fcfip8qUQS%5#;sU%QQBlmJVS;bGqvs6? ztYuWyq$RpastT$a9TgQ`k0td=def#4R+v}paNQme~a?Kt*asyC=0EM*|$ z*p-&@6gh#f%c<*Fvly%7q@?SB+g~oDTb9X~mq#W#-f=YdT=>tvQeSw#U$I=ixNzA3 zy(F*09KhqEuoT#=xs&V!(n=*T@(D#kAP`SwagPzdi`B{M&unONU?&C%Ses%`OoUgE zrVwq&xj^3kr`1Q_Z*NO3C58Z+51=E5EP%qZP~E7LtVm5uH6D`R4622SY6J;yD4fu= z)Jz#>w{ZC@z@#N@i}coPEI<$b>lYyLcDng5>QF7b)3I-+*K}4FpReyboIYv={}rBN%9(BhLQkq7J3oxBjhDm2GRP?VY4(J#xT;sW?^LCmTwhernV63*dLn14oil z<2=HKAmj?7LboMRm@-gtkb^o5bHR|7e-9rRLu8eN8rV4ub{vVnLX>;u;D;ooGpV=79+JL|dRqIW_ z1;<00+jw(W-nf1A-Tk`n zbo$JrXJwLlA{t$K%a0cdm~F<4gsqV}mC$O>N4s(hw1mYnwwc-MVpIDmpUg$Pki_b; z&JmMN5`E_KYCoccgn3oShW{k4PI8K?Y|>nEnG#MWTuS^y2QT=utyRoV$YW{vLINYV ztSKjFrO`68+F9^rx&WO-tSe6Ia0bs~vh`QBhwNjwsN}otaoitpS3IJTXL)`bO$lW3>3kSBllr&lptB9U(ATnqmn=kr#)5y@N-kau~db2xQRA zdkg1TG!ffa|H6!=h!P1~Fmz2GVhfGGyCbZjaz|Rj#Ehl~rWL#!4Sf6$(wk2y`6h*i z7+MK{0R%qy*NxI&QwS*k(SKCtcb~p3kfBILCP~KOE@9Ylru*rG;ki@}*X4u6d;ddT zH%C^Tko~Z0=F?CJ??c^Jn(RiCERX=K5c7bp)pgU;`p(<(`uoiYAH6QnN#96Qss99Q zUOtu!I?QEaI*0>2Rt*tny*4tyGEj-og z6*R56TcfQ|LDbxfzx1jPE;HU@?}2DlI9Dl@<~A&^sbz#C2Ol5345&(5qCaq+4B^94 z{%@@NySXAj zbFDKi)~@hi{Kus7hn>3^%uD%Vh!>PqwLg)G8BHyB(vza?S-H`$2Ph`HPHlh{9dr6* z?P~Xoig7L)*cM0G0pdq3qRKAPw+hc^Zf*B-Y*@PUc1Z#F@@mKx#2|RQ`AIkVwl6xut)f8&0^r8q2iJmZiiv zNhTK$JJ5ca$x^=0UDGaw?QWwz1gcxn5ZS$e%869j5U}n2&AN*5hUa6z+p%WQ6}? zcUPXhs+e^?_e>aqcl0?_Y%@u&Ml#FPPhT+C=L>&{wcF{)Vxv>Sj6;wceWzmmC zka8-=cSTq3uS6H7Xr&bXx(&==nf^Tv+?wfL^XYdi|KVrSswS_;k8II_e-H$~l-W0H ztjwk5?{D%S0CkSLT_wJt!KXb^ z|8hk+6$X+hfv6#5lrt_7w-bEqN##$%p0f3nnO&cEOqI4cDY66vLR1Py_c%V)+++%$ zAZl^~RMqTXCDT$We9@WfBJI~mKZ++@Tp<^@6*iSGjH#E~A6W(K(xa)#**`|`AC?^Nk<5DjDT@}0B`Fjw zSPJkT+%G9DRl)1N~NE9-_}U}%t9z&?N!rbg8x{hEM@dv>x?zUlc9 zG>t>an;uf|s|u&6jW=wq=VHwJ&2lu|1tKd=XPJm9iv_1ouN*FVAYz+iIFy`TQeKg+ zmq@z7V{>G91O&a^!k2iu!2uUopX$KPAc4(dx4>>}hAee7Yq5V0BXO{;=Qr|4C(pvP zUFxu{@Q;{$|E)$ooi6Nf{iGk-z*B18p(s*d9pIr-_$Z;t&@>5EDN^{c>0}sG?T6|1 z*vIzc2e*n+yeOfW0rsFZpt}J#LQC=?o}dFJ6^RMWHYoQ6MfEiQrskFki&CIPr*-pO znOtm_YbQvxc36u1-vSj_GOeJv2Fh$ct9dQY8ts2{mVcRJdDg^OvnOKwLdYzjJR=}8 zC=aw2ln6(iWx0P`HowZoL|F=kVpL&EW<@)2|40c4Z40T`1D;mJ;VIK#a)Gmaoh?p= zEkFavtK|_UrOcL?T%FHt+(xo*W|8BBD!bJBR>wGHis$F)E;Ttdro{d}WY5ip_^vaV zNo>VcsD>?G$`|(wMP#lDz|QPf`VV(%U@M_rKAK4iM_J5rO!7d&(gjJ1X(p9;4c-o}GV&b%{0FT9(R=(Q^>T zfsT<73P>)xq)D^}nnQ~av6xD2w~>m+bibjp@L_4dD5Scbqg4?Dlsn(p4K}3coF8}v zS!1W5YoI1VXqOzrH1Yb|uhblq9#e;U zRzcgIBhh1(5)89x3S?duK@G3zmg(;UqZ=k?r%=*B!(W&&9u1GwetxE8T9_2R(7vVsbWSuK?FqAtGRpj{W*NO46axKT?`{suN zSlNdsM%$lIH(hPObzPd?v;kSp!K1eP@Be@565%JqWG0-M*#!LS*BjWcU!4EPQ}6?1 z^ps6nXe2-|$ao5ENNS?s`Z_FS9*ExoNW4S|Paa1^m2#Z6gz0)39#@eb_!}cG9KV){4Lf62H+4i{8S;F<TReP-dYK@>%$QAR&sd9Fa`>?ybhGM{qJ-5*|5=<890^6rTaMs#gzQYuS zI#?G6YY#=aFC#np0NWtSpo+7AiFgZn4rWot-JG+=DMu6)iU4=1O9A}|OEM1$rl!I<1 zvE1lgS%(hAI0~6+yI;aWcmdx2VbgS9R2k4on?#BhNa|fjm(SPX2iRkhARKfs^K)-b zk!+bLr^Ir5Os+(RMKNXz8R;j5E9*WA9hq;*#oDhrSp zt1lMO9Wk9uw`p9z+5etx_f3(inPZb|I$-uAJ(i{>c5})gXdS;ZUgPM z$;2&}ZThhkBWjm1u((C}2KPJDchT-4aui#fkUe2#(e-{Ad=qO|hI%15Y*>@9=%O98hDPMY)aWQz=-8mdv=)Kz#y2obtp|<}* zTiVf+ui@(QzF_lGZBnaV@c%6V&`uQQ*6O74a%;D(B z{6&(oq0<$Q)_C|n)2$swukPL!&bI|Vl8;%^RG#af77qNexG5oJOdE>R^?Y%$z>S`e>+7$Q+P@(p8NUNG9}M4T}!CGl4LB zsHBr)DKP}9ndM)aU%^PFYnU8MqeMMEid1y4mh4SIR$}TGL9N+m_2`A=`#aYlwx_4+ zAhJKQ97qcAu1o22FAf+656U+VwV2i@Xy?{tvZ-5b)kC|=QY{*mk{zm5gnEVfnIB^wWzQStxzCU zR_+1n7}ZAAQxBAkjP*)LyX1$X(!PF(VFVd}T5q;_*Gd03sQfQHybue*n*4)vXo6{09x0`UZuOgjGH!@3-RO)GuleTX{8Z@NIXJ0 zSWC({KM^Ef5c|EIVhCm5{l2APW)Sy!5JqYQHs_Y3y`aofM`*)WVwh(wXi#c#fMY&_ z8vPepDW|pEJE9(VImICpfXTywi3eE69Nb!1eOfp=+uZ&G>)zMv&|5x+!EbJUd$2LK z-zC0bQ~}k0(EOVs)S)hzwjr&7S^~BN1-wXcim;@1;T8eE{u|c`aPRMk?7x0tx~CA> zKvSihvO@d(7Hu(OgRWqM{7)iTT-e1OCI#CDIu4*2pXGGTd7Qm-&3$!L)AQ{Px67&> zmH*olgb+9i!pgkMqDtd5|7cr$hGyrdOIOH!)gkMw6pUx713?5ioj4TB9P!G>q{jGO za)|KzXF8WX{FM42TSeF5VjSjj#7V5)*008l#w*Cmygqy=-bTfPIcUv9pZ&=kLM7A7 zcmYr^*tWut{bUi!b*FBzL<$BQF~4k^E3~RvX!Gyw5vm5tr^N45v1hoe93Xy@0M;J3 zE&sOe2Mh)WB{Yauy@@R0g3Uq06t0Ql#cp4Y~gw3&)I6e-?P70!oa4Y#TE~5umTYVbFoDUYu}}* zMG8+&k5i8howLqbl{0bNjWxAw^C>xd>MJ7rF8_h42&lDvXfpv&TE@!8K;m%{JfZ7xP8&utc+A(PgQXT`KLKO_a?n(Ry+LS?vDqjQyx{1 zPVwK@`5$&tDmoNzW4KFiFnmc zi~pHkny(!g0l@O4==$Q=L*L=;ArBbedMJp1f-SLdNiGzvU;BVfe?^HKX|(9YJS_#j zKoPuPNngcu1cf<@G>9CHr4=9uk%iQXDYNTkz|Ik2pDh=b4r@h%RNDAe(TBqys4qG@ zDr!*cv^p{ztA9KEpXJ$znn?J+37@I$>moi+-@iQO{i?B>XhVP za^)m)CTpvDK(O%S&hR4JmED15#!U-k-Bw&;`5sMNdcoU~L+aE4NJlth^IyoPV3O55 zaS#wQ2fu%!vC|+;?jtp(DZc>jpcvgg(%I-{j{S1J6)5ZPkvFd>%OftsRM5Nn#~XuvfB@kdPfmVwI|A3=fZt5@DS zl8tFCh7Q9&DWNAGWRRgH77hr~0$U}mK^6WH4BHZo+3rzL6HRH4^(zBzfzf~kUcq9E zR04jQg(P>R*=78*eRK9}KnODLJnzV1#)Bv1N@wXM5)vnoBwiKHS{1*gs}Q=|9b@xV z!Z^Y-(Lzo&etD%>9_K}*0G>Ls)Y0^Fn-Z z?AJmt9DR9|v_gtQgze;qOwu_$lV{Vs(Xx<~A9!^bUU6$ueIE7~hsAXkVNmU!RsQ(j<&!w0aGi?EOJ0z$^0Un|EUN4 zA8f;c=|+Ws`mbL_mnpUo&=e`Tjz3447Ds3^pa<6$0w?Hwwg3GA#35AeF-(D;fbIqS z^|NC+gor#9C+jz*LXB!sCE=QMx2iP!$}}!5pv97%DtOJ*gmv{Zdb5Ehk2f9q&g;DiUABac1FOLJDq zkJNQm2N~r(MF&M}Lg+^ZA2{R0)BzoUyEy;$(mdrxI#08UPBUj;7<)AKL6il|%2yVE z2>9Lg)j=P+k{F&_?ISvERm!(ckwA*+3+(tFbur-{XtWVeO5rK%`v*(nA~Qb4!ejr3&sTLZSW%st6WhkohsdVAV0DOBWsE z+jA7p%sN=&cd=oyzb{bV(Bc9b7&7|1hNX)wc;+xmIwv#~2RtiWCJjv4kt;NQH7uT_ zPSAJ;n{1CKQ7WZrR20ajjRkfed2szRE203kWyw_-0Kzq6>iZKrVJXq)ADo`{=ww-; zsytI^CSi7}UP|IZQgAuv>>M=~k9Mx!U(vR985KBXHqV4Rfht5_7N-Wta0zsGQQw*j zqE0WzLQ|&IR#4*Wurw$NNepxm=8tnwFs4!4h_I4OPhBoAfK~9z)5d|0pOf~HM~Seq zTug?lTt+;gy)x&ngv;1x7<3^~Ke|yj&!xz!B2FX4#~^_x_0|+4cMJ6$+b|7QbE2(W zs)I{h5u#B{#2LG_GTsNYadlU5FN}g;bq6o< zThF;RSn8}^h>IaRpm&qo1Er|i;lmi$=e3d`Ko$x4nN!8ek^oW0W8Uuqef-VXgr{5{ zYVuLUE~6dNDycsRx37!F-$S~iea(WkRJ>blkus&HvvAxS0crw3uTS!~*TmGOt1{b? z30WW&vNVV6pC{2?gw^xUM>+>j@pH^=BQmduESv*}CHX09l@8Fj?J@bqe>()b6XBka z)F^C|BOyjFpmJ3Y%8d!(RsoIRcRR^mFGuSV)wuIB%!<0QL(4!JIx;_t|o zlGVLbDKN?N`EP&CX()Q#bg{51!LXmNhU+CXIV5q-IZaB}Didz{Yq4$?AGltbh|Lzg z>nSMPQ^pSq`c@psZi;jl*isOzp@*a-jb&B}J6^K=PBQ_=74P8UhbP!F0<|gho{^>$W6qrYCP3FfV(Y=*@m~6AR#qkWj zTeB)^ovDDYRkW+N<)M=^AAr1=x%7f>{Yrh`oME%*f%U{2T>AQ?dtkMYr77neB)9S% zLtLs4?zGUSztLignuAa$4&SIV9IM^RIsHY{uj!{`= zrG8oeTUoA9(_&>A+}53PW?xOxbu9|0hxB|VtX#lVvNF7Sq%mj4A1w_c)!PC=P!0Y0 zZw1=TQX~{ZGmbcMQ3y=NzluaPtOZpzXI1ht#pGOGk4pN3SV-~v$k3kTtA=D%9$3g( zW3?K%M-X@}v4}^Nf1?%T;J9exh{`-=GS}Z|+ToSF^I$o5Z#fKmE$84b2;cnR`Q*OU z)V2WvA;TDFW?YYFIv9dE*bjqX-*ZCheFe1cm7u4OB?LU5uODRs z%RnUk2;N|rL41RgS|ZpIPi z3B`adsP6mXrE8whzws8HfmZ8z0m-h1JC)JIkv%dpNy&+gI7Q(Nb1PM{wcrS-2>9!E6$1CctQX%q2Zh3+VbWt$1gQva_m;KGzO&87Fa{u zD*HL%K+%x%+Lg5XTeBhoyqcSY;Q&D0I7YJpBJ2B`Q*EM||@ z`dTc_rGU7}V+rv_alg_;$IU2Ea>r2Kfl4R**nYeri#G!rjwaNJ_4?ZGRI~~722dMa zo4j#X#@QVbyrJF3Tjq#&`T%gRba=_vdyucZPowZR!5;|M<1sgNAL^@zTK%+qsO=xp zFbO#kK(9d%2sH6tL+-Ch92!^1%!e!anpfy9ci3~nR#LDbp_sCD%d>-SFe$C0H>Duj zl5=(ErGVVvXSE?IPK%;j z7KIqI1`BQf56X82(Te~vkmvrmflx-a0L~#@m>qC*zj~(fZ}H|6nREx6MD@>7@G@&N z&4i)pIoiH{rOg*06EwG~K3Ut^ zvza2FKIVi+yBa_GV zRjco!&K|crBwFPCcG72VpQxrT==&;1SKRBLSYKt;JuA1O zqIoYMbS~FdbbtmKlJBcTxSE6CHsK4$jY;cN*xs^UWm$d&iwbMIiRo(hT+RByGp9?A z*w*t$E*6VO6P_VUN?1GOEfGcZ;W_5 zrjD&IB90_qM(G>&*vd!QmoO|Q1@auQhOt~I*v}Z(QbUv?UrX7hdrw7ylNY!J8&!r4 zNuo&A?Pvx(h8?vHD|=N$nQa*aS1lWNU5WiK8@mTW_YsYf?w&=Zw?7)oI~ zMZR43Kmg;Awm4Wmt6(>5+k|Ienfc4w95Hu?IwGVyW=2ie*KsI$wLI>6NyD}u(Ds84s!6x$W3mTI}Q&)gWU^a0+sV?3?b#$s0#BTFj=&Se0LBMPy6 zKlUd>IOsnoF2;?-`p&td9M}g@B(f}usRo4#MwO?}T1Rlm>9;Dg@o4QB$IU-=+R9Fger|H=qKpHh*vE%Q&(EFG)wX1n+Cib%pKm`=I>w zkjXbi?fLq2%zJf9zWxV2Dh}+y`~7p5SgHNLIm+Z!X#3ytEe@;DW$K9kAyQB=!VJWJ zBoPVNU%wds4}&Vt2!jKFrtRW?@|zcwm`|h%)rK;!0tF%z@r;Ymlv@z;B9JkR7rYh8 za`?cFhQHen;P@L|!0T>+V#lm&>g;_ZASQ;7W5*mFslKw#$w`}s$TYTnUfK2hwye3M z`R91Or=|x~|Iak|UVvVRDZyVXKh%<{235QDap^}mnapM-5x;c6mh3R)73xh0v5`xu zNLF;Np9upc)jd0a!byY}GDz843>= zTY;MXTB8catv3p}e=D|@v-QvVS#uI(CN06{E;I9^#yZv8uY{>{ntGRUn;1DW!Dm3@o zT0i3<0k=y41m3*EVlRUzh^AdwGhd3-#v->%5l4O7y>u_qt6q5gXez(j3mjGuyCv|N zgyjDMV?dn0c|*d<*vZ+M2|GVxO{7WFn4rE%k6C$#pIxO^oOUQ}vD+K>8kY(nkV@ND zoO1&`@ab*4{HbvkrwI5X7tZPm63EFUgfsWXSIoPXJT7A7cz+}w^k)3Z^qi(VO$ zI$S!aXY6ys)bNzL43lNgf>@y8F~jSDKnT+h z@7jKf_ONDW^cAdl6D^m~#?l+X%aCQEy)1N=g|4XoGJhgG#1`D>;K1ek2+9x8B(Fir z53x~xgw66}Y?Ys2hx}BzRdQjc=hjKjnIr|mYi-d>X!Fw$5wGE{rLamNe@3Bxjz;+f zTIH9EY`1x~AHk!p?K%D*W&-?sBwKy~&5R?#a;&|_C{Z?flQFOU{?L4F5aeoxi$ z1EuUo3g~Br6fN2CklI`%o!$jF7$54WR&1OiTYr|SYHG9(35ygl&E)8Af=j#>&@&<8$}#XK{%Na<%Ko6aKV5;RU`+3@Oeov}EZdvuPaZdkR&zEwn&FzkcuHZf% z26))VL!5`iLRwYlnm!n&A5CTeZDtKjQ-4Q?NpDYP9b)D(uP~d)fhSy7dR+G`Wl6+n zqPGawrxfK-#So%v<*@4LnCj`*Fcgi^JyX%mW<3IC1L3bA{FPObkXOh7dPObJg~}lh zdVmuyU|Z;oAmhoK@nj|5Drjai8qF58nyriQ7PmtQPg8j76yAZVc2H@3IG5I2mtgu2~}xsv#eGL0027_001|aaR>_~mo{_{ z6_@%q3>kmZRn$r-(bPy3kScD~13AFKkfb>$R;|6*wQlWdSJ!S9+fKCG*u`Dy40dhj z?r!bwmw#dZ#I|SbeZL$+z@+H&#P9vy@BM!7{rwIf|L^@<0Jh?vl_-NlhEqW~ToRU# zYbUg}xRw}giw=$J!50*J z+y32YEj4Bgn^D^Dj;tTh)0Td+)3VaWP{z_Fl%+-`tcxspvx9Y2EAU{s1ZP5&aVP@7USS6U&sg%x)dIb%FVH&3eLshVv8E%UV=@ZPg zXp(=?tl(bedyCl^kx(9rL_7Ogc)fxREUEN`2fL%8qxOLt_bF)MgJpVLpU@LlpRLlb zAb|TN$Rj7Tct$rV97jTov`Il5UvPwb1oCDDpXPm~jV#!1JfPq+*h2S>`TJp(|Ez)s zg>%7ZG{TY{3btbhNe<0R2KnG21-sBmnudQeBNCd5BqEoxU}j`QPmB0=DR`K{%SYpp zNXNDLQ$Bc9!6DY_(uOVLgkFh39Fc$V zIR&4`V+-mzS1%-}Kc3Oz6c2ApWO223_y#L*44RA~1;eaw%_oP40zMiK$2bGJf)Qb1 zXK!!k;iJKWp-^{kC83RRZy6E-Eq77$Vfr`7eRdpi850T;NJ?m4@}h(aBVo-MwKC^f z!brA-=eQk}cpPaNrUDBY>ZLnHs3?C@8EW~umT=ft9AYh=P;e5bBzUZ`w64X%W>+Si zrVnceA^X*&!$8sDd-=0K^tX*6xQ3rFri^$pT}jkYv84Re2&y*mtM z3Lr?Y5WjfgMDUcCEj$btIg|7Y(T@sPI!!<7iSm{s;>tp{E2)LP%I$*JX#aY_{%f@V zdcpo8?cXTaPtyPNwZmP=A0uL=&keDzveyQCU2U%|_DV0USRc0cyX}=e0>ny>xmf9` z7ArlVVm)BX9kka&f?r3!a$F+I-lQRLo@|qe^N#-}B!3_a*?)f)RsPjktnhoCS$O^4 z@+|6BU&4Pfznn$mG%5tA(d)d9HB)qc9qY2#NX!piS@@>$0H3txPCjLyRA$jWjRrp1 zI)$2o6L%Kd{8AP>{bgAM{a(W8_B*oJW{&7#jwh77#RqX}=(|Kk)Ys8w*P z)u>QCs8*Nb9(4uk)f%i-S7M#&ML=DJ&1wT4R2x3AOI5K~U5!3<4F*+uWz{B3sLim{ zdvQkHfV1jGoKx?^%c>6-R6j1N0lclY;;Om{ZYo0h%}ea zQto6KZW+gA3`+Ema#CMkOPE(lR-^`;8b;phzk#X%{bq1@l7e*umo`2OAUlTaoQBhJ zEgwP`o3Cyb?$zehWz3>5(um#01qCjyTYm(V^86o0w36lCvGkk|5%`)tTMg4}rTtn>3{jbRl{RJ zeGHZAQ5sgq(4r0%sP*O5`fRmV#7(J%mg{-_o%UR)2$0I)44z)>jt;jvQh-~L$F0b_ z^OKTr&n<>C2yT1{xI?&M!=1LH(@JOqlVUIh%ch|E8JJU7qz0hXK3c`c7i zbpo=QfJaTDQB6^l%mVeTd4Kh-$YN$;ly2fZ+m2nfTS_C(!!fRav1@tHa;5b|0j!dT zRq#{sa0Bn-0~>9e6!1i^B^;k)-2q;l>%~&O;lO;vatVHt%s)e~(o^uNPYWIX-0i%M zT6~C~2_3b#MO2xfeomA_=slbFA{R|JX=-;gMi=MiENObKzzcU?gMS;p$b0ci8*Mi? z4XvJlL-@h1@gBas81w}){agX4ClBhuujrd22m0%xpzWnVUnJ0%N`h{&L4RX|UZ!|) zB$^#N)WEH);3RHS18V!EJtZ#mKVK$I&;Dz1Z=I)NeFY7)HmR=)bxk6KYw%kN2PKAb3BTnI_&*nc-&Pv_O@e=`B>avA z@DBV%-2N;6Cf4KlyTG9@Z=(MJ<^NDi0|W{H00;;G^g9Vv-waQXrwh^m0KCxw04JAm z2n!^akU_bE5%4oP?L>sTp7=2lbfX2wLVa8M<$!t zZ#mxj!5r}K0xY;1~4aBXZ zxcxxPe--l(k$7%%x+B&b?@lzw2NGE+W^Lb--uO(fDo)HjJ0HXXu@Fn@%O-o{+09;J z95cpfe-HvRertB;+4o_bul|llTF>^ zA*Q+NY$BddbQ1Uo5KRnDCDV!R!7U(G6L@T2CYjC`!);MUN!EdAC3-LG#Trus$;8Iy ze|)^-I0CH)aU_98`=D5Qz=s|UqMe}8j(Be(8~5YmAU1G;Dn6K{6GVbQNCBB+6CL?v zChfzzLG)1b-Bhx>C(o1F7RO34dAr`L&ZKkscsie>Y$*`Elr4&rDBqt=ti`UiMW(pd z^(eNeB$VxV5LwDLQfF(9_x52Ib`vZQf1;l{&FV-c`zT@~h)rTM5++47A>K6Cn9Y0* z#0lc-IP$ufA?&5NUY-Oef;fqCIDPp7Hs1nqGDVK)N~ZFOYyi(wL7Yao*qz8jG=AR( z@g0gQ%k^e5`5vT2B19hVGeMli%~GK1cq+v`NwBj)oI|j(R6Lh&_TdCN55)Nde;Prc zWvN8E(<8qNL0m)-r!ToFkwWsP$nSx;gb;{Q`*1Y!nf@%rUk2iGig!04g&o)26Yt|P zz7OI`iiXZaSG+%!ukGwk*$$;^H+FBaL%R&lE>ZUgZnak~`bOBRXK z1bZ{nfencj%A1Hw!j6i(6U1HOZk(K6zPeN;vpJcsA+AeS{bWuuW71UOMpi}{Dc5wH*g87e{;yln-cjr zGMP?-KMLY8o^{PFRV{&hkAwI*#g7Z*i}m&L_k?Bq3v&bn<84eYH)e2+7X>9=uZtII6 zUJ@^(V3DMFDdv3DBDRWGK>V4e?<6%g&3T-xy_nq}SL%q@K>S7gRSi-L7GLO!)BnG8 zMcZ)tB8Uk0#v35s6n|rO&5+@ZdQmad*tbCZL%fXy#Esol9q;Htf6jlzf6uvw)~AYO zl-~vMPw^hk+q_@V?5|RWE&f$X0`Wv%SG+HlQ$7C%@ezrvZeeMr=>Gxn2}Ot1Vop*2 z0r43{Mf~-hV*eM!7aZ%$3K%OTNP}V_C_xaw0vRH}2&yiSWvjG7I?N$fR;_EVk1b!( z(o7j#kWpHLBP<@Ye{ANZMUDVjMgr>yj$M_>B{kx56v)v8i87=ilkJVuQYXiP97plM z@m0MWk_lcO(~Y4B*kPr zmE4l(Lqc*Gch;khS za z6^l{{uMrdLOXk4RYNgnBc#}VoO2zY;tSf6&Eh|9ATGoJE%X`WGzD|;} zNR(?vGO`Xm%{`y;w1HeNk5m#`HP7n0#x=Mtqy3~j8e}^GT^~sMLKz3Sp*XtLm7OwS z%Px@J5=pD9u**VrgApc5?LCIh zR|Uv}f9xl~NFPv@!)e5mdn3qA1k*eVTSu{5Kz@y4?T$jTz7FymfjHV0%acHUGZ06c zRe3VVQyBS7{%Ld9;&89 zypyE61;be-hvZu9$_qrbEiXiA>8s}^;<*^)fA@%Z#v_kLrq$e^?TU9K^cICV*rgyZ zlb0h0L++PDQ9hC8X}duSrMrL0yrv?)5AsSXVnQ$O4{$$&o3TWo5LfOms!3$7rmZ!- z$!kGgC$C2Wp_#)3-4RbESUbX0dn3r3cp2f1%UW-C{1D_VEVy#?3Z5bqe=Eq_m@oD* ze7X~>tT({>s@)5L@_-k?~!8fVaWz-YE}jZcg8T(7f6ZaFM~ui{%3s;?X^_8`zd=GSaDnE{xqPA* z$0(6Sx)`rGGwxN8^QH4ju3YTM-%3%@kjacm5$AatnR{2+uugf7ICQ)w0GM({vj_ z{s!{z1Q~;nW-Oy8n@K0P#7X4AX)d=>EpLN-hiVDa@KJ$={3powXhb6$65Yu(DI+QN zUm!oA*bu9mTqNgzgZxN-Op86se+G3)nooO{>H~k|C=Ia~`3cBR<$rLrX;iAxoz!&h z2;3IWC{E7$P5C*<|7D$7BHhU-$(IcQhBORpAJSOWKs=cuy+%tsi$RnrX2fE}J0R8X z+|!FAh9#f0jS#Ys(kZZkh7E>eM6f?``=WKNF<1W5h=Kve2<)JEHXGmEf05}!Vy+0b zyKw`F#EWAkqDWnfsE-6=lrfqVFW7K}vTlCO&gSTjnlrS=aAb|KV2mT##_1rz9%UHY zn1Iw&tjZ)2$5&^%#&}~AvI=9DA+)TKC)Af1yMi&rm`Vzhe(dH0N~9~1bNeVNYIiWo z4U}a~9M6_wy^-YXrY#-{&YUs zo2cE?fl!=_jjB78>9CC z#Y>;D1dKyyu2>tA=}yO3inFpW(>Jut@?@^OKfNK2ICUgC=TOFFU{q7aa2M_!aFSzH zwP4f{51A6wCu5_r&9Pi#f1U(HVnfCXFk%J@xudD`6O%!AJxv^Y@=dHyAwx8L1&iY#o_QmSjKUe^@Y%BUqV+6?UgaFBs`y zw!j9_=mX>UAgs1GiLDu60?vVvC)g-2Uk_43nl)=%jR7z=(n*v{bX6FV&0uU{C0=cP z?aJDQmiD1Ta{?G&4-QSNp{8~n4b6!(G$%PAr!1aadXVbX0&QFm#tn4N zIa({{3o|@|BYhJXHxmh1-KiK>a*MImHf{yuHp(%Kkt$XZj-n;ko0D|fN(J5y#vN2z znFr*_#h|;uxSK#DJ&>L#1ltD2J?eN?!@QY7!27`XaS_m)Dg=B0j0aVNy`27BLFmI^ zJW^Drf11(^`zaWY7Ud-E8%=8Ls>_X^f$=yIw}}Hosh^&9q{==9yLx+Ab z2_RVNFTwa#5q>y_xGQnK{u+$mknE1l){I^=bQAtnxnr5<2mN_ z!IMUnkigG_@q)+k>M?~vlOQjG@sc;W3F0%!e?NioN-&FR6G2`D!$ zk!Rp&Fvk=F3*Bgr19LnHDy-wwiZF_w2<9Z(KSRzJLRKv&z+^CYHK*w9zo$5>r&F^X zoekndFn0rUcjAO0%!NB?jM)RsJ!$+#f988==i<){$DA(3=dGFk@_05;j$DeiqWMfY z9mAGq`t!MDXQEuq$bE9<@ibyU^ir;hnd7cX;eNWDq%wVQTi%iBMRBk*SDvI)367sJ zv%IT6&6GB~Jd;HbmFsTK^k>U68`C}zYsi(SGFS>eG4p1|iiEyIXL(mP)2mCHf9)bm z;LR~sk{G~tl=onrbg&&LE7#xALj~dbxGGBu$<7%wU97z~gF9?LW)5zO&Aq|ghql$x zTu)}>+ISZEVYg$>r2fkEmHYci%#UL-3(VP+7)5M4V5F!yVD86@QU}?tEU$0j?s3g| zW~FV;2XldmTh)r;A7?P#rRf|pf7jxlxR=;qsa+JSC(Ql9Jb;g%yHl)r&(W@%kUI#> z#jF-(YA9&s3AO}G7P+HHcx&{DDa9`Zvx?$JbK4u!O5dgT)Mho9YzQ(&K|OVt2d)Ei zIe}Ggps0~YjB}0|BiRiHEzqBic{rw{PS*Ql)x|5pY+#fzc4+0Rz&wIrf1?OCwCZM@ zNMfpEt|o?nRr#exsN!K#VBHFcV;QvAO~&5e2CP#lCO$fSELp#Z@$y*ugo6I?`h4<$W^+ zX0J(`{CHnqYIA8#nQ!*Re?q9)2j=l?f3v|efFNvg6g!6C{a_B58?i_f3-UQK0YUQG zYHkLTrDeCKc2&!Y_Lkb_7HZcCV1Aw09oYmaJE5)SiC~^Yap6RoqA2&bz&x3?_4Tz! ztghl7ITg&)C{?7BHk)-gZ7KHKV19>Yl9kNW(t((HCYWsM5mu%ie^l7nV6ufrbmi*$ zmRNJu%2oArx^A8aCYyJZt!k`qUEbKx-n_E0v1Ns8UT9uqn<$%>o8R+<*dj9prR0lI z{g;Bc-@FXlGsD|bZ8fg|^ZRNaP#tS-Zfx=!e-)TN;KaEOl&@&1+G<_{=CzdAs9sA+ zt_PFF%LuYB-0&i|f22e=fyrWJqcExp+;KFJcY`@-Zc|4sn#tEKlVXpO3&s%rw0SR>_pu!n z@mUq$+}}q`0Yz-Nzj;5H571_L92Q=qtXyjRl!VhmU_MOPf4YSNBAD+dVE&YkZ@N=; z8#09EV_^P_o5gcvmA1Me$j`xif>{z$=c6;0;qmNhPmcO1tXfAd)|e@F3U$=u3u9`6k(GvF2`CDJeQQpvuD1{5zO$abt!kXbAQ;nD3bHl8IF!Uv!wU=a&_( zc*%QUzRxCFeaTIYebu-KcPBdQmJ#R!Fh68cqTw1!e@fWckHGwxDWw1>j6MPLQ^K~a zSo1^e{|wB}hY(+rpO>oq0xZEt+qeP-PWRup46sZ(moj_j&ZTe&tgs5tAYB>--$v8?1eF{`nN1308&9&*9l%?W^;1ct5b_>iifstV*!vvynh|YGuG| z!CDB`B8nfWIxJ|?U>yL~fdq59Q)&x{a+0+etb>`Bw27Oywo`^fz&eyoG*SFZ_Tg5P zAnJe;2iB?rYZ;BVXTYcz9;*hdT3$fndUK0$f6KvIL2*vb+tgy@VPGB3kqK`zi;*kA zYOor~IKbP)5-+b~>a>mki;YI^? z%wu_0>o#+S#kQ3hmSI33k87p*@Wsl4m7|UwpUnASETWc|`%cH|mtr3Vl;;$rs8f_w zp!wUnSeiIwh}MbLNw)P( zu)al0=k|vvTs|FCC-R6K)^G~daHL2S8f3Pkk zN($q0*q=%{7A~6$^%fO3c%9`5GFvSgFzk!+F5Eb^G{veKme<#obE9bgV0|Aev96>; zruEpnj`ag6rdFl+$kN-l@dB@{XHnp{u0dg>A%OtgX0krNI6-+=GMi(XzYeVHtsAfb z13XRCS*0_hj{d1$z6q?Gtsmk7t(;KGJ z%QY^y260DVp+Fa&q1(OHx)-eb2oW>Z&_YS>rzBU>+k^D>5RZpW`v_QUf8uH_Yiz8i zB#%;($2dtF4cX&T%vJT4$GwVq{AqvP6CX(6hM9B&xVV=uC?ANY`bk4_x%C81j3Z(#P>{E*`Q1J-A3+@!c9 z89`b93)UBbI5L6?NeCH%I8v>IEC}&cEzmNGhe61O5F2rh@B|ef;zB6O5Kmh1AtO*^ zkw+r;2#ti$DBhWSAqls9zJB z0HKMYNrXZoA6zx&4To|ACeU<9UK5%Op%j`^JFA;> z1gwEjEeq-ee;{e}8MYikD+o5W7)BhI8+I6k4rlFNF}yyL=_Be~2_e?ajYjHh$tID@ zq!KxG*9D=gAjI0aakyx9_+al42}^H=P|J|o{bW?Y8VIow=h#5;b@8-cK`VsX2tFZL z0VW7kaU_I}VpG2DtH6X*NIQgBLpMH93Af*`W&?y+e_uB#SPdr$RFr@atMDdnUyLBoP;tS5236#0u)({c^*Rj{s{Qs zK+zi^v}wo)_{j*q1wvm7oq)v$2`ja^JCi0Mq^+$@O|fs_Kw4Mgz9n=Lgucmpnm*s& zz}wS=e@=$bDZHoY^Uk|{&}k4lopm97g<~Ke_#FtHq098nbi5m0p|c>w)}#(@Sd(2z zw*Cs810j};qipA;6i1Z!dPvJOqM2*v40-;MuL2N2* za_DjhT|vnl409riyb?lJ74oWCh0#|-=o&Are;;`rgsu-DrKTsw-w2_blb*iAKL(+ng&rp(R6b5tX1t|t ze+aHpz{PIpiO`dF=ob)riWa~UcNkZB#f*sa4JnU)G2^cw^faGkDM;ZE8Zr3|gq~4m zfyBIX5p!PXSqS}(?-igF2^w~gr>^II=t?}c83&`Y70 zv4!1|_gDtQG$e-6E>f6wm%owGYuP*PAWbda%xu>UKBUMHhdm$yZ{ z^ilMi5c-?CCKC5zanig6p?`$lE}Cp=X&v5ms80Vv4%YB4g#KBmn1PYd`=Ni?p${PR zAwh<dJ_f>L2|kX*0WCciB^VFk30?xvexoSC zBna<93C2?ip8BgO#jX&Z;uYZ;e_$0Q*bTzFhs%|QEI`&fA!^>Th4+N;wD5GCW@;CJ z%Vd%L5O!8dXN6b_Qwibue2hZt7v2A$3=1K=h^>v2IVJO9+yM|ikQ9MYf7%Ge(#tku z2I`f?5I#7(M9G4Fcdc25(xJ-))y6wlOn4}SmxilwOGE6C7Dv6Oy*ykE;Tk%D5BI0Z z=!_EAVU(DPOd-4i!hB(Vv;qb=k87pFheNoYL~x6AXAz8OfN&$*og;CtL=h9Cj(~6z z&ys-*&jh*~BP#Ol z_V0)D5bh5TV29GB3t|fE>(ehb1Uhfg7j;*+6uN+D#k&T1yP)d-&k;nM>tS}6sU_#G@Ue1@NvDh;1S zwQQrevk7_*>1;gMe|Zo-p9dB93u^R`EG~rbMKnkw^I8fmn4W~c2jNQ;(eZK@G$}&p zWe~nRe1%%4cr&2asi~#yO!Qo&alR75SMi!tP+IeH6nY<5P9*zlAbc(Hpiwzha)JL~ zwbw)VhQLfHLaHu&6NGPOv)*)uca9i!3vI=C2yUfa))>Oze@76$UEgRdm_iZYP6*${ zG@J6xpeT9}!rLf4V_YzSBGA1MzK@AERb>7Yz8}I5gdao_+LFj-)CofyA@ML+|F#f4_$CZ&aO{qZI0-f`1F)XZ0)%m^l&T_Yi)Lx+vOLFma;z=OO%p<^u)u zCIY+&;g_g~pf6zBWF0Dmu$DeK@iR*P?6AUrf$(3$ulrtN)&#VqX~bWV zDfWE`|110fiHn_`%K{i+cNA*po1RAa-w^&N{4p-t$K!@5iyWpSh;3wshboo(34}il z{|EbA@4^Df3A3VdKZo%D5@sU<&UAR@TW8n;Y-t-v5Lixi0jybpD!{hD4sp{|w=>f) z!flk_e*rsU(*_6g^T2B*d7G~LJjy=;>@sSY!-TDC9tHMjn~&Z)dFo;JdT6(C8|`sm zkGCgad|;o9mp|Ec>q^%;(LNaLB_xAHlDRd>T#~J24Es>9m-2p+&gYe_4&ky4>}sWSBJR#>ITle1 ze|8;R2c)YaeA$m8SAZR($Ozq8Q@3F;_HeN4y`+2?N0l{z-N|^LET8aB9{zjs*1|`R2&Nm(Ke=DOhHh|q>chZ&hOkAykYNEF8^e)o&hYTff zE`2bFn0FE8-8)BmehsDD;Mm8aWV||^^N?2uXXWY!Iqp2{6xh9NOwzofYE^AJ+5NOP zuU@sPv8kn&j(P12*nRf#$}K{kF6|6)^`dYiz+%VF@nPSld{wSP9i-d+U=NU~f8rQ@ zUQY=dvo(o0QiHw8-fY`j!2TLp?2j*5sG_L`7PV0NvcC@YH|!IYm_Tq<(++N3A@$eU z-vmVKddEIlpZwP(G;&+*Q^7us3MrHqaG@f4MhN!gW*= z$tU&=VBcupROohp-*-TXS;Lf7(sHbjlPt&VAA)_0y;XaNYN6$;C8lCIZ_e=RKuL~1NLV77%Z)|CWrz=>9g(GR(OOf9&6bfBl^DyO!uuOIDtu zp9lK|bqJa1)3Hb{FM|CN9Rl*aWEBEN{t4_?>_4+!d{e%|I~k^s8BvmyKX*GU){6w7>~DbWouU zzMB)>y}Y)uDFsP#jss4FrY!_5R&W`2qTqnKHd(v8eP!dCf7+HtiY^0Zq#s=$Yrtsg zsj~?-2Ar`z?1HI&70#)C6~PnxwyO_npmOC7=g2#Lwy?CMOx)l{VjO8lf_pt5%Z zXLqH~#ImbbFN;+xeD(lmPo{N_uWxLwr2?mevlq*s$c%KGs6X}r<9lK%;WQJR3ck@( z>^YHTO2?Uvf1KXG1I%}R$*`v&%kmA2_nkRllso$oRkQBJapoakFOkm^J7>(C&DKb1 zHsa6pclVSk)_RayumGHeB%Y4&g<7>idf#p!@B!c)=p2N7noJM0cqzytdMBpxdWOF5 z91PA9=MZuXm`zkE8~d?EI~zTjouy8d?JUF8w9VR)eariW3e_;nix(BoL;qIr+tMtXv7(v zK5&kwL36Nvc6maPIdJkc7$f<%gQ{BRat6TJ$V+iHK?e-juaoI#D#5-6X0LMyy?q^= zZz$`xG-((p>LjAfZ*HgR8qz$f{$y}Y;nO^>f5P7$Ij4bhy7O(?B^S`z*;S0n8g=*7 zIRi7AX+q*GaM(03#2!3o)|~^+xqLf$h!0V3E9aaK&ILTKxp*)4&PCu{OiC&{ok_PP zvKgB4mwTm9;O1KmDVx1`cRZQKa2HvA5ns?L9q0Q} ze=M$6$=P@>0A#DVOn+Wk@G+Q7KZ~j&Jg)-rN%(bY)3gfVE~+PEJ)&9RR&Z`5vW@m7vg~R|83j8(0_S#0Zg*w-bNT*W znlyKUa~DmTP&^+`S6UCBq>9*vMW{ONe}(YL&V8Pl9qDSF`yqU~b057u2+l(U)LPp% zZ*Dz;@!?ZY?sI+$4!e_akb^bnHxs?qIX?sEab7UU5UMVl>8*~ZIw;>0;5^Bv``Vx= z2zv^gU-Ch(vXf;$X-W2o>O4*Q{V*l^4LHxx%z>awHUc~gaac@dnKilf`8xIcmO3fH3%t=GP`oL9kljrw?0r>8)Tr+naF!FgSo zi7WeOuMGry6H5$#JVprT@8G=U`~x?%y>T+cNq59?bC&P%-QLo+GFD1^fTg?xvdnpx zPxyS*k@FtN(a!sPcgK^koDV>be{8TfaxL;vIfBQx|8MKdr`0g+ie7d9a0>&|BS)17+iMfOEL5t*a>E%yYNvJGY7) z4v~6oXkYMowKdWJ;zyB2I>cRH+KVr>{s@RPkz-xuQOx(E5ov)4fBP@7nwBrCqSDqv zWL>0{3|0I})P`oVI*pGNYVhw8*^%{9Oe-{p&puE}Z|qt|J(=@;&QJwMLFDL2JKbg> zi^qHwo%Iz|K*gA^=SxsqBXJ04A{$uc!)LU1q*IC+g$lWl9o9hfNfDB1BHok#$-d znT~u5BI=T6cdCJ9imj1TA#z&ebh^r$>DwIG{_m#8GFGb7e-+#K4n)o%TcIc&j{DaZ z>mp~73!@0Voehz5BIl~Tx@z7YTv5vI+K##0g*eE z@t{tM_4}zP!QBuUBnM~{;~V42ya%dQsd<9dMec#ff4!u2p2TU`KN$H*3nofOehl`d zk^A}Ny#xvA+W~U_$b%4hh^{C`hys=A2IhVQB0pitN*%Hyc`+|bM;=9hc^T2h&yfB| zv`gE!*^wutn7%`!mg#{z@sXcLegPsDc}kgcuw;>r{EDKUmg1n{Is7TWF}PR8A27<|Emyrjm>YC)z>!E(DeE%_Iu=YI!i3fJ&J#m z;{QgL?6IN$X0CA}Z%MI~E;Ok2kWyP;!|9FZe~!b=MK6l-v_m1E613wfC!-zhC!##g zzAER?Bzzkp@31W*<D82wL(yca>)aAIeoOSe)1>9loqQ$03L(_tdNABK5Ce*lpW zDbwgeSvaY>5$uMZhCs-73Faa!WmRLWp@ohyNMF{BbmNW$ zcT`|MRJW|LKE9b}h&u+{vAiJW1p}sv2St?h^~720Qn8w2++iXC56 zU~{4mxfp+r!L0{(rP6#hAsY3oe^yjcY$LdsmO>I+iZF}?TWi3rr)h&*@PKqVIi;Wq3&6}Q^NrX;wp>QC)VKeeC zjO~eMJ2#TEn;A&@opk(|o$0u3*mGWixUjlMg1L`-6fy7ZS;YEMD*)lye-7?3g)vxJ zwa#%-_;J|fd~Gv19&kIsO$3s}8XUJ9DY&Mp>2RGQ3GT5&x~itRrJY?I5IhBLZ;7t- z;TdrI`~l!t$3;dpZ`d7_)%Ri?H%~rDV&oX1wxPP#aR(67M(q6hs#eD()0-7lO*P7+ zzT<8o4SQoygL0H}DaHGPAYZ zo4~!Cf=uG-vW4R;s^~}H-p;Fvb`Iu)(#8_Xd>6QP2Q2D} zv!}y#C@8x3pa9_Bf2(}Ov}sQLV`>13wd?Zyq5T@(o<} z+@FH`D7%5`r>rZJeZBEM9^s#X`#7m0MtTQa`cqH@djd1LPtxMv#%w+9J_YVC`PKv% z)0F7LUZRvwW4x@yz8A}B0G58yt(T^=gZ{Uf+9 zZkMN$s(qQp{!e6Ax89d2F~gs6{3Rt2)sFiYDX!J3>1@ApKBgpcpLzHm%?Q>TPkMgL zX6xIs@T@abir$$_wjER68h4j5Cz7lg^}BpO@`EwPH7|_L zLoqm7Nt(ylj=mpOXObp3x)7p^81)=EvGe@S5aa-e9)HLXUzQ+U5_R`th#suIw&m+& zH4aAf5QrYC?mzf2Q+)Bo7X(`dQFbToS_lBWBR5A>)1)V z8a*7MtaKgCoe-oA6pW$`5N%|g+ZxR~dyQ^FlJrUjy_qie9%##OZq z%j?@!dVfT6dr^?eT?f%t7U@t*szFhSG~3bj5IvI07^%xBz_vz@hA6v!wn>hSH8xQC zI7By4`ZB*x4cZ#*geZ%QZtc33+6IaxZ*9?Ti1tv9(K<&Ex;1(%M319PlbTml)x;W> zx7SxSEMHx0=~4iM$d%kSstX| zrhmzIhS3`!dZY3jh^Q*ZflRhHL-dDC%~+-8 zx0HM3v30Y2;~{gFas$I-i@ciYiH zFv_FbynAs&k|~db^o5t`y%4>Rj-9AGm`tjA=~jdjMJaR6e%r4DO6`){k2w%&w}1BC zknQN5)1Att+~|YRhwSLX5Pc;26YR_(Ul>rM)Rf4f6x6ZvZ(;D0tAGCnIu2;6qk<42R{ZHT@TeHXb0wMkul@h+cDn=wRVx`Rf&2hsPV|5Eogi%XbL zs#%K5dYSYEqU`p^YME}P_oyCSBr1z;52hwaCns z<&B|Qi%FO2-V28Z_LgGVj)$iNaqWoSU~eCd zOcm48$c(|dbjy|dNTY)rBbH>KUzn_Ozue1HYi;88ZG zF}l%|=0JdhydDcoKmr{Mu%yJ?3}ikOU@2uDQ8c{?vJ9Yl`-vaOS_@F;)jMQHtN@6W zU}xS)8K;Wnu5|{~6X~p!V(tH*&*PGNF=(VZR!On$|I>G8*MGR?Jh_d&JipwAmZIzX z*lQ@&(iyc2&HT|XSPQU@&dnzxuj}ZcbDE+rG$EC?NilOLODB&a@m95F0t!6)?0lsS zBtClQW&3NgPELM1hq;RD92{mx;3p+ zr@lOOpzQR{k$?9;tDuwj4I_D=^z6=YAvJ@a+6MXrPJu}21E|djq|h7@@J4UT!!S0q zQS>{2P_YM*@YeuN5M{`($Qr+$&mr5%QAjhLS|q#EaiynfEd8O?ga5m0M29SvqB5{# z(6`O}S#v~xqCau)_Inx1R6WE1<=|mV@tS0=FT)0z2Y*)_!lm%WrlzSX*3iDZzNxmk zJ=Rj&RMkTJb!45M8RHsq@?o;|xfoMdzq)xvdv#+&ORQmaYFQc4f_2r_Aft#i#9C-~kJ~EG&o%8CO)3fnHwN8k4L)lF5^JZj?@^K~U4Pk-PVR~$=T>RU+RG*+v2T2}D4?Q5Hw zSPjMYA4p3v98)iHoQm|+OkVV^RrQp$wS8Ib@~Q@=rN-4hbV5TT0b<($c3a)x-;LF- z{oCtn*VNXl1PADM@nVZ<#GG z2n$w@?~^M}Y)W+W=lME!agXyA<+{eEm49@RKn=;{m9b_bz4p~>NIz2D*w|Fl><@FS zVNF$itfsv#R^LJscturBfe3bqHQ@L*$H>=xiwA3IT~*ucz&+UGfvpwY0~)ex&MD8d zB*7+FRwd&R+zU@!+ti5Y1d8)|`^UJSRC%>WU(dcMu3ekv^qz4Sow=d5Rv#m`SAVtO z>|TZ}aiZ7Wx~8h-D+`F@Z1EtPrFrqYtZq2Gp>b`4htlE5)4VR2gp`hHRUN_Jao{IX z^aPD)lq{dm&@keFdAXF$3`VO{CPjKG))MmOOOhhz9aQ6_OE;AU4KED{ttUXeYc?)iC^rzCpgRh5ej2kYMYyD>+5+L z_Uiu?Qj7mlb@~7k87dHt-h$iH{*qFMlo=`$-o* z?<DoZPY3SGL<&Kaj zf*XC^q-J1MO|$n2=_#d*HPJeg{VKd8=&`G~W zrjIV)B{xwZObQTs(Jq{p*RS&L;Q0=;me>2A(!dEAOxRn9FZ1G6M_?5jv1gGUolL5e z#cDb%Ol;Jz`eHO+0B0ehlJ$ERlTy~ zSd{NMR(*bp-!;YBN#*X37@KA%_J9{9$vv+p#Dw?`CXOFD*W?RWY^WxaWXRQz{HE7a zk=y*qjTQui$SD=JJ)(=Gcd}R|*a**~T(zp!$S3LMX|`joddyRgO1kB{X)gV4=3nX` zeCOXy45cnIl7DmQhq^6Ek$w5O{5y|-E9sVIwtK@|{hX(tlrfJOI|JH*8TlC)u*n;l zncK+KZKNVoX>u^-eQY%B4OQ`1p$fN9+!hRu zJbtK;FQbEhh;%!MbUT91yFz{HV!ovu4H#SI5q1ld_*yDeYaz?o8;nu*cnv z_0_bt>VMTe)Tx%pQS?=M&u(xfukBHeQhqPVeHVok?^#zIY%LD9(XDhYjfb(!f7h%@ zMJ)47PPD@pI%Cuqwem@JmNDxqc*q zr*2l*nv~sk(7ZHgTFSitEd{!lLll(pJYtmo#(!b4%MI;j%HvQW;xX&=lP;uFHX>n~ z9(kG`d7K{MUVSgVd}sIK6*-moIHR8eQCB6gSAd;=BC(EcSmP?lN$cVr{JrYY1DRBR zZ=xt}mmQWtOMy-l(sS2VUJ};%Z>|1Y8~Hk^Bnb(L2y@VbmV_L6eBN2Jsnte~IxI&W zmVevAygU)luJc}6`CCuwVBSp6oy))T_?K8{dLGBj_H$HGbWu$H-8R|j0T(*DAPdi-AZhxk*7zidbE)Qj59Mq zW2N6({WpY~{eA2Bx0Qd1Mz+whxe29zd~D{2>H)tNa#BRTEY#8!-jK=Tl1-vDadC@o zjgu^|elr8iEBn}=VrWYP1FbD}{J_#T@gte$D)oaRLtD~1DHmjEL;GH`5usx?+gutVaczAsNS)tB+!%YtrNXnu|8$fRjd)UH$+im-m0-NmcE zi1@2K&4qsI^3G(IdFTM~G?I4=l7Ds#l69QKroK#?agHRi`X)D#Uap%(eO_d(WRABp zn>&clvSc;af1{G})KkRm%@pxXwN=X0s9Uqt**xpl`ERYnz4=XhzXKIop#>dVZ8_KZ zZ$zjhK&hRvchh#~H)g5BbS>I5v#zC4i<_Xz_JW>YE>66R9f$ZAKT*gSdVlkD=+#(t zt6XW+0~b}RQmLUS=_^AC|F#}kO<{PkUDkpq1*7~+6Qn*!5ru~P__N4T>^(dae4rDDQQpN;*Cu_W5>&Brj;$kQ=+-mkEbME-dOVz%}c| zZ)^z@3v#iNjd$1is+Fozmngqtt^BQlLXo@g>{2Dq7ngAG&~*EA34i^SQu>bdroMQ( zlg}NMX38NQgL-w-iH$3hX%(_HC79Th?Z@=FwD#{?YE||WH|mUvXCh5M z?m?Y-9%c3dl@!=}IQ9cG+X}hn2a8w`3@oI8HDl)bxh2|H978HdToqu6{7?Lse^DQbWW&fhk0Y#xAtSgJKt}Md3vIy(SBCIQmu&!KK z6e_}{vIv*TB3vqqaG76(%lsl-<`>~IzX+H4MYzl_!exFDF7u0UnO}s<`~yiO9p)!F zV}*PRim+Z#g!O_VtQQnvy==ZA{0Ucgw-7~X{mUi7?-+<(BO!y=!Z%DH}l2NYph zG+qmfTE4KT~;j*X*mqkpE&cPiiy7zJjT?u6-t;B?JLz+K_ zmI=(>pdInz@16E z>{Tf$ze;AcG}&c;!EM@C$){9UUahZ7G5@RN_D>^5Ez4x`xOm0;)TOrE$Z*-;+_Jxy zy=9mE1DvuzMc>i&zH-C z$|Z^yv2;3-Wy5z>2hzuoC?55K6C&lOzq&2qGQ4qTr!P>Vy!_2q~@?H;`46d8Bz1eepsrlhs1P*U4Z9z9C$3 zfH=?(pD0|iiS)xKiOKLy5ytShIDE2@a&NH^-+!mTDS`M?F??Ded^(1|Jp}%pBDf{$ zF^u>a>y0D%xj{b@`q`tO$LVKUKabbXynddno}!WQvW%6w+!r+bCH;IwKVQ@7n{@i; zbox&<{B!j*g?^ek{c4^5W0hX~PW+zx;fz4L&cyIpf$(<)m{CeBXsG9pZCcl`8h&|N9pJ4=o)?=sh=D4vqwME{N#%Q^duKE z9DYncpHxpWR_5pa`Z-%a%XPYc>u|LWzoo-5UG9hcw8$Qsp9}PJrhZP<&!zfVr=H{q zho1CxK8_FRXH-4KOX6jIzA663&wq;dn18Ng@-TYRC+7K?Q{yGimFMyEHAT1N?#id{ zvoU-{fZoqR`rgF-D&^Po^Bem4P5nGYKTp@sGxT%4ezxo92K_uvKQsE7)z5x@TI5ZX z@jaCBlj0+sll1&VKR?sYFVs^S`WfPfwA+M#W}+mT|pOj@Hj{`Z-ZQC+p`_ z{VdndY3fNHD(OicDES#u{Udrcep&tOSK})-alL|E`E&cu547(BoUfHCy<990=K1`z zyqup;si(16J>_Nkd8LN`QI&7LuYc<~L42K`C#ffS7UX9)*Kd(SJ%*pG;N)|M!>8%| z-_g&rH2&x4=lT4c0v8V9mlqA;rxypp-@|+t>HPQWdN0xCU#_25>hZp0NV%5|DfhCX za;L!Mf$$X={(c~QC5EpGgnxkHs{`R{FnleJmk!GmhEHI60dX_q3F01cFMmEK!F9-o zbUODn3|}7zuf^~Uf$;GdzOfLtuEOw5f$-HBzPS*FA7XfGAbcx^e-sGcj^R5CVLOT8 zy8`9ig5kRZ^#g_n1NpaM_})PHJ`CR<2+zgv1BGz(ISfA-2!Dd%hXU!T{D%YKM=<=; zK=@G%|11!G9K%lp!cSuOseeHDml%G!5H_dD&BB3Si>Vm%8;rRYD1&F=cgQCUu_yeVXcnGhI)9KF_6Nl2d5jq; z%+HWyJ`)pcvGh|B!2~f6VdEtc!myB!Roo+LE383rScN$#R?^QZ`f08hRX%Fe&%_#I zP^=BSw*}sh3cMc^c<-PBy6ES)3TIIC(Oa&|3df|HX8@UK!qF>Tj=K- z^z%(hdJ6rVPCsWJbb74>0RPycZw(O5>Hj!E1n({zs1~li{F~}isuH! zA9dhP@uz#mtApb83QY9(LGez-{o?)Bd&CEW;={u0$A#BV3xBVl`>#?IUd@U-W%vPi zP(~_jeCv52JSd?e?7faGypAcnjxW4UD!lGm5%OMls|eF$59|gxoe0Wgf_e>wPhlK@ z%<4EC?=8qEzA46vZ;MHCftW7$7jxx7;$XQ%tdL7Zi(D>RWxqID4u}qUg6NSaiWB8^ z;uLwK_>R0woPRAJ6c@-x#3k}4;`{Qa;#&E*xJmv}+$x_Dcgo+2d*rj?0pmdNGh?xM z$~aj3)>tB5FqVo}jb-9ZqguRU)QAs^I`OHoT-wG8Ing*w?rzk}3S*^QXf(*BMx#93 zSS8mON65I*ERQu>WWTXmo@A_%XBune#l|{$wb3fK8h>r_9%H?H$T&(qY8=fI0Tk`R z3nYRwv17~^;sqgXo`zD+lofhv9<8V5_=;Kg$bE2>uYFuZ=`m|i&MI`>80<7*bcm4A zDZogGaYna4=PQSzFKUGI_mQ6;->lk+P=gL1*H zmx{eAMt_ZZQ0_k{53IOfE@{0-9y%zO;%g1Q)(y(#H;OVOXnFYEayfkHNpz5$W&VD?84` zxFp3T$I2AG_j>Qg4$3}N0_R0gj)JX&a)6#k4a&`2)Sx_pvkb};>DfCdzeUf!L3t`Y zbA$5R$f@L+cQ8w)o>?Qtp zwSRH8h#TjKKI1&G$v9t}WLzM=ZCohMH7*jD7#E8l7~c~&8JCJ%jmx+v%T>?#J$W0v zL<=*&y^L>k2c^be0G`6I$s>QaJo|Amk{;XS`Phl_Y@~zA%fueovln6XCH44o#mZTa z3wzc!dDU!u&c-JZ%QpFgihJbMg^@pqmVbKVDq$Nxz_wkDZM#lPHm(=D88?V&#*Jcz zag&&B+$`oAw}=JCR-}a6#i7QXNDX)SZJ36{`zI8^q?jQ_!7KO{pb&4N82h=HV$1#U z|0lvmS$93o2i34c^z;cMiHO4rUGGw?aSwL=y#c}t``s0WKXZ3ka;@J<7whS9h<|GA zH8qMVrX73cpu9m57Qf$2J$9+s1!K12-wlKENBZ^VL3wAPdv-%yh4FxJj0bVPJ|xPG zhs8d|BcjsyiCAJh8o=uijh7=9!K*A!QNt0x&oCiQf~#@rDjb(+93%J3yIPTB4BqZH znMdFFRiN02-`ohihHnxJ`3wA27k@>3nCPVp=lH#?II=%(8!l)@oKR>A$1>59fmx=>b56#9dS+ImA#R7bL;^(65PWjYW`OG%?thtr= z-3y1%q+T#p1-9NP=KNfYxL>}E9Osq0#2n1@=gY(lH5`B89;dfAFGT{rUw>XeIKM>% zj1~M@5%ywy{NpmQz+8e!Pq|D)5UY2sCHVV3bB?=-+~roJ><_oe|Cw^Burd0x8%4Xy zXLBPMciXxVH>FGNWGrr=v7NF_e$lY+&qc_jp?>0_eeX8Rhwe4Pi!2J76g0QOi@i(`bIcK9t~pXHGDnHU=4i3R z94o5L2_j}r6wT&j(PmB&X>+RBV(u~ zv&CKJ9C5!nS3G3S7f+fC#B=6C@rJp-c-uTc{Kq^{y5>Q0vbluEw|@yqZx=BgUT4m+ zNZ9ZO@?{e@EwkZGd^5yzqDC%a=o?}I{0%odrudK89sZ7S7LC70YxwpSi=srr(?r>4 zxU7GQ`_hqnTc3$3__~|nx=ZEfVgjza)+b_L-1Ge*^1LQWWR}dRDrWseAh(;u3yv{n z*8Rr#*4g(M6SoAJ;xg3ZxGShj~L^(88dF5eS7g@ zZLStzt`U>Xbz)DmEr7&yABpK23EB=6kZ@?)?`a#;5R-Sqn}0PXwVKh5C}1*c?GS!v z9)nfJ0}Nngm=2@-yW*swV%q3CrN=ho;31T6U4lqlDt|^;mx(df<)YmBeqhx0@cUs8 z_<)z&5bo6pl>pI|D^x!9`{yxDAq{^2T;}!8q1-#%A)SNNKdPT9S5i;SzFth7#Yk4o znvHnRQh3iAiZ|~taW@~bt`T5eD<)dki#@Cx#4KdK^R1i2LDtRUP^8I$#D6qym1;|wFg_C#ZTek^A_KN)(DZ1&lCSP!d(|{La0oeCw+EIxN7rMaIHTna ziV&3CDy)^xtQVq!!2hZ0ntz(kWPAiu|YZ|zEc`DA-+{QRog0!%HJl9ZIC92 zGmHYG?xDn# zgtS3G*OdH#L=pD^Ty_Wu27si^fjQCP1N{Xa8N_!=hpf1#F-iButI&Oz97 z2plw8YYsstO}a^wZvGX_10Xr*D7>w33nmRk8P&0%sqwAwOhWn#=Qdt1VP~nMsDIYO zr|j09sasWPx9-F7*jcIDv(j#FP2HN4cB>(E>#Vd}+f%pBNxQW(ADy4VT4<5VGBqvB zqXp|gkI0SkRHx;6!Ye9N61cGRrXemZDw7tKON+(}i)r=J)2Y&88Y}PFx+9NrdBob5 zq}BFfN_x(L0+gOT=(YV5a^-iSNPm7G703tBOa2I@=wlcue*%-_&)`h?b2wlA5?0Dz z!L{-?aGSgr?vcNP2Kjr~CI0}g$v>e~?T4@ApJAVTfaJ;t3HmLhQa(fm$cM>^3Xt&% zAyX8INfbI8q%E{y5~Yz`)b3QGsDhX(Bx`69fsJx@07r1LDrUvtWa^;cHR|odsqUJxg$^xRQNdC)$We5UPKyeiHi&#C zij~;CY+4rLd`d!kWu5B)`%O)5 zc)b<}?m|`W&Y%L{&Y;HjWPebp@BWS&`yfq?otkEJln^*d7Q~cnC{rTPPsxEXN))P; zT$r!K;8G9U6gjvOX&c^lz%vkS31Hhr3}th z$~{ebUQ#^NJN{Ft>x@#@1*NWQMyY$VS*hE76sfEH9jU_+R3@n#KZXHg$WechEk+fUEbg3JPQa2o>?o^bzktlVeQ0m5@ z)Qv@{8;?>q0i|wYMyY%4Kb5-EQR*h6)Kz7ax_!+`-A_l6x@kw3IzqlnQcL>tVmG^! z2RS(UFJ{vTzHl7>-bn0_Tt@6Ot8r*3G)3`Uxi!Iaro=$R*(05ed<_hfBdlpl%-hqNmzDD zB5QE$0!j_G)ohf?Igq8yg*;^*lqhGTbe;#@mHF6i3!t~M2nH$_!w_XL3{{rEXyr1L z+GS9qtb((ZtAF5pWi>2Pu7OLGHLzT{7FH|Q!y08R+@Rb9>y&kHt8%jk$jyyr#my`& zE9hwXMhIJ*92TvAAII|~q`{`s*y>IN}Af+Y=T)Ewegggv}@@O-%hOihYnz>|K zlL^n#2H(WA;ji)(D9Y2#OnAC8fLNA5xhqFmjmI;T^(>b4oQJGrS+f6-VD%WzD*E`o ziD_dg<$p!b!%FgDU%sz^KRkv%oaf@C)9&DbipJ8=dKJ-n4gAU*o|5w#qlJn7!=j4* zyow+f9PDnV$9chC_3;k6@Ow~&{KHdlFge@lKOzw8&CBzkoMT^d}k$mIArvlr*x@B6sZFCU6AlCssmd@7Q3M(3Exr|mKC*h zO}Pjky8;LH{HfL6r&jZ)Fz>o#+BKNL)ynXYFX6k6US)n&_*KPg!gmt}&#i@H+~;oQ zWq;vsfv=qYmDyi~{Z-2ozFS1SH}g8S`fg45+@YDTPNdzL@ZIB<_gP55>se2=6JLzEvtSN1_j`3YJmKSO)vSLm!9gg(k4R3wLC zG>#5VS0$LK`rsT@g)3DJ*5b8R)nSurz<-^p2`{OB_?sGl57Z!hrDnlCHJcb}4sp~d z$x?Gkjv6BcY948)dR$b}-fc_bK%NbBj)(P$Vz62mIoU?|AWSgkYH;@vDu;BYN5Tl3 z^`UblHc2kKK_AwWFjGo+Scg_ydnRFs&@9CN1z&k0w!}n7wtb?oMO5eDHAXQUhJRzo ztg>C;l-2tluLZ5F(QFW#HdTvp;8FtFYJ134uEJRL2m|Bpb3=LQB zjYM&Ko=&3pUh1Kg#pK(;D2pj~K!5jqc@wyPtMAoXrX?}-2JeOm-&-+xXdQ%N3jVe7 z(WI#?cotp6qs5W+jfxvbi|dWG{Jj>A-Rk>Cg-XRdXkxz(MAWUm_qO^zy!6rvH74(( zh3*1>Oo_=6>~Wv4ilVfNEcbamhE@~r(y8!RN6O3X5W>qB@s0`K*XVBezJH~)(q7HzO>L3`0C!5I9X83RBf#FiRZ{^VJb>p*j+lsH0)IItH#$ z$HIDbJlvs9fcwRE6^okwK#Y?7;< zM+(*Xtd%F>I3pVd*(!>ijGk0qTf>k7%b|nuD+;9wQ=yuzY|1bTs@TdVT_B_G1gA z5X;X+v3pL)?Uh{eY2$xei?%D_`vr}I?_1V9o+dbm&6BZNe2togt!t_mVv{TaOT7q! z>ZMSuE`dt*a_FTl^>l*Xjl5=GFdW7XWeGzwo%{G-Az_D~MF%bzd{}Mp9i~xc5$k0# zf<|OFBD09%Ml=>t-G7M5BAOeqSwwduK^6(}d|@}nGv>H4o-^jg3^!Kb#!NTX(v4Ye ztjLY|-B^hmv)x#GH|DspQa2WGW91`KAP$2tg18bvTm=F3DkxA_LkIP0s8Ih5C#Y-S zRP|bv;pv<{y0MmS%yMHzZp`n-O5B+3#@f3v$BmV`v49(E3i)ja`Ckxn)I;iD5%Mhv z`JD*)-3a+T2u%6C2>E>o`2z^~R)qXPguEUhPax#m5c2H^`9lc#j-x|vXN0_K3i7Tr z>Z1-HhrFxoMi}H>6*s~l@2a{H26TZNV-ZhtiqYN>BQH1<4g#1Z_{3(R| zX@vY4g#1~A{5gdDd4&80g#0Ch{AGmv6@>g%g#2}c{0)TsO@w?mLjKm#A$Nqv`4c=CQQpc z1=I7nnlFuSlY5}bmV3pOgxohCf+Gp}gn01cgghwjOUNh3{Rw#p&2VbUiD8?#)L+nv zIRJ)w2pm-L5sg5;CZU7qgAz@JxTbk%DNPP(mh=T~N3Qhw;<_$W9K)_<(}6&JP|=PhMO{%zT~t9XyqK<8`n7Jh z!D*Xe4b4}72Up|=wMJPMrn1a+v&_iHYC2;zGiq_v!-$e=o~4^qFAf`p3g_a8~wR|Yn3ZT7K2;H<6aJ<$M`e?0xV2IWlMrcJaMr#9AS}{~>B~YWa zh51@LSfsUwOSBHKLW{#{trV`;I>H969B$Q)fi2pxaG%y0p3%C(OIiiIp>>BZwBz7g z?ReOy^@M|3FF2z0CRth^lBe|}ZL||e2W}nc91QQ#K`e>h%S&YNzZ}cA!tcRBqy95idaQOMVg-LH$W!4 z$g^Ddr}Al${QO%GJ1TBn?q-+sx-^~MV*_e!1jyP*u(Z*h`I3Aw$jEnz;`6OO%ck?p zc9tFH70%;(6LWXU3nx$^Uo_NhOT8ls-{SOt-5^>OHrE*t(xyO;HqA4R$`v){%I~-^ zfFrN8v%L%RIhuS4EVUzcju=%b?x4u6z2i3d@?pICGFp9Edi6EP=xoT+=AhF!H}j}U z-YrH|QT9fe#R>6@s-lz-qNeuW&F8q6pzAKvIrlvYc@^~+iMtP4ru(3`$yZb1UXxOP zH$`-bRJ#xqZ4vmjixHQ_$mAucZZ1PHUW#J8%+o3*g2)n1Bth>eNy1`ILTNldAzzOq z46cO;y~vx`6x^o?`9^oX6uYWUXGOkF+rFV)frMOzL&nwEkFG{tw+40Hbshpr1p%e* zzQLqN+d@T!r(P@H!fE*n-%xTAYJlZ`L46~g+`)jck#C!j*U@bg@zR96{@*0jMeIgw z!keH_TMtFrE!fF7Vkh4O{k7ZRMD2DD!6ylVPqK4ip^#&_uu!GD{>~KW{fVQ8BRiO# zzmaW$`<{-&W~U9zwL3xA?!wl(2V3i2PhDA}t}Htyz;UPI;GE1mHRq)bpS7)j*a8n` zp18F0+$PrzVd|>5siPYL*CJ$Lc_W)Xm+Ag{{8O9Wz}rF79s*n2frjm22y2gEV|%Au zV~q`~gSC~2+Qxa-4A#=gdihpX8{O@nwg*Rh3M+aVD|!YidKN2suK9UgtVF#8y?wWm zYN};`&IYzAwk#_l--eP?w+oDauzVM-Elqj742Jd!c9~Z_sw65fi`w~g7by!BU`Xt4 z%VBk1!RtH&>qMf_Kf*doqNq4-OK+FmsJ6uB37S>ZVTn2{w+LzHg?h~3I=&1+tbaavk_ywtZ1HIYC=+S& zA0+KtB<*`F>4)DXt&Jdmtyqv&@;jupwcByh7IG7Zq$ykFZAi-f!`RfJOyATg7@m-K zq?7hDHs3E;(ytzg$xK>%Hf?A@kdfg_BV&nwpWT6zaULflCtj)|LLDFFbm(Or6Y|69 z6dVRWs_BSMJQU;z3UUMmIcghbV*OyIQxHi~5YI@#w#F2sW1y>lNP&(N7=M6*g}*~V zX+{bjYfQnD=@d9fK@cej{XPZ0^N&J-j1u{vcoRftg0@_X$eY0m%g>;~Aors}exo$C z@9bIVyi>Y)LcFw~Fd}b-XST`D_E1=!820uT#!>f#hF+$|mIhvrDfRLj1siFJZ?O_- z!rO%`VUI}oXGCUyDev=?lyk+#w|WFrJqNjtf}_VEU(bV9dOmd43!s-?2!r$%FkEj1 z%{EYag|x!%#!rMxTuNyL^j?}zORV7{V{h2CRo zH6Lbsx|AOj=Qrq!Fb0DmMDq5e8YH)%L8hYx(n97XOOIRjESrRp?fwfhl|GX8d~jy9yla%0E^b^zjl5?pHQJVN|BI z)XTptpIeC<*Nyy&5!xzyP!C6Ftq1UTC|<7s)yfe)ip458#!_%-t8SxXT}g||#nr5N7Wmp+ zIh?Jgu{U3etD{P_o1m1m;UP7uu)xvQ-l#uzZrTnJy$WRg45W4{Wb4zQK%Wj}dNp*{ zXFy+neI`uSYp{`KdwRok(IC_9V|jy2w>$F&nQnLC4Km&C${HjaM%dlBA+8XP-02+8 ze0TjYrxE9i*n6O9{+vD!p*BNIw z5=sRNCY0lNX@?R@Pd7=Pkx=^3L5aGFE{c*96H4DYav4q0Mal_vWF8y1bQVd2>d0v< zsf$QDxsD7@j&uC(IA;@da&-b-L0C^kmT^7=6W6Ru#)i9(kE|mWd&+9&sWFY78t*=T z^`|;`i#=sF^VI2$o;t&QYFZs^WKRW?q=uS#d`6?kYuv}rtb;1{R8})j&1>}3x$aX7 z>ge(vK9#)*TGJ$%&U?8H?dDH5`ofgh-3z5Cc9)^ZT@E?=Qs|^FgFgCl7_6^=G5Sih z9;;xseg!PhuS5lQ6|B-%!}a=~VZDBT4cwuxfqV69VY_}EJfU9?FX}hIZhbAhr{4(Q z={FHYuO(r99VygrCT;cg9>)a^}mq&_1np# z`W@ssy^g%D|CM~EZz22iJIP`FE=kkxmP+*dQbRVWZL*JIC^bkv8wzJ?WWWi3_@fKY z5?#&0zhnS82p5F1vO?LmQON%D&=Fc(Dp%?uAB_@vEJova^1jUCM55g=IUpw|^8xwx z|EwGSXZRf-VAP{vG@xK4(8_H?_hLI*wufMnz5{0H zJ5ewmMt9;7xJrKvZq*-$`}8M&V4MD=XKcM)DAVnp$$^%jq&JjicTYCexi%2;qj*36 zOw?|4CA+6P7ph#c8M1irvdtXCo~bF*tkjgLd#@MIye#$H%H+M?2<4S*hXr{~I4CmR zd9I;GySi{4SOwU1@@ru$>7fv|p`1>kw534zV3YWm7T>C@nb<&pzWAPh+Fz5;ULusw zUPmX7mFuyl8+Wl{*SWK29SUmMoeilwn+n~e+fqq)B#UwHY)Rd@o6{1G#}ry~Or>wz zCzSixY>q2*bn`xn)q|;~y#?A~(>{xK@Oh}zUxd;6E9fD<26Oe@aE|^q_Vd4ElfDB> z^*z|EAHuczM{tw=G5ke;{{)-&bJ(GO0gvim!ZZ3;@Vx#ncuoHn`~7$Dcl~>KU;hC< z*7w8b`p@vS{tNt|{|fu{!-N=wD27D*hK~ddjpQ0SX<-6(IajWFV4`7C8I_CTc`f7|f4gNCQ! zpGRoIw1o0F04CG4XX1-q|e8p`nPJQ1xVuLCP))GOab z%<>A0X4=H&8S(BhBZ&dhc>>z!A(2lA6ofQqoy*@2s&)h1F znwd}zvl~_HhAO!?RApvD)hRQzu$bMauaD3HvrkPvs9NmCtfmh-?8cm?H$v>jSxs+b zvm5j+7CLR=i`Z@rQAz>o2JFQJ%~OHnMEb5v8=&LOef5b|ty_cG#?r{4?b(=Ah*IhzGylyLIvAS_& z7PH)n`_~M0Ie*4v^H8mH=`8{GKye~(FUrFc5t52 z9u^vLSZ0*M8lxkuGs@w1;~03#=mh^Xj)fnL&hVSjl|+mRQf?eax*0vlFrz1#Ve}@K z8huHv(VyIJ3?e&?6UlDl6!NYygzPtlkweA^skJduDmO++-Hp-GNMo#Y8eXf6ane*{ zf^@EbQ7$bsCP^EN)1>>2)1?QE$~(ufpV}?shaW}UX|}rQ{|n=ROKiv z@-afpT)n0HmJoYc_~u`s>k){6+4NBWH(&b$AW`p0cC#>*cUMy7DJ|H3CXnv`&s1K2 zyv_#0qPw3Uc6jWuMVX)nFdZ}rkbiRR53lY3~Ex3=n;9d6p!c?Mofw5qa&Jl_()L79uLeYg9D>_Fgx=yCgqv9}aVBMj&8tb=LpbP4^>8Rg-s!_kq zK>aog`Wmz06k`sIHqM08jI&^taW-6NoC_Bl^NhV?uqMIN<~_%@ZQHiZIks)l?tm=;FFCASGnR%6Axg&oSEBzk<92moDN2Dce43X}7 z&=#E3!WnIF227egHe<3bV;wN>=;gAXZ&_MnI4{Z7MCAi;=DxQ0EVHEqu#xG**%5H3 zP)8cizBO4r#%n@*Y}Z2^W0<%3Hh^{n_KW23NVjsjW3EfW-5*xyTI1;I1yB&vAxX)~ zXxjyH<4%{%ySPVn<4~8>dXLH3_|S)r*4cCHD_P+kYr_=57H%h@K4Q%bqW<* z2K zlPIHvAU4n3k~BGGd;2SP;*9aoNO~XX6gHo{wLPRzOSWvG@Yu=q!u}SLdKfn2frAni zT6t0u-fHYgO1JzcD5U_b1R%L|mx^*u=_OZYd`4zLx&$RVU7i@ywmL4deUW5%?dpYq zJ4cB`c7`+oC+nU+$rNcRdHhO+KdLZ(`Z|tL#N{`kgeP!>z~hGmliZ5pNUS!bUp%u; zi-W{Nt}^_$@?7mVlH`a9HVnBjbaZf2=rR<)^$;i)0Qy_iS~Rvw77)HK8@`T5;(vd2 zo{knD6Hf?p=n@sA@uvrZ-2<;`=2640WJsfAs7sj+ISp&_$#Qeq6BB+WYB*tkZb}0m zX3^1vmLnxuaTafMfT?2IgOedeZqRjZhK_ntMRiR@l^teuN!J7q4dy&K`zB&MxY+>= zPK+4J6{$1z=mK>z0dQC9LakD#sGsbeT**zg6sftBWwOI~3}?KqDVP4PsX}<#gPH2o)(RTwtQ+juA_<>{RJ5brqlC*xrn}UD%LwZ z%(T-J=05?g4X89L2eviz$b`6o=tIGqoRH+C3L>4&#ODNnTbW+V*r>5OUa{5&{p+w> z*5aU>+k-2dp7-g8v;)f36@@j?QVGE;t!0VG6{5G4Br%XCh5FS!Z*r4u;5`95Eo|k* zaW0yI(0~`JePnTN!UKE*r!z0{juzLP7l8tcp^x%_EX}41wlP}WVd#!p$EXW@6{~g- z`~Xf8(|!OTGopRVabWv8@XB+^u|w2QA8La2LwXhEE~Rk5$2{PXE6d7Hs1l7Zj(cG2 zRC5QVY3U=)j+q-@J#uoWbO6)Tr=QS^r5_&~RXg4rWj_XF%n&2|O@=knsyy@xFF_(8 zZ5!>oz%-(;;5gz}-h0=`y8SAaVf{&6%>*xb5funnI2f^CfEgh=139Q`+U5NFkhw?0 z9A3MSl3*(kVUi#~CaL3hXy z)p`T~VAW21M4cRgm}v*6U6q*&stNOaW*Z{}u2@iU^jSVTzz&b8agOt&iFhtR)Q#c` zkqgx{5#+Q;7*QTS40b5=><8yjCuLKM!WyN3ZnkWn@Gi4ujZF583h)pW&(|x%^oW^i>#hy)I#rAWZQgnxX z(%|kP`GI|;=>L-R^^UjufO`1*#Pa|LDcx7!qo?EN^J(_@$3B})R=!%?@V+VYZ(IPV z1SZ72p_|XQek{oVCb|BqNEQq?^_z{$_wx5RBw{f_q!ZZ+JAv*y0A{UmdVa3`!k z!sl#ry(;sLoWP@vcRGb8atWDH=kO$)oS!7sgstnBp9FGdKkJM&(?V@Wgr9DR6)}Ae zh@9txN%%))k8>YbYn**~?dolU!H@s~J}2Wzz$GvnHuJ*%zU#Q-U&V8r*lC~CcIF9nWty4z~9oG@G~zuH|CKpbP6nEJsHBp zO2nz8wDsOI%=+|LQ++pkS@g&UY)7_+n^jZ!1g>DD4k%IBMTQfkKdjbj! zv;vuQs1)y1H`c0ke?dS_fpAWNjy<^O}{YylQ?sBCsAF^bcJl~cYrXjhuM_xV!ZeF+QiFM`bN1|B3 zHE*H9sKyQ)=*@0PSajqF;LCKmDJ@@3C}&H^ks^Oge95?TTj)ypftZ)`qFl$~O_wxQ zFe~@ZnXs1QO|EAI@1q6VzJvs7gms!W&P!g0+Q=Lgrf6irHFpaJGULFsQtQ)b8pGuss;H&*{**Gcm*~urnl6WXc?-ADiB{A0OR|9V>eV zx6Ag7=+N)l;4|!6=~4YGcSU%Tod`j3<#>~E9jaa@i;lYhu9FX?R~>6fB{l}S6UrVj zU!>D3VCMbl<|bRXP;l@*Rw+|8RV{0E?H1d^hKiyQsxJ( zVZxwqiVa{P;e!?_jmF(DCs-)D_?A`;YSt+HmKGg))+pyfvro}8!3!i)6N@I+$eDI2 z7HjHQql{oNbGp8bg+|@q5A?X zWmlY}8e6%IC`WPiZ>^hTd1qg+UtdUm&rUGj#WFxHb3Y*FX~I4D2#r|}&|ev_8tCy` z=51Wc$4yOcW+vs{IPo>AJR>WM?#P^+ZKifdYXU(wf)XjcrtwvBJN~E`%9U{8F?EU6 z2+(nFt_RZKNr!ptYLLkxIHUtZH;t2@?TLbGydv!WV1{XD_Xq1(yzQSDhx)O}dvJ&gHn*gRxF}48^BQO}`g|p0 zSNbO=laW v)(CUJqv?4*6FC6aZC)^d5tLWyB7j$6UAn=1sLc)(WXILX9iy=#=l z)CII_)T<`pq-$@*_baF>6&VFv{DFe}AtM8|Z0b#$MDmrFmTTM%Kk_Xv@?orlj4yz? zQOZr&H%XJ~aRT4GgyYXM{XYn&oR*}_CZx@*Y*yFV$?bCO!@Om}z;t-9Xa2L(;3=ew zHEBBHN*|97DO}&0V<%(54nJ0mlv$-;E~YN$dGzYoc2)S{xDoF3=GfTwCYR; zoAUY9k*=Me`bG%LdSRHB{>Skcz@BDi7utR-;^5y7LeD}F(tM2KkoiVx!Nj%yTI2jIeI<9caV!6W;Qodmr_N?>X#~>tp06_-*P(Iesjmoby%>SQ`Hn#WwMy zhT{-O9Lda;QJH2a;yO-U@Ohv)Q+_bCY;TwAnD|7uy>qWR_z5YzWyTz{F-Ut1m7fAP zlVR2ws#4dO2(&WmZYY*_pl;MdvP66|SfPQiBe`MLHtAQphi(+}^GM>gR2b}Z!51)8 zpm;Rq(~obSq6Sl}WH3|%P)WKt0X2#dArqT3X(xeIjuCZcX!f)#)2m2e>kx9u;+;99 zld`y)^of?Us7O#Rlj`8PCXzeLEX!bz(k%;Gw($jORv0c2+Lez;b*D8rxf2M0j3A{! zYIS7qflS?#gDBqIJ|>ZitSybHCs@QpBl1hf6s-e?;Rn@A>>U>ZR!Ue!imiw2W-W$t zhIU!-NuIX|SdDsFjfddb|5>TpWrFzSu(IE`7CFhYbO+LAsJM*)c75)A*jI%3@MTF%q|5HLb91!>|y(N8-UQ)*+x2LbG1Zwr)Yp#f4S}EP1H_eRRdrf}*p-;3O`zPADUcvFfW`-nQ3*8ajDriES!tj)xRfjR}!@Eo-4R%fs7}v z5Z*^6OXxMpliOB$bTfsjra4{{i!@nMB(}GsVS9lSSe*=e8`->(E z7Dy8+k;RoEOR7SVR)GH3bPQ|G# z#;Vc7wKD{dpBpL-Uaj#zj^|hTB0q|?{|F7X$vKgVk$a1bZv>4zs!=xE1@5fq&pGT| z6M2>q{x_5q>1!CQAT7r-5J&u=M}Thu*k`cmKif@P;ItffH-Xhu1tFtcYl(lYgjKc? zZpY#7Gk&m+pYB61=@8{2DOhQ)e!*BnP_D=`R)^MW^9F4HWx7O<9pt=#dQE&P3eA)X z_+J#@q2r6?TYkGt<%k78>##syY2?pw!vwF0Q8v}+j6S*MXyeT2KgCVX{%cCAHf=0s({nVS#oY{pyb$bLfT-q>3X zdDarV_gF7M@{VdIjC%Qnc|9uz##+OSei8iodjV;utF z(AB<+C=bR*{k;rshLlM+R+LQvqRo%^tK9f2{kSWTv1cJ0tqDq`QXXQ@fGe#3A6d58 z((jBcZ3rZQ%}6j*h&t=}j*{WP^`A{<1xE+Nu~-_YYEx`@KRDH1_>|p0dAmXMegd%f zn+_ej{^j3)AVMvH|4*LDa6>KK&_)e2e5wAq?x20a%gLYtZ>$5>pF@wi_uV0)We_cM zL@)p>(U=J2JyHO0P#&1@95O&RO$}1SI@T_mmN3mme}*W{hT#ZNwk6dOl6-R#3$&qo zKyO_013xp3yJqnxRr8^uIV@#Pnwe=09?K>c)=d!nV9Y?mqz<5?~0+WUbQff{D_qdConOi{Dat=VsgZ*o+?e# z9uqnCle5ta;pm2$<%f62nn)17cKwfk@HbB-AYTCiWdMPscK{&7_-}4tQkV}0VPtN>PZ;-;l-n5b87muzVish%; zP-G$W5qkx*USYl9=)tWraiO%#xsfFyIA0gMCYc7mq$*!d+3iATK3$@U z6jgQQD_VfMx>fIo2e{;kF#n%u{LJX{O?D!K4*H&X=gu^(w5R^7FVnZ$zT3O;MHM*;R?&E`819=lcY`F|aAOb#PoujXFN><`~{?2&kr#C?X`{nxM&+rb?jh%KE$Il4gA zSJD>d1Se-~c%UqJTlQ+i>BG-Ym`>i&LIOk>D@B<$OD7y*jo_pAiBnGZ&Cz>v2UJ(p z8<&8MDSf2+?ok-8*nX*Q;@W_JMXCg-^D|_vBKO)&*Al-v^A4wc(bM6qPe_{{ENJty z1%|LSIwtuR@rw@&jzA)-aaQ)%tTNrs`u=)@0bO3Qc!PIrun>*rfVI29H8qG=2^({@&;Ezg-hEoSnKXk&*1*534-KepRDNJ<2=`Obom_4JoI=kA$ zX`;j27%&mrOqjba7rSUwq0a4No_o1(wR~BWrJZQtJ=JTOcMdt_dcN0l^O^UTKEK8< zI6c%P}LD_?ES#TRSmuw%0QIPJU5kV0@oV5$ab4SyP#Xyh+r2*PHA%U#w{=T*we=3q^_oq?c0`gGI`gT)SShDokD;-%FZ(> z=CDgv@l|=cvSrHLK_!4uL)TJlx@;uzODXdGoYrR47<#9n;JYk)Zl}6%A~ZZ4Yqr$c zn4m<|gwZ5F>=RD*!?x)TAmRD|kGlRN`1_9DrCvY~=Z7e&USNRfdDNlji%Q1~5Mp%4 z6)}Y2(D{YNYXN|Z-PrA8d2TI`imW5DZ@m%h=KM8W5u*WkU^AG_GbGNJfRKGqxTL)pn}1?yt@rjZJ=e~SikB|&Ly}zW@<#Y3 z?Kvj-68x3aIQ5%3p!@*328uRH8>d}L_Y`b+c2qX<{X!Diz`Hh@ka2TGuDJ85VL{no z;7iJTuiFr5re>>5u=A6s07OzDScXDXk+3n5mGBpRkOImWNx=Cy$@8t9f{~b7&yU6H zPSMb$l)5-e-nr$d!pogXsi62IjVTu}E0-=L@u$%@Kyi+sX#y&gXLn#_NLHM%h5MgJ zBM(kXtRC~r)NEI)W>yN#by>(tsIx7wyV>QV-%-45q@gOt%j9Xo&v!noC^E!rqgA#` z<2s7b%K_pvb)~aO32S6Ee~&JS`+w&{dwAxbX|HEb+K2Ng`L~ zBk($_TkqymX9*TIk;`~|=+KfqK&J3{z=pjm(nG1UgdQ!0!e3c z;vOUoILb?4?j`k)%X7iH#`vpb8|P1)!9HZs*8%#@pi?=w4T4pGR=KwK(MuC73$3nlO4Qfwd7^%+=#DC&iTE8d+p9j!05si|sfl^``hmtpU9N=? zjz*`YrY$s$>j^Wpn1#vW{Lt-WlJ3m1eH}d!nFxl;Ap8R`%#9lN(ol(Z%kqfz^2nLr z2HchP+qEI+Gr4@AO{o73py?3w_37XdKkJVrqLIS!$XCj;ng3C11cpXRFX)d(S#ykn z`I}c5H;1RyR5O90^)+i!6_ff>T4u$(pK2CudA)dDy||X)T|m$dMRx|=o;$mj)>I3D z5C^gbrDpVW<=tj%q4k-UarUcYee*ZaovwrLCsemRolBTN%?sWJpk7Y^2moSrJ1h7J zS5dxGlgn9V^5o`w%La08ApQyU+JjE^?D&e$G6@P0`fMJ8I0XI-wyv<8J64JoH%ZCw zFoV`J=EbksSFm~v(Uxf8cj@H+%mA`gHs)gIINAbAcu-$D*6wq=9_n$xaB;W}k)Pq4 z8*ImT=X}XOZYNL!@E{CC%L}&wYjOrv2n&*){>u0w9c)90YOTcdshqd;j_3q#hTK|2 z)p;z*&F?EV!|0HNF#PvpaA6v_kmzNQwjbTBTOml^p;ZXD<~>SRWen=VdZu5Y9r9yW zairA2itvVy^!|2_@TMnm{gxf>4jAr!=Nabv8BO1g9`1GpJpO%L93~b9&Ztm({}$X}a-PWopj#M9FxDx$f%W7hift+2)H_tsfp{BO_x|nLA0E z?^Q2=-t43oK>Yo=`BdK=7fba%B;CweF@vWO001{sbG0j;LW3`ML00Ed^6cbquP<;5 zel&*U%rzJV{J=V8GvqfvuytVX3Z^$=aP#~Ks~>n{o__u!$s#a}YE-D&ZVrw6BF=Ti zq4B``-%NVK^@Tsn7@Za?IZh{Q<>PaS2-D2L0i=}&g`lAua79>G&?!7y%|=tXJST}IQK_M@ zjk}3+_7<3O{)%x%OnxNNz$VP`oH7+QrAN`A{hu6YSk$G>8gp|lc%>6%z?rkGN)^Vf z)rQqlbTkHPb-__DYgz(h_T9+}K0!8-Csm}NTG(ct68LVbn3UgHFOuia0^}K{f#?u# zlaAT^7${^WEegJ{q$78kCVNm!2GfzL;dZ%^B9fq%q zP3%JE207sE%Ek5-FDYG2@2E_x?v3qLVeKf_c?9Ge*^n0KkUKwf4K9BG6eed7~z7${c?~la;r8UQ+d@Q|Ofc)7~30eQeBd*H~d22@zUGd@V3?!OlM~9#_xf30Ge+zVsYhyc~N3z`8wD@16aCy-y}hzs|>v4>ifEUns-z;f8k_vZ$AjGZ!C*^DzYR z19N|FbT8(&^ex2!Ls&2HXY*)oNH62J*56uG0QtAmt$I-JJ?u~}2na9??;I@Z5JHo? zF+ONfs>3w}6hxutFZ#p6F_G(&()v&x))?!hLjDvpTM%_2 z$31LL@;dMi07Olo0GQpQ!Rhu-%8)}s-~TJh$Rdr+bNIzg<|2!=gb-c&jS7BXn(UE) zpZ;hpeA4GqxBIrAnLR&!4fm&IvX@f6-rEy!if61o)0|U^U zThwdU)^`5JUc~o8sr1T)Ngw=4AD~H}`gUerF#`aVR$&2CnRhml|e6lSl=fT#*~gqOKvViCyU&>K2`0q|(S2VS5>`Fb5U_igM z657r$)Ba|Bb=`H#zq+5x{{ zoRs^FfC5D`+6##@BKrAq}{s>h3-cagZ2**waVnzMNZbDO&b2VkO zVsJ1vn@*ZQ)IzERzsdBVfvKFR=+6+wtS>wU=0G3vNdr>3^ZTc0HQ#T|8bqa1pqUoF z@Ea>81WT#igM%020%~3cl4Xw!=Azz`51t=6417zXp>X{Zi6?`vH36HoOA$~Rg7GZ( zNJ&RN>13OIgw4-y&{aJhFd=ytFp-r2maLS*F%YBUv?`Jjg~Ti^M-qAffBHwx12bt4 ziE&;PT$n#B$YczGYL2^Tz>x?}9`cNl)TA#h4yrU1Hw_tD(3KLBEuS%qU?RjcA5sTr zA~-r9a|>l65HBD7R;!HclMk>2y@SvkGAk@r$Du0hlixA~-AtmH|4fR0E~pjEozRnS zJpM<~+)23%1`GLInmmYltVz+GnZgB^OJFHb2mM?sCDe=Q?!6z4sD7(`VCQ7R3HEC! zl}CN;LsvT{KleXQU*|vWKO>MDy3skI)fD4X4zo#;L);HUK;zMy3B0%dP{2x2MmNsi zP^zM!E5f?`j3%=WaNIJYV4F~}Uo#X!EsKPZlVL;87(shlui;liV*#rMnZB4JhA!?Y z8xo93a^QVXHr3?9@&Ww+E}^jg2kQxnNv@0VdpxkEG6^oAH6b=lu2|pmrfW0EUjZ88 zz3(R_ey$b(LW_JMtWT?TY|@F-fl0-=-Cn-#KmCNE@^`3tVe2V$1%JX_D6sW-l%ttH zyN=ki(QvQz#P3ffyXtCi$(^l`y>z|!Q1Vz0vzO1(DkP>JXa6!#1Z}Se6{2y#H3%>A z!N3~sQv~A;WDnMnIG!+GzP34Ix|xtGHfizqihKtFrg4V68zVPW)vc7;i#n7gV$qh< zg|^vwD)MuLlY^wGt9G&26eZAF(;NPfZ>Hgha9@4Af`Y@f{@g@npu71k{eh_}GghkQ z=<@~`ztjf2C+2(R1Z3u6pQ<;&F1(hu@? z^1ihLz@=LZeE&D>=Gh^r*BG;Isw=6eWoDaCZ0|@AExP&=Qn`I@$T*6>2G?Orp~M`R zGxwVa;lI{YD+q=w6UKYsy7RKedq60JaL7M^K;Q9+Bq-+G=kKudomhbYk1%@Xf9>^z zduh6ZIfUIT5+w|Xg$=HefEyF>0VFZ24GHYeI_&>afUCjisueDGz?;hbyMHb5~UD)Cf4p0pvh55$#o& zTm7q|B$C0MG;Mo6C$Ye6oK2*GMt$* zwM0PBrCqz1MH$zfG%O%0LPP7x@P&-;DX|kr^K?(4C}H@ZvPBexOiwLOQ8vIZg7t!A zL>QRnj@zRk=Tac^b%=wU0O5!eWWtoGoIvzRGFgNm)v)3`MBrNHsC~a-o1{_u>|`lF z1OenZr=aVS^EaVY*M@aD5WFb|4&4Qt8Rot7kWg8~iEKNA~ zbDqOH`|@~VD_-wd9ndya_l?N#urvZAEqD5Pz3ZofNo7~_NRA4)`9YA5WmSJ4JS+Zr zCg@W3^K5Wg00N7jfwjr6QSX-BSZV|6Y%`0%iAW|DAye5xGs6ueZv+!-0gkW!LVfO5 zfVCXAF^sP+9#i8kR(2IJW7dutQzLCiR>+6x^|2z$r~6Gn;*frohQ8+!c<{{@g6ei_C}o%EZa{W3Rew%!^FO%#I|EiP%@% zY_0u9czT-;(Eor*?WlhDCdr%5B5_EI%r&VguX;9h#7;GPx!7_V@T!!)yymRJBd2qX z7iJD-=%R*6ZfZKXRE0ZhHO1Ti_21mhuLC?~55_2k1G9KXzARKv9-)#I)Z;`L(X!b! zb?*Rbb}7Y^a{Lo=L=$o{Ntr8@9Jb$)PL0G=9HddR^VsMQ?O8>vpuw!Dkd_ud0;!qt zQtd*t7PS9r$`xd!kTUzHtzwl?C8(%HsHi2V&Oy!1T|>k)b$Qch(f=0!^o1r3$wiCO zKQby?$>f|kHZ7Dj#pB7}r$4{j7YJlhE2Wbv@hR2$lxn;Rb)LR%{wY-d^Pbb3-(xe zwSNC&$#S5V&FaVQ`=(R-@BSq{msx) zN}fTPWmS;!?}@M4rW0bD*~of6hW=-rfU9=YO=qr_lZqcJZ}e~Nt8xJ{@aS<}pnZ>S zAFJ6{_OEcCcWgjStq?z(ts&6`xMIUfK)fr7iRt#CuH*g|S64 zD}TY2&baI+zr}Ep*@WKvjbELQ5qHFWg0D%+qi0 zKBnQSjSnM?Q_gd-{pA7?>yb}$OF66@7_(Q}S;$RfIm^31CdNaYSzWA1I>L7gGNX}7 zIG#RG11gXn{EAj&SCpVLFRYN$(w2T*R%7gj4GsXWJVQTfS#cI5ekD0onim`Vl(4G7^E_odL?wB$Xl{G{w~mtP=>(o z{bEMeF4&Qv)IrOAG)BHIWb}~QfXTs1KKX5B|DpdT1{CfN!=6dCkD@1qIk=dd4A2Y) z{2c$Q3IyUZLI6CCmp42vOEfZu5KahvEM@=ApeWDWNJA^5NwEupm~{E!PTi!;=L-n%mkZ{kaW zP?be^Y}V~dL9r;Z6pG|xSL9wy^qx%g-co{Y72Qf=>vu4mjY9MIf;5wfr}x)| zFowb)wI!HP)8m+@BS?eZf`JFTn+d4i<+_PY0*vF`uE>nZeNu!f+s~)M!mQl4&_($JfADBQa{_CgujB9}UAHPF!a-oLjO7qJ5Fe*h)|0M^CY&YBm!Zm*|vFR_x6EhE{H=cNF9B9p_UjZfGN*t5a7f-2^WXob|BXA z?}y6WSNUuE+3Q^sU2X({CM-8)+9>*ZO7aoZ zEu6{G!g}D@e;XgWrz$n>&BjxWD=##St9M+j|5&vP5ewU1mHkJIVY2UHM=Sx=aZlM| zYHg$f@{j2K)O`b>$EmG-fd40o&-QHwJTx5lc2m?T4gnKb-ouTWmjh3)&)hi6fdma- zArvLiEBJLGH7#p{u=P4w>>vgLU-*Vnzn!dj*eRfkm@Peo);LRD007rf3-pcM;Uo+9 z0(CGHTXZ14a7T<^^Rn*^Y7DM5LJJ#(hIFEBq*aAxHlhVER;z+L9^NS6UV)Dt-7uD` z0!gTk`Ij?>b{m!6GMu4JqSD2yt{<%~%OLh>4+$a|LmuR&~z2X$xkoGb{FKxg%w zEXrM_jW&y%^XKWhI!^h&9+S0I=FY;b6jkkdRa-+O)A3}T_A5CV%21#Fh@^lqj4es3 zaG(A-Knbc?6-$GWt|I0|L`%KhDLTyy?Qv?SYRW%gcAf}Ehw2muvOyK5ZeAcU4>b{!wO)bOcLiA8y5=>7NOi%VO_J`~~Imvtuz%D(( zVu4fKxkz}QLAopcFF8h$Ab#R;&p>8Fj>MiA{z)aE(1V-!yR^$P=1WnQ3j+eQbJK1t zqe;k4VB~F}J#PI&&;N5RnKDB6s2(F?+bKe~A~JaW5M|ek^LYR%b)_D@TC3yIB|rWE zI$Iueh7h>+4zaX7*oxkftUq%LkgfPEG(RA!%uhxnMJCnGid3D-lPJ{>Z^nMAX`=iY zGLaUzwRV#~^6e1tKmhTjuyNFOJR!_qj^Kwnu*2~UNfl-HxElEFHLrg%KjLTY$Ivan<)KDoGgB%wI1B_Z*rBc<`S~lwRM2 z_oBf=x*3{>Om@DB3Nlu{-eu5(iyXWw;w@v=Q-1E^P4g1!-QOi_p5!D#+7w+`ffP zr0raj-z%GogwFP&N4r4*hV&k8NnMGUjL$T?ZD)d3utZfj_Cpi5hhwv3d}2SVW%@Y6 zeE*$d;1+j2;O0h!;HrPrIA&oAQEi3fMmqiH`*TR}(wDLxAs*!;EbW%*ag8Eul%Gue z6XnY2XN0Q$2a%;m{AG>f6zv25%SgaL@lpad9Pept9t(cO^Aza|u$0XTOA_Y{3JpV} zlu-FdI$u5We5eAI?F>1s%Y%3jJN@{8`NhZN%0&hJVye=XbM?2jlYNZj;%FX=nfzIy zoD{nP!ST0n__;(dwxB-S;r>NAzGmSH3IlnRcpIi|z9Ukpaa-S5Zc>Z$U3?KLeDnR< zMqaF_pNleos)?^CfSBrPua;fyllP}abqnrZ6#qbTLQ!1XC5|DlLI7m&Pzrt^`*nwu zO&C&ws1nSg(&{v?;H(*St-qla(u}gUR~Y6sQGkY*XV`rXW@|B^8JXNF!b(3;U$7KOWGy#iAw{oGJP;BarJs9USKJmL#S0l00 z6DS?`Bf)<6)Ca&?IDgAR(*c9mY?I_TQ1_Lfj5%og$`3;oL&)Qe6{4f z=J3SJuEm%8yZra1(GxJc65i}_WonxW{7KyRISKDcjIeug?JcMWdk1yt{Wwj@U)kc^ zKO6a}fQ8-Xx=HjlYXX=CI_+#ERCnG_y0M!4HQT@iK{rt552ORB;CHQelhXMZm#q=;viTlK*G0nJ zlcuH1P*<*Eu6 zi&EbAMq_%PGg}<<7!^fH*0BpF(~(Oi9Vi^S%{~=>;kUXDToG)2tvm54>}G$9iBcEB+OHUZ;(Y&e{Q3Wg-=36pLvf)f#8_HdreLj22=p@qmKpX?UmS86eM?Ine0%XCwkOMca_aF1!-R(@X8kh((c&b zH>0NKf!BVsYNzCoe@Q%JIRHnrhHDNMfH;xsqXOz64uBHcKxS_l^#1g2^`FUX=&@0* z2?wIPVa$>!LPD4izKq&Y<}ZA@5Hj)X>pGrTPs#+<=G-1UVLSg z5ey#e10kM2_B|bMKmlUs4dY8ApdiX^KKmkX^TK>S+H+2B;=(G%*N-=%rMWIzaZ8@E zM-=aRGUyoI=tv&H$`8Q`=^7@q@EHVF85u|C!Y50!xWARL$-06Oi_@J{mGv#h}dqQI0V?zi~VPEtz%R*5nGaUzr{%ZHW` zHnjeqS_hWH0lG2zt%$6FD@sZqEVF%hRE%rk(E)*c?S1@5>aE!M;96theVn$2TZS~f zSNLPJp4hkG8zZ6p-Mi5N1SMUMU$f|bQE_E={QLnCMQFfnS}IrcY8hIN{Y1r3EuOnJ6OVp;w=sh4UM{O-N{0|H@`V z3v3pSnq!SxbkV6wuL*J~0r#zO$}yPtNKHOylnYHhNPdtK_9>@9x{u$4`M%{&b#BbA z_faTaMi$D(KCml%RTl!{Ffr#ry*>Gc1*@39m9q8^TS2~RRy!?f77t!o8T^~`PaGQf zTXMs4gnFb*K9&OIPr!oy$*F(K`?hdLT@ZQklIMc$^DGnmiGCu1YJJ9&!FhMi?y zD!7Pjk)NC=OCyF*4g1wJQ}eY7JS?3|;_$U?OW!RvX>6%~@+DkFF+ReJu?x2KL&+Dq zUIu^6U7_|(NHxuE2g*2#Wy@Izo1ZCuchxQRMqt;l4#0vT{vT9bQ*;*wr$(C zZQHh!X>8lJ&BnIXw6Sd`f8O<9eHXLNTF>l@xj1vUp~cyp3WYSEb5wiZm%d((CkJ=y z!1S#lU}mqaed@*)WtE+NtxfmlGc2>rvj?>`g6!s6%4ube~n$TQ^P;onCBI_Dv3Pb%AX)oWp-kheyqC?HURiMNyak)df@T#5!-n zl(1OIt8}BCo;5Ryas#Pgx#We)>BLNi27+L-1X7Py?xqf9W+cp>Ahm8V*~svn59#Th z;GW|WU>oC$)tJuYC6HWmiZPuV*LAF%+zG1wN}gpNQgUw6a&CTxl)ZdwNT%u+OhTC! z8lTJHO{3f*RZY>fP246xRb3WQd{kD9l-TC^<#R4L(>Cn9H%}RXU)!Z1Gjl_019T}! zqClB@kw~rw!0VDHkqm64x(RZOmx2}hwP+e+GZ_|xx9bg*;^&X@GEUZW2XGb;A0^M{ zE#~zzzUF(~Q>2b^3dNF%6gU|AuI|N!q0k{M%PDD*7b$ndL%T9<5Y_Y5wf1P>p}FHd zooB+dU0(g#<<`m26O2Myfd_4Q1b&iAoq+t&tvxnO^p-gs>1uy;b`%Q6Zt*Q$}l!VZhUJvc>iz*LiJz(p7O;t?Y7Y@_M0txpS4}Orr_HHXSr1Gt7Ti|}Ey%T2optKo zsP9E{PuRW=X{|K{eXH0%tI5BO=g{AFd_L{R|b^nPt0i-JqJ{7dzp=_IK z$10vfsxm%ze9pObYJFq5n}u^4tN+=mduOxp(0k`DC{HTWIWC^@>?@hq@yS~r!Ym(B zo@e*H@R%xDIcG4X!!P4j(^A%71b9Z`z#|zlto0_oZ4*nV5m-(BSy)Gu8rLGD;p%(NEvhJGYfDE1p5jpn z=d)v|?GF%#v@>A}*;kxNW2lVSIXd~v4!I0D8tv)nd#I{|9tBX2qn<6KT~UBE>j0YZ6rfhFOvQ%#G)35g>` zm*vJeb#(@nnIQ{ac=TgNnORktIaZzW)3jpjHf8pDiPkzL`e9}-XqzQ%qt1U&wMVws ziGEOtcc9S6#X2x)lKT(E-#<~VDtW<`lXb!UxL;_R)al46(A|a9OOTR6MNuxHw&Pqe zhj!fyD!b_Z0%+;QI;Jy^byYUz!6A9R(>x|A2xL9K=$b{t^4wY=5f}fV5eATPGG}QD zrI|?35NLU%IlQaiL2Lv-u5TIdTfLwaPapa2tAm;vv#@cv=ma&x;m+iZ=NnT`yBwwc zB1h>irOiFd7Ed|`MK$0K;b{6D@SV+8C~QXj3i4)E9ymhmXBmzm8eV1GL4MpqxOvt* z$%Wj1Z2YndJNngMLd_%0T%&<2z<}62I zC~vxskvWsRNkV4)SW)iSo{v0P>RLJsVmizl=S%5wNbQXY(b3Gnr61jxW%IV>G0Bqv ziQ!YQ5>MFu;4#2Sh*QE#g!u$iUg~%cQ(a7|}z5(Pl ztal@-SJTZP9@0kAA1tR=+ruCLVrlnZ6BYL_yglCobLC){ZBQx(DpQ`=fE|zCTsNRKm%JqX>UxqvcbAPSeOJ9fcf$5*5 zZUfryP6rFM1|5E^)N`ec7cVf&;yod-OSQ)6r|fl@FS2K3?`99$zG$7=xl?M#&Z}DQ zk5y`)Ab$!rr~fTpngA<@^|AMzt1B-*^i#TLQ%gVRR@8bnS0wfKu#5PQuxscaqE}L% zN=~GG8}CAWTaPDvBJWYVRbQm^t3SdnJ%RVRJC32&IcB+fgT1CnMpfnWgw5oS#zl^I z^P%J1?`R(C>DwBcx>;jM2K~7(=3IG;xsNb`O6DXKt{yRo9SK4nk6$B8+0TL9gQiW% z`i}y8;gk#Bw)pdhyR~uFizu|sMEV=IhnF2wb5nDe%P61+bwMoULgZILP+PR-kdkXm>OAAo<+8-3wRh<&G6 z)E6)R0QWk!&+qwAhnd^#(|qy9DE|D*T!*>4!!OpZ=EBT0jgsv@qnQMYBM4`?=0Sq+ z9hyElVT4gzDx{J*{asUe5{@30AK0^_tWU2-XncMd7e0Mjl+3_lJTLjg_IrmeIO4~P z@wPixtGRX33E}s#eqt;AC2y$D>h4EGnM}Lgbx;Lp)cHa57e92Nf3^ewN5d=BZd|9; z@5iUa#Sc&+Zvsqj6u(zc6yX*7PmVKH@crfoJnAtOKj8@9y@l=}_D=Z=011AfmLWx# zSwP7B9m5N=*C23PW*`(%?3-~E!8B|CMO`homh$C_uuAyhv_h%W&Cr+ng=$Pp-~gT5 zNXv%6T2`c#x9@E{oyzu)#a?TP7zb+BZ{@K21ss`>+^Mv0%uWbQPVwe@!t788>?%!+ zEb_E1wk*yB`(FZ1$XfSEpvEbJ4GUFQn^?w^s+P|fKH5;x(~+t+ZT!~mCj-`{_2}+U zl@s>7$%qpj8gok0eU!*WK8bgDUL{ulSbRY?Pil%7q4+Rm7#8Vllv3=TcdOu<%`yTK za{`~@j#%lSI4<;WcFgij3lpJO^dKI@I!|(4>yt<_;mo@p$Vyf*`8d{-fX;G5b4~7Z0-UUY(=&ZgIPD(K_l_kPen{8{6NMA$N!R zQs9R1IjvolC2U%01UU&`i13#V%#!KJ!4hGd?WQ!~8V8><)-MP7$p^S8KPn#(&MK_- zZd*x>9_Lg|exN3;0=eg)V^=vcj99;fj1jc3N)bhc8KyBJ#zNd<3lB@o1cU$jbPCyN zN+M0MOFXxQhg$B0f;A>@%laO=7KOrw?mSO}%Fjge0jk0tm!nFhN>b&hp~mQoukcHu z?BVFidT=YD`V{-nDdF=-75Vc`ZL6#-P@2OQ75R)5Ow(fh07m5WFvlIk^mUlLd}>S% z8?K4AJDTf|qBeruU#+@Sr#;~|{~{BwKPTPTybq4Jw_d@yewzjLiobFI)%Qf|0HJdZ zVnyxOE^Q&75AR`z#kOyLyFwySk&rWy;fK45HZlSb#zZd|i447IXLyEVqCzt2QYs*} zLoUU+M^TZ-!1%ZHMKGg|1b7aJ4i;FKV!J%?+qi^t5Pt7j+dFoy=@b(c z;2COX$`a($3R)1nP29RCj`q6NAz4s#rX=yMilj&u6W`~q*fvg*x5vb6uNSq^@^FXu7&fOH`DPt>G*T)~HW zz;*Ihf+PLgeU&ZQ;YHzkPwuFOh}YitosB>X)3_l!n(Mfwd`8XcvNyqt2nuI41w5A( z-T{3i0ISnoNZ!VTcLAF6Bjjr3e%=nxO#GD%lTXCHHjChZnrAZRxiIYbR5l_Zv#B$2 zUeGY{LqeBI+^dIH>rD^)hV9Xje$y^?&>OwUH_qgNa&ufZ=^ zJ|bSD+-D8CLVGaqcXW5Z#bDtx=3f57#mF`?Au zX_P!{yL1&#?zN;j`w+V%U2YvoeolaIwz=|J3#Lm1{#~zeHoJII{M}-7L93(_$c(MZ z>Dn2uW|yrrMO~Z&kNQzSI;!-(q<|#(3F`)KQYEUDc>j|A`(uVZiH{|qVVtNCQ03AX z_)DSu{Q@Fl3Z6;V{58d|NKK3CfL$cAL-1q}c;8_s@C(dNm~Y5f9AqELPOeFukhtx8 zN?^GK%H+CBxSm6znm%_>cD3(VyNRVAycqdr44pDcu9M}0fG6^WC`#zh`f^MzZS z#$562lA7lmX<=QMS1#PHEQ_$D#4PujReXya@E%XDhRMF1C=+#h^&+O5_lQo4Vzi0Y zt?tA-=gUKUa**b`CwC@=REsP6ybbU5NTG5}()uvf1&`n`Vdn&3zFMdfeBv3-tsKvM zNkRE;;mhe>(oLMb6{`=+Pevr;P(OLxxto3FSuO`nuhM=;@LKX{CHM!y{!orPhCDOgOF zJXXZ6a7-z*E+z*O=as`nf+i0N-!2>+zYZMOoKk)(4J$gMy<5#knq}cXUZeJOGO@MV zio$MoKJ>B-*uuDo;{7RC}V@ zvDFUiIAft@FxM@1fmcqQ)-QMcbUm0VQnu@>Jh;3vccud#GTpamZ|S=1{{_xWd0*>0 z6T+oG?xwYeNgjaE*zk?sOrlOQsW-SC6jn8A4tQn8Hhvr=+Jv>IsAkC5Q{7^^g=F!#pG47>Ir0`=zkAZo~#pHj6F-X#9_{M~A9o$2&1@`9brc3-DPO3W1~hd`>@?~ zHwc*6=qMs7z;}@J6Wl)H{h@t#Rrz+CP@h0FZ+}PpQxBKDOP`ME7`!Qy?;|pM5g7#LM$fD65$Pcv=GrZg3Mjf`H4$!WqxM*ppUsbA`9Pcw$qqC~!v8lVMU!v-@ zqYimbiD0i5^0BadT4dUwT^m49F{A839F~B}I2Vf4En5zD>zoax6Hz^kLF8Ar+t${Y z1Lq!WUgA@Vn~4r|q`RI+ku*v<}Fg?^|(%+MseclVM72=|bN z+1p)Q5(>!>A0mNiu4%3rtd$nC)hdA0u?xZPK|6~Gh7I15cgF|2f7yRY0I*z1B!zWf zyck#)FIcWxC)m9Ji@PUf2Q|z$HFJ?_y1J?w35~xJEaQy5Cl~3FH(U0XUJh>`U3tGUeOuOWHBB{VdR4??}_0a$-m?M;#(G& zQ4!KdALyR$h6xyKA;^ui2HaSr+Qgi7oy$X+<6udh_DxjAFnYCw5t_QX&y^QYc_J5M z%2DO2VYc?P+HaipG}=8U2({Z80lfK-u>Z!;B%dJNoOaY1JxUK7rTerVM@x+ zZ%rBouW)>{xT`r5Vz*Dsm{YCz6{^we9;_9My-0i)@HR8BWQ8wCFf4DUh0Aj06sD)0 zdA|yW#w;rN2nTYl_{C-+Sw;RVi_^xJG=wzoV$L;&9adbWDsU~p*_Hg^Nhgy_vV{10 z2mX2{Q$JBsI!l%ZM717Spc^&!5D5fjU81EY(=}*UNNAUHi9T>B#{U(;qB=1u9d+K2 z;hj9*pTEu~U+5+uZ%UO=9-}qMvBdn;jox6=BQ;gQzbo}}Q9v>!p+iq7(hEv+Wo+KQ zCZR(v!<83NKUKP`BUALwiE6B(8EO$kK1!k$!F z*AI2T)oL?e*W6qCm`wGzF56!fxK51tnyyfIn`@fd?EH;?8xOcq&1t-TB5O}HJs6wUNbv2BgjOXK_rn-jkG$(#bw}{G8=k?_!E#ml!A#4HJsTYY7Dm1*>*3wSr-kqC1uV8MD(ej_ zVG{|Pf7PW*e#I4i@O(fLN+?>2{6r@>LAW`Vzu!Qj*f`UUB{1NXqH<$}sv40vT#Wn1 z8>3uJ&bX>2&DOtA)|5l|T`SbN+FUo6c8CH^CaElQ0$t|LIBr0shCvzHWgu?X2il;@ z9J^u+fG@}zUqji!i9f5hZxQAJ91g?V3IA+hoH^|_vapA+O-1+dbPvEjqqofoY^(}w zc*L|_^Eet4I~pT98Z$c@Q#%@CI~sF4?vm~dPkidPA*z0C;rVrK92+`M`8isn_B(z? zzkl5+;?Jb@wSLHijOhhc`6^Vs=hQH%x2w_sMh-`8jK$l51sfN~RKDU8B*cRez8+JQ zUs(Ylqw7bV)fI$Z%UpBt9TTg|n-mX!7KxNkzdi6MniK+hss$wf5O8zqFK}xuUD$2~ zPHak;(CydFnG5kDvFRg#En@ONj?+-aE`|26Gc9F=TIuPR%F%LsB{$I>&tlm=&#m0R zV3Q^a#5H|Ujb7bM=>&FhjcRzvQQG90HMVS4*qL)<5_j@qG=U?c(2jPb9460>Iuwja$E<$$NP7UTkNO~@G~PcH&iBH z<+x^E<+)}=$+HhZ$Z>D`66t)eB}b|NzT^4SESDVVCDa z#PC1aIy?JQg5ILevwCYdP3o)==i(WG4~1VPSLa#3Do%?P7Krna%)kfaDZ$sVgS_7* zoEEjVaO?74$kMMe^A}S03)%98WP>>G_(JHFyQeyw@k-_gxqkNrtUEeeAwCGX+kbW3 zIE+(x&Sy&vNV-#De|_)af6u2nsJ#j7NImb*+cmPrF_Tv^QrGQM1oKTwLqz$4y5qg+ znq(OoP?hOwsd1;qhT@-$6dat4t1mq}MiV{)b!8xj!2LGr<=UtStWCh zKAoLMpt>bpRlu3WkMPkk!g}SkC6OIu6&bS~^^HN)hkmMp4QGbVU!8CtYdi&Zc(rU0 z{`{<=cYmiSJ>{K|KHE7hE^Xz;UNe+$tiMWtvy|U&PST#atb|P)xiNdzay%h&^&9;U zaw%lZ@jn-0#Y;xyR2mOrchy#5Il7?{(R1~n*~;j=fOmH$x{yV)=yAvDzVqzBA@JK}vT4;TI^T@=R{uMOdL}p%(JTd$>mApO#u1n``#YI5$=WZbj^7%tm z>{Ma`fd524BkZ<1{!BZWuVDVB{kYSAhj6NM=6i^jV z)*u8j7gd};2sPGPLrJ=bYV}ze?aaJ6m(y!0?7vTvWu+0mjJ8}l=@E9Gxt?S|VJ%b; z=MaL$EOeJw?o>3*SMPQj7{#E)_?=xf!b zZfRECAPd7k8|X}|nbjE`rrDY*k7gZk$lH8fL@!NpXU(!tS>=@eJ$*R&v}m_3*E5`IrQUoD=D7dYS@MVfjN zc>bB4xa}|=zke_T6!f5l|t)b>%&{8dr(Cpv#odM6bsQ^a^@eH~{n_Z_u(kIdb^W=}1c>CR7>E2}* zC$E+&fd;Dt>|kxp6p`GRuQ(2%a|b9!5&pvPazNHhK{vn9Zkt-A^V4#|I7}nSVDOim zmb}5UL1!KIh9&of8<9c0e^^2Rgnt{>VGyuK`WBWJ@b0jngc!gOa#RD72Iw5^P@ z7I2<~G=#fxzX1PymvDAt$C(NV{6USs9+$UUsr4mc1&e!(e`MH?ok}}kJczXZiVro# zcw|Ig{`mI4ojT$G2$}ow?b{pJw{NVeg!r&nskyH3FsTx*@JK+kvbH?3BErY?1Ngbp zR|a$!A(;1fsDc7CMH)&YEC$5a`BGbNCA8MgDYwWMahW?o{5w&67BUQF{I~BP6uVgq zDbnj1eA%4NX5G)-oXo(-#|x|hY`GtW!}FHfwtp(2Vtw_GS~b_kq&lh%8qDxg`G*$f zZC@v+fmxghID5c6r<7%2)H)a)M(l&6zxIx{5MkE=J{8s2xgFWFi5ywl+7Jp+02qeOkDtXk+UWJ|SSAP1!Augt}%DV6lq zA^p$eG#3FJSrv;!VO(mB6x|{$DZ5C+qCk@f&$0V?e`2HgMUKh?8%Y8BF?MTH@K5GS zGjtCv^sM)UwS?Y$&9!~i!+KR$9}V-gBcedTzl^eWr7+QZ2#B3#wCy)scO$y<&&DKcE2J&}JHa)Ks%pG~Frou2waG4VM)vad)7rUBcT8RB zraCf#bjeLgWVu4figJ2DNQ98H^Ld6#a{(7|X1LS{yfV>zeom49Ddg?u_{eHW>%mqN&Ley}62od!&5rr{D z*-(2+sVU!ixfM55tI38O-G}^RI0P_+##A`Le=;IEVhYD$PP1!^soJ(;7umC@{;n~V zc2`S@P_AStx5_ZWq6IInu+S1MzhE$l@O8skn&BRA=ZM*E3q!;tXBc-Vu{twrjqYgp z!?U5e!nIbs0}{d!ow7vF5lomag9>qy!7I#(H;K(8w}T?Q+Vr3Y)1o|R83Ne++A6i! zH571++Lg^Y{CQ#ABl6^acox({x@+4tz#x*d_g6*lr_j~PUP@6ceN=~F}L z3a)0rA$DpF`&%r{8#i*ZfvbFt`hi#U^eQ>Sh-#y9r9rqh>x2@%Ga#F}X+?)nNPI-s zz#FE2mHexbqN>(Z^dctPdgABjW%tz{l~Um5(Yl-^eb)5L~vzEO;4G^ZG1Y8 z{3nrHxe*9{IAkE5uD&bPHXrtA#v$nd$x_v~5F#PSTZk+^Gs6$b1}`s~a{PjO$dqzj z!sA~DU?=Pgz^`KFSA+#!m`h`tcl6;E%bQ6)q~lFSHm{U*5p*Ci#i5T{=ML)9E4YaG zO$-e*sZ5qwZooAtSUl_}HU=UdF`*3+DbG;V6^y5#pk&!rxWdq35itG$_vnCMC&q)t z#aXrEk38^0bfP(=eJXrK=0=_~h|9!qA`r(det^PwN{G)To*kzs2~SoQhv2-_5+PU@ zUe?JHX&D!b_b&i8BlYfs|qJJev!??zpk!Kj0dRcZQ zUsL)ZomdAQ|J8C+;h_7zjijB97k4o2mbsgF_|X@02Aq!3?gf({VRxiEN|eG5H7J{E zG>8cz?UC7!Xm|#sA}^p~|GO_g&N|jyf2eAlWa%yRlAN8pi_^>hGzqgj+ z!yYIh{#S(o9efx2npopNzkQ=gC3J>DOXYQg#{{AmU+w1=P#~@@!K6HsM$&c;d~CSL zw{ZGr%QKZt@<^g+14uqJH2!wD&{|F)ebN9LGH-oPPgDHk9(MR+(ZeEs$Il!8oTqK= z>G=WQj~@omwMtXt z0)Vkx(!x52BVPKvtil`{eX_kJ!aIMq)LQcKuVF^4f^h-E=pvL-S0fdDlxmc4h9LWu z9r`zar=7A`D}NQEiB`&STg9cLSv%$DIF<_8Ec>D+hp5#Civl>Tnv*@^a8L)S|t)AL$ETYr0-%>o_5rRe$ozw=m9A+YJm z{_UH4z_)Ms|KHz)Twy(dm;~7CUO^85DhK~e!5gbhtj!~EedWJL^Qx8aOSUi@3qNH2 zTZ}QnHnx);w}Ls~2dO2#4G}c9lWLsX+rkp~)vax+tT1#`75r1*wKt4g{fANp+rpyu zg0=o$4Kp9Xdj8NNFmUwTz5F8DeNZk^6BT^#!vCO&mqvAIhR)!9|P$L-J|NkZT)p zkyEP=BZ0A|CclbQV`ayh$qZ#<DhQ zB&W;Oz^W<=&y|Ychn3Cv!znX3Prscj7{L`?;+qlxi;_q>q<_LC-q-GcSF`h=)}wj7 z8d+HcB+Rl?wf&k+WH4!NVSgELOn9MFaX`E;SM@K+AU(o3r}g`L?G2XNTa0md;#-}f zG-p^*cE|*lx)8^~3)*P~`63Rcj>MAxyBzt=3M>=y-#{-cH2hn5->e;bc%L+`Hfa2F zV}SKG7sHkm^0a) z3Pd0+t3R1eTs7y^M+y!QsNacir@~o%J~btHH<_WRx7uegSWnwm(vem2FsvGeQRNx~ zWG5h7O#Ey*V0k|EvGr&D_)fA!mq4``%@aI~|9~+6_b-7eYJA0ozc=p{JJ_p5zizf~ zJbe91^uRY-tdS_fyH`{mfwon=FE>gQ9-HQolaF^OJl6Aik^%lNt|3NLG@xcu zzq=Lc&qvUok0y^!(Yewbj|;J-s657l0G9Z9=+TJZ%XL5idbB{tp($9c#<`<$*?UI7 zimW$H^QOvGilz0NJ4%-|MQrJVH`G7&JC|2sFnmm(zaJufrE1 z73Y04OK-UleU!Hf=K#`u(MG8QRCE;rloeiMuUC4ibZv)?2-1mhC`cNVL{K$UQB|`PA3|OXC1%GU^|~be>ru9mf&3A)k46k*dSoz_{;SQ>Q#d=+msm% zXw(F%SGS1eFJ+c$@L_LnX;yloWn3smM4K7o@K`s;Ko7j{qF~REakK#|Ru{qGeG_Dq zZYaXHWX1^?Gw>K$|#xRC37W+%fndNTBt)(<5h$s6l?>WCOQVN{^pcye}3Z0 z8_;J~YJ8^_k*^CnO6t$YFr&Lgr8a`bF*7Exl$UU!ZZVn$G~k0u&ys7-zwoqdzpqRI$~JgV${!qYO+UBm9bic>XTiB zZssY!KVB|-v_z3` z23c~zt6)f+SQKJqU>n zApvGkO6>;DjqH9Ywkhc+W6CIigKbecqGg>aA6hWi&d6jkP_`g5kdFF_`$xchLs=n| zV8@V|8$I)^>&OByB}XbcjgHXm{fL~7JTF@uV@&cAu_9AKr*vbqRA~X1yGGtZ8lp1= zdOaKx0AH{*8dCSR-Jqzv@}Fl;Zo#4NiuKfMs%4LIzfEvp{P?mb?@m}+MtkFX$y(M1 zK8jXZllF?;MC+M)kW_HC^(t3g&%96?By(}S4u;dBLT!O_7g+$!Z5w^zcnwDN9 zE$)ff=*2&b*%Pxrk@jm0qclchr|KYqx<4qd)Sb8kk$Mc-@-r=I?o3+~kvuls$-#TQ z+^B!{VGNLeSo7GhTh&U3C@vmV7BaJSYS;gMaZvmFPiQ2l!Sh;S>_YX--Uc7H^xd|_ zU4HUBW6lEL;z+*mO-|dWT?N_JFf=_l!iT4PVDJWIw(ao00?W`se_0VfW;%0J4f-rI z0!qP-D(tRawJbVf=Ps@|0^{53h2C!pD$+tdu%1bR?*Os+mZPnX6>jVZw=lv2&i_NbU-% zci@BTzP0tO>Wa2Fq>!I8^SzZ7g4{ z$J!Si_cg*d`euc-X|{PKXdw5avo1?&;Z>~OUea2!tt8vr=Hykc9>0u!%3^Wt(v*MO zjD!8i-WF@w3^&SmyV1Eazb*t<;S8M%m3)3|C1yqBHE$g?E`!@z(jSovHHft>cjw&`4qVw=5#zGaq)?dyzwC*?Nkd*XuNmN6 zJ$bw#^k9jO4gJb5+-djW*r^$2N$Z=drxT8$s7j!Dj)>hNR*bC9wsSTzze&Qno{NZ` zTl-aS6>MAX7;%a{isvkao{Wl$&Jo3`cr9sC1^P-RUYg?5up^%MGr_j4UVuu%&6%pE zDAQ5)+W*=HnqTZ1(}(QudNU|iAv;h$DvFw0{e;uOeXfaX1KFaXa`<9B!I-GEA_GOE z&=of`V7hW-U0Fj8ix>aHcr)^vXb9cH4c5QorG>&RNTKS9NJyeNRk!p)X=tL18>F+7 zSh2hTOhxGQvW& zFR-}C|Ly6^T!S$gahjShoN17-u=lvqG*3E3#jo39@K0NZ#r^}y7evB9Cm?894c}s_ z{1yWH-In&$nSqG?RU2zLb`-EIt;+KH3Hv1H*iDt%N_um%I@C)W|-w=BXCiPR>}``USa4W#*1Dv?a12lWF>Q<4(aQ2 zufWE9j~~lr+=ah9XdZ45V(ej-pRkuf->fa)@P;mzcWo^^-gp%Sct7mRWL@%?;>$Nm zpWa0XIDfz?doW;CNb<;}<0lkNs1w!cUyCJ?dqP8HN!iC*Y!mdZT$TqDTN2){m z3sJ-d(a&NSDrPv@ahpnSw$(9myjY*Q*-*qygKj&ID1iRuJY3uGJHq~aohG9DhsL#h zQ+XCH)@vif!v-K=YwKP4uu6~e$rNDA#qywT*iMZzvBe(&Ajfz1x1)7KE7KRz2Q@bb zeFT0n`^z%nqGjFvLc|mz-y?Tk*i_aO`jLN`F^kg~_}wp@ zBkyX=k60?wRbnlCk72r<9FiJ;lrN%$QM;%oNd#8y9}mQ-`DQkcie@13HnZY5ME{A5 zVO{D5k6zLam%;5}0e!t@plV1ulBP83aQ$Sf#c-ZoiV0Sue4(7njp>to5q2zsFRaAK z8x&xKOvZoSF`AOtRMBd6Pc{le5)K!aN*f^}f7c-mL4FVF2oXhGPbSh2M`WQ|qSW+w zR*O)SiULXu$C0S#8P%>s4ap?g^}>I;fMlS=)4f$o$P{!Vs$^CT&Nb~n_Tm<-u1JYH zbvO}6%c>e>=xv)x(k+{WOHrIhEUtbNOxlJn?)lk&Ip*#1p ze}f6x8|Io92l7byZj;jJBPa%6|BT<4NQlSgGXgU~iUaqkwHjq2^&fR&o3h0A#ATHt z;Y#m{u^l-2uY*RU*=D6<3_I1w56-L#;UnzEwyg znz^@8`~8lEN-C7~Syczs)?we|72Zsbh8(V zLq-6bjykrt(KVOOo#mmLNVZEioYjS_@XXQgm!70bgsW85%8I#cU&(w*%ZtIFwq;Ha zF+WZq1ioViQt84-R#OD&elaw(+9YiS1wfs{Dh`Yi3Yk+mrtsxJ6qd`NnNvH$X%@5N z-5F&BcRllv3S{Bm-{hSJC$tIt%pUZZ+-GKNlL(J&mZWV&pQfXIs4fNZDsB@Am#%hQ zUo=ImYu;fZr6aH3{UOUWRlzCu&zt8V$AYIa8oqDvxDCRhn$#at`g@lkEMG;p7~ zFLd(Jh_oW+u0CuyaxY~=Sg&gh!fJaD+AbK5{d1@0F_G8Oj-7H&5Y4Swb+N=)_jy+HI-7I0l!_Ww)W3%m*LtXA%d)zT^WB?C3j{x$?JzOi4zg z&s5hk+T|TIaF7Yuo=IXmApR?3ay_rVBO$a){ zfv`+g6gCi+55oEqTq}NK)m?5y=*;{lpaOc5;j_$YZ@FS_vjF$*_=;eUSAxf!+?OS+ z3%g)P-08vSOYZ0KMz2HcPNTG-eYgifM{ zs_W{w?Sj?RY3zba>=zMv#p@eTtBL);^BwFe1tM!dRa^wsR-DK^QB_i>T&b4OqxJ1; zh3Am{PHk}uT&Si?weIloL|rHRWugWa2+Ls@I~X{V_BlL}?dVKvy4{U)>ss`s2ngb^ z{_tKL(O&E<=FU0l0It6x)c-z>iq{G&vuz$qSm^LsBwQ#c7?2_(yMeC5m0?~Qmn0kWv%1$T1XVV5b{O<>9b&T$(aTjLRYik;in zzl8q1p6VD24J=Rb%gvQEt&*2|&r9pQBn88QHge;|s0^kF?N4f3ho+gn%|dFh7jQ2L zS}%5MmW3z$ckVU(No}NbC2eyxtHb#e#M!$oVBBdABH2y3CZEFM_n38a$gy~~B)FPP zdnwqpDsn360bp0B${#`y=8DqqR`8ivL2Ya#+a3#v zU8}-T)j3?Lw`$wSwajcI2o5e_Yfw z9H7H|F9@d_$#hDfj7dIM;Dsm)V9q$pCqgBe_WjdY%bBe?rYoju5H`c<*sep z`fA&@?Op4uZM)souFc)sbN@Hz;vCW#T;?Oj<_&}dIU zA=7HFKJ(5_wbx-nQU0}*rjO-MeA&nH9H>(-F+F>ehr@_{@w zOW;iEn!gwRO@$%cAEAsGcq%2hA6rChayA;m-vJ%B0l8S2(+UpajR{CA z&;tS3i@mpq5ad7!?74<~V0r^D6A(QLR<|I5hI}yrgv?m(MH-=ov=@^2*MVSb@X>oj zns5LyrXFPV{?7xBJ0lyU1Gn3-C-HR8#i@GClhMYh(bv@DKZ_xE9-`}?N*(ZVlargU zqn9CvR$-c#ghA+zd8o?o1z8|OlFGy)%Fh5XMH1{+zRqhQ_Dy{(Dva^q8ueWY)n<^_+(zgWR3rqpy3g9%3!<-(2~XSLO%fil6p z!xI~kCK2d+%T&`buP|~#F@$ww zRc*+73~1Iu)168(LYE6J87L6zc`qf}xSm54ZOop6jtr*$8fdXU=*B``c z2pbiKrC!RD6@*wgw}X!&wu`?G-S8UEU|9F0n@+!&)J@lOYscP199D>-8VOnsgj)_s zS`G|b4p3SSlrl!cL|E{VqP2+BntU~9Bt<#!A*mW!=4M6)acv27$3}pEY{9f$$ZXA$ z_srcfwuUKzMDFbT{bfZQfQXt!?U-F zLs19tIVG4^atSb~@;{Oh7vX7l;gS+7cEFtirophY5ov7W$dk%9M9a<#1|r&CSg|g1 zm@gMi=JLW@PRK8d>@Ab;wOhXIEQw9pXt?Ix=ZbfSpxR*0Qn@WV>;T&KwW39jzibJQ z!vB;gkZaF4m*@mKGoDG#c*G#}M%4xn7;W@Li@bA}^dMMixQV@s6$jTF|LrHP4MtDc ziQGQjW0Qk^n1l*j!KJLl&BYF4Q=TZAPLLQp*i|Ow=2KMBM+>^Yy$0;>Msw{uBM%Uh zRhyHTfAoK3*sX|yRRep8WaCY{CGzbRr4R|5uG zry#*k|J4Cjqk45TOpQ%?bdYza8STXk-)JvAx@GM{*knvI1I;sx*ru2fD&4E&^oHK} zfNyH13b*wR`hea|^kMHzzHQ9tFV2USY=Xw-`su#^seMJyUDb=Fq>s7f93roJpG=%? zZm4UWxt!lbfjqx)UH+{t=jf+P_+=8HMFYR1o%!PXb2e>V?AeY##&4`yk1ul5^Do?` zG8kOU#xw~$M4>kSG*~!foBY250urr%8&5Z#%!WN%jpVJ5Z5~D*^i1XMNB!vEo=d-U z!(rdVBKeso`z<(tY9_eCh<@{Yk zOa~e!2f<;xl)(CQLSz&&zMFnLcjNuNCgO$lVkE{MTgD#1_vSb=PK^&)U)hgrEH;M~ zZ}q!%)npiW)h~2Gl8F55#rv!r(?!^78u=P~I~3?{*f>0timh{`hBrV2&Ex}Sa&gEU zAaHgw7ua?RZZ{9DUG#Tjn&Nlf5N`rItkqF8Pqehf13OaD`M+?nR;Uaav*_tJ9J}zY z47>syS89M8fAF~{)?FjPaGnc&{(Kv+mUGg!bM%MFpMH#H+stbqkA#7tOFrM|0;m;bh*HZf2-uNp(W0-c;xaTbA zWn8vx+^YLXw~bm;X@XPQZys8RQW^jT$tbt z0t5qDE>ttd1cNg#T&N8V`pKR!Q<}fHMKwYNQsI1PG0kZ;lao}SFPZfnsi=PZpy}C` z(Xd^zS_VisYzZNsK#~ zB?l| zK;yN6?%{LQ&s2V*9eR`*H1%9NtXn2cIX&uWF8Qf{_#+~*vEu0&MMkBG)@lCChb!+8 zUkZXazY2%@g>N?F+0R;n@aQfT_p*3mgg+^FW zCubWj0{^6IQX0Ls{*bFm`*9Hb=|}}Bh(4zNtJcraVTmPg5uRN{= zTTC{ydUP-Sxpo+j!11ll z!+Gk%yP9Mgnag;xF{9!`t&D%f@HSRy>7mmaY#d)EM)t3$`J|HF?`giB$?J7b;%3%k&N+9LEF^~wh7?!1!2t{$CKLkmT$Ohgda4uBCDPgco(_38Sp zB8>58Gl$~FK-NV|TavD|oZryrOoeYDB=1Vcr8ZhHE;e4$%|w@>I8smrbLe{(@9p&L zkrZg!Rxd5o2S_t2vF!~ARD#GWYw-V*h%>%NUB8IB^hNiiq#mfAG##o zdL;~U@gm{I>40WCt;!Kqo$O|zVp$OQKdT)q6v@q#=YhyDRIW4qscWmSPIYuA?BGZnXQ;y)+-%_OvAMEBO ziRXLfp^;%5_vfcLNt>sszu)-x`L_Ar68L`d&ywHlJn&dS)~wsdF;95B&oFXk?~`hh z$|7R z^gGFrHF3a%myh+p!WnS(0fny<++6i|6PLFKTvF-Z_puq=TNx{70T(ZGgPNZgv=6-8 zooeX5Yp#8h<#RpI>iTEKkjH=;(IA5d7yYr1A!OfZ;aBR@lE#LrfmJ@1dX{*+_4-p0 z(2kBuKp^#)zN#ztKBs~QJ7lf9&PDQc@Ox(okXhv+cXfKmxgO;a3UKj9Ir%`Dc{R$p zC+9x-eEbjXwG^K2`YM$sc4chofUKo z@G#=}>q0+BdOCYX8NJ+%VT2q1MEbDGIbh=+ws0~N3V&a@&sgpSk-EperMO2+xzQj5 zh!ij7X;%ugs#IE9d*e~x1jOWJggqpGPSanNsDVu4dhxACz8k?|YWZX^4V_|bvn2OmA(*LkK1?~=f9O>}` zdZ0&dkS{A1;hoLm2nzn>8BGcR(|p1J^5`e{9q0kX0W3sq=Ty=|g{y;Zl5dEVk$6F@ z-bBML2Ld(z>-O%Pep3?C{{$Mmw00A_)_F+X|2599_m@*2THv(z1`K@2NwE_c%drjp z{0uwI%_lI0`79Pow3IGkgs}+D`=@SAb|zMD(U&75IV^rOSnFJrVZICiaCOB128vKU znyYbblX@ENETEp78Gd+G?Bi3)d|q-{9qF%#2(Iin-Tc7gPC@|7E^lYm<6CFQCe5DE zxwi0-cS`nKFe}rE84M{B<1b)wd_;^0O*%`9SSc5?U9oH@2zL!nJ98(s?n6Rds%V!C zCx+u#yp((ZB{VLR98E<@yJdt1yy0wp@rGP=4C5y@qQj|(x9k&s@WrNG#KEjXBJ+@6 zjUoNZ2>lx=jf;+5D*n+(xRnK9onT&Ksg~yo`+HO2x34*k&tR%M+_6p8g*PaYLu^tw zN({HXjS_doKQ5}sjnO$;aD8g%pmRz~_NoWv7pLk>=(LUm&%+|xMc0%D&>piRfO&&xBh3kUq*n1O@1cCu(bp{V7v~f#j@Xc zbZi|!Ow4Z(2=SlAh{3-Qw4gA0My1d*mY;f1!YPDVhus$svJ64-aYRROW~T`=Udu6; zNtF1D{g=@yaLTTVW3A zxurJ*2&DZ-S91Ve2nv4gJ+P-cu#ZN%=S{lLxgV6^2s|7FXM$zwCO_DtLY>_r3;Y2; z+$2GU&*F`)`Z*S{8LzyX8YOFHHNIdc9(h9yjhYUJ*DnEPKV&Ma~SY*2J$QF#UhR7A0OZwCEH zRPnGpiv&HI>TshmAd6c>9vkrhr%`_j#lmD3(m1VMdkSlFh`=d4gYGFx^fn}eN*`U~ zz@<@`00rJGi8{?sB9eec_K&i0V-6YZk!z#)3}$KzHZ#{lAe3|pI18>b@JE8NHK{aL zs|U$qRikO_Z$g_x4x;5W8~&=?`rC>&eD6%uYY~U)k;RJ*fNht1(+CjtLmRPpBia2@ zxSjG2$UoHRe))X?T9+DnJWq2I-r{_F30!qpqz5Qlf#xtd;0$vNfnK6>?E-ec%fdRk z0Wb?Z%pLGOeTPRdBx*au9xK;*24|iC&kjG1#p7lNJVYoLOV00pe0&&KrXzW+ZR9BX zA!&apf-(UR!Czpx_3mWe%4MgI^`x({soBcu63$+Yk>5udGl<++$g4<{={>d(x%(7V zi)1yBAZwVhrooC{hZw0N$~wTT>Mqib-HT+tRN6Xf?~BZ-o%nOX2K+T0%w!ps;2chd zUsv3bMo+RYbJ9LtMbGe&AZ+9;3$}GRB+Ms1=SBgh8kq|v8sy|>%hG&3=iKc-l6sEz z>4ldHYW#8Ntc}Vlf?1W3@OXgbx&5ZzaCEf6vQ?%}+?m(OKwd^E`g#spmzNVg`rf zC`$pr=fmEtq&{mzK5HaCYs5Zlq&{ZZ3KIo5!P29o^IVZ)yZiGknb6kdruV;oiuT1c z(9vzgdSU)+ms%DLN?DQ7l;`dM|P_>>^z zGBVDV>ToWz^!MD_kUI{8d%^l|AO-+62&@r54%4SVe=D}G7kgt!z>zl1BBGBc#kov* zf`nV-*t&G-u#I&~U6!>SdTNL}f8eebto5$jZb94Uqp!*h73$^$R zJlzw-I|_PUf+(o>09ESc(!%r%_Leo?bRKOeQ2NJ;zVT=6w0EJGj+CtR8Zux!Wu4<< zb7NTXfuY-TYd^b(VCNcaCz)R1%h(KI&|hqAmtnsgSuEpUrh?duax+z~WeP_c#m~dw z=bJ*(JZz}2mkLKWK4KfM(GX3>6+YI3iXPvnCnTrr7#Pb-WG3OxZ&&8fBr{TJMzBD} z*Bl}!@2E}tdmrd%^lt)5?s))?5t8Y+?bV)RCPQ+89wksa z6Aa&!Hivw14^7_oi)3*hZymla754^vtIQ!a6D7&dFn%g1+|GUyw#0?-%5o&UgP^q*lcG^$BwhO~7zw zkQsCP(8hg!Ry!4Y`=CC-;;5fqKBtxI?;(3qOmAv{9vzEqp#(wK z3z}3Z?Y@h`mo)B#G|$Q_)#Msw>RhAX)s{)-r%%1Jh1gR}@PNj*xR_l{V6m8OLUAeb zaP+v1l5|Rq$KcFB1$r!I|)h4UBTKuyNE=6#Us*^ViTCOHZki zooLBH<*tdp)2+$=ar*9Dz1se9OjKUpVWV-Grt>VEt_kJ2?=^uo+L1~h1pG);_s1}^ zHsc_6Bq;n;ZFv`w@x^0W}L;6RrhB3gH-;ZBl<7oj>QtWJnBP`rw zE}X{QI6{xwrsz@i&zz!n3e5@n_G=OKh>m|7)kdI3L9hCVyCDy1+F#`EVRxK=JEqg= z1&?T4f!%aWOtJNdw~t-ic}y>rIrlr)&i&PzMJaesYP zRBI@^HP-?3#g_lNy21Z)SX$1mc*EA~N%i+5VWEXg=GaSZO`!ZcCl884r(qK2gEo~M ztHhYi>HA3-^|oVsx_~`Ch%nX9=jVbK+t`3Bzy5%Rw}d)D(dE9s=O$`?DjNAk z=gpmO{J#tqmNhEgI_r96mOWe_4b(n`HH3=J%RAqAetp$e8>l|&=zZo@37wsTRuPp{ z8G7+SvZ29Q32VCjtxB(g?aY#1Hq}!oweGAlPpDNPYg_13rBf8q`9!jFqqP?-FYK8S z_Q?gnN=-H!*74)Z{^4<~;m1}Vzb{m_4{^H#BIT_A$C;l zK*&o=2in}hy$I{W8jM%(NqKQ3-zn0|=mX!zY}Qe{2=U45Eztj@Mf9vwg!dde=FiN` z{KIW4n4h#O283{IC2NvVp*xg1Fxe_fKa2y4DVIH>E)vEHcedS`KGl)5a=pVdcl_KP zh#s$+y`{2tq}mqhi%?Awei)xjb0EsZI>txig_iA?jhM=`5aE^x-9$NwpEcGpPelr? zMj8m8#v|epprOM)SJpB!GBHuaCDD0A(kwk=WO>U<%X5``TF)EpqWMZfd){*!OWFcD z@ZJg-eit%01X0ACejYJcPU;v@ge_RzA+`L;ZBW{Q{N+rw;fxJo2JDhW+xRHh<%6pB5`Fw^y*P|WU^s@&q5AADE`TiF;JOM z-3RH?4$}01Z3wC%Qj}BD2e%u`H}(v`a}WxrR* zaBTz?aCn#gfqUpR={gw`uZxB2n2GE73&J%OR1Y0g&qP>MSR%;TiOh$XXv-azv+RrYygF(7oL*5L`oHH566SS zjKbUJxbJR%ckmjVVYPCQ9bPvw;aE1Punr^RR5rAuj$QNg99B;6OzF=#Vr-o}_u?`% zqlejmLY-~<<}z}g<74=5U7nj(8c zWk=NKF3*)5MgzAa`v{T$#2w#F}yINVVsj7ce<2Aiz+`o3TFk?;bfj8H_^z^E8U z(*d+-hgvt;Fmu-H>m`u7@n|6p++{6?;xg*}bf2%1QG4YZc01uvZhY*fv?(Vw$jFmQ zrFmOV%^=fo7uE%M{#};_rsGcX}5$CjIFva zGbhosnnEjf9@Vn3LyE;c<4R@T?mBF?VXr!p-4y;SY{2LowoHC7NxTRO>ZD?6Bs5%X z)$*o&L^#KWo_dvA+F3z(Q87fYPG)Y_4FkbZAy9W!4QC&a1y!uaW|(9{IpsJVB)V!# z?KTbBSBe?>5honIhqHESL`wPjTopvw426ob!!Aw;*wPwyu z_Xrj<8++zto!>8XrXOfNLBoqT)M#>~)}uws`RnImwi#MBefg$h1!ceq2?DbsaMk$( zSut)`tTG(nUpl-DJ98Gi5TGvvd_6TDbrq1t`#Z{i)e$GOCE^^W;224|7N2%Vr$Z7u z!S!1hEcNR=Za@|~*dGbX9;GMrn3=6?358Ab9h?$L|Ox$ zqDz}l@tFWQ^wCAnIISrE@43a$8#}$LLz-88W)bmOXTs;!+QqEoQxpD^P2y+gZiJtR z?GrY!@l!e3`=USjQ)uJ513$!jbHZoXZp3Hz+65C|$la{i)5(|Q#mT5SV3~ByAmW1Q zEp`onJ!}q`{vJkMeBIzT8lYr zgwMx5Sf6@bQv(;h(oxWqvdB&Mn^dcVC&F%Cg{_X@)w0OTZ_kCo#nwReg19BL5UIk& z`hZ1gWDnoV2fNcXQZKW@#pZzA!q6ul;N^h*b`PnSLV>?K_^(BrJiHJrS|DTf7BeFF zElUC%TOrp}m_IW%lo;vJKBxx*y>Pej5cNPFYe-6QoUAlxlUf?+Y5ZXJAL9bWdV4J- zd7^TF`dR+y-+Zd`e7eWkUrkV_8Z!{KBWG_;t6vbbW(?F?RN!|MV;}#ahamnpJ_KE{ z7&(2t1~CcL^|x&;;z%Rxf7wL;i9mV&N#`>_;s@+HpoyUTgGvKiZ7nTrfh?7XhSMMy z%y45Yf-TF6q;e^Ird)N3Y;J6lc^2NdfEFnotx$8Nl!#SBz3$tvfcZ!b^Tw; z!XEAgzlyX4DFv%089UR#n5xV{c(A%_;h@MIFE7zBRbBZGVei=rUom&2F%^F#j2uuE zAXF(ty3`q6y@BOCW?>{lFNOwZaV7N|vpvUeO-OYo!AIbGI{hUn!JgeGYcXnw7A_

YpmGwAP@M{Zpi$WQ}LhrX&ELZlS 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 LK5_Z80-EtZT6lUC diff --git a/py5/jars/dxf/dxf.jar b/py5/jars/dxf/dxf.jar index 7be9032da0065801fb7e68d228f5cb46dfee48bd..36f69ef71e152b3917d992047b81f1d3ce67a3e4 100644 GIT binary patch delta 2121 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 EA6`jpx&QzG diff --git a/py5/jars/py5.jar b/py5/jars/py5.jar index be424b98bfa5fbd9150259294ac356c7773aa644..8c0974f4e87e96c6250d0f32801de49d11ddd2f4 100644 GIT binary patch delta 13342 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 MC7{LG%=f48KL&Xt%K!iX delta 2804 zcmZA3X*?9%9tZF-!Wc6oGh~vfk%)mk2wks6!e4`k-bJGWpotJVL=Pqd zjF;|@h==8(QGO;eAq~L|fd6YfEO_j9#Gwf2S6!?yJWUj1u;Dza^xMxxtqrxHRKxFn zW1nXy<}jGz?w=^Wc;Eh-gFII1Bz>@*#O})b*8_v8)bKV@hX;1kVLMuzvFa8^3ptP; z+&Cg8{Vi(}G0W+-`hLrcTiK*O>Ncpp(fkk~9AlXzKY%%k+|CJ4elqaP%zS`1i7D4n z$2(5z5&XcrWi^E&7MQx!e4DEP@-?XlzK;**kMNBBeFv6=+=+g_$Y)4>Nh42)e}-mh+($#W;J$ef7z@~2?;pr@t;Ap(=!|Q&IMjuN=lOv ztPGh-A1jVG2=sn7x;X?vRZlaASs1}+k>GO^@j9HwHwCY`k`@z0Ti-qX@e=vc&&lah z^~1NOJ74s+TGql}E#*(P9L?Y)TOsq5gCIVri|O&v*U?Uqo^|$)#T$rKE3{-tDeXm) z*BXIvC$p9Oi5KQF=beSe1zjOuoK~I&!X?0qh#Lj09!XM7Y<}efT*Mfr+jUzj#}r0{ zbWBB`a=CQ)f!;hNTVL7j#gh=yJJLyVPn?NzAS>dN6_Ba-SS9OZ%ChBcP8UP%tMqEZ zhKyCRK_qp7Ki8KMHcV_?83oI+`BVCoO=Ogd&T!-n=)6IRV>)r>kxfM`I+u4^3m0@Q z6+B>7hGop71f3*=7FHb2c{}<$8CaY_M83o!mv zEO~cwCwj3rqzPAfQw^aVuUic34(o}K~_P~qhz1{>5kLDITl#x8+p7lm!<@oj9&IZv0I=iu}Ss=4W zrhcZu&}NX^$u4W4zMw!qTo|97Ga=P6wwf!minZa3k?NWta7oE4%_{ePK0PcISp?j$ z{*X#z#5FdMo4C5Zr7KMej@GUpX6ttrTIFU!Bw)=+PV|O>6d&3s->9zL^0WT3f-RGZ)VX*@>elhG+OsnD?kXknS%6 zW^3E1soi5uXs%*TGH}SckmuSn%;vBlv6o{h5%>4IN6#b0$c=|ld^?J>`tE+2P5DuU z?R&;1HRUfC3SJtkh*X}n9Gq4zoewW77WN(6!3)Et(YDKSpBcEf)kaR#uDT3Wp$`c- z$r#FyN__Hs(b&Yj4#m}z`Tmbn&u;`ZjbjL-rOkl3S0cga7u~cooiF!N$8MTmjjnW+ z`^E*l>-~5O-+k^;2#CY|0QP7^;Q`z*IMnI;V+{$ZB<*cprewDRaqoJIjpB3JgBY~* z`YxiiJ*7l%4*PeMB-lf|s61U6A7iG3Gw98&r*BeyO;*3<9K_>=z7!^8XGoYST{RG! zvBcg082jej;FmRpJ5%>*%dYA?{y{dKsAb;9TRrFDuTIF?PbY}x3%Cn&JDGRxYA!?8 z$w%LrpzrpoYss(r8TyMi)=!QD2dxY*DWmJAB1oh#?PDYj!Oc4kn)S(8pVCE~sNiZ4 z zi!p19bMViVcC9DxqA6PoQ7YXzP3yeoa~=lx#kvs(iR8;>uA{n&mFI?M%h*Pr*p@{Z3i^`u5WqE5^L*pJVA*^9k!o!n;n| zov&)ok@B_QHAT(kp?=SEG7BQkyus56&hiOBLrt^j_ABr68nXv=gS2O!ttJGvD270_ ze%z?Ik4#SKax&;4Sd9B<&-nyI{o^UjZK-fA2% z+YV~neD_)&_LYdGts9~10eT#or2G}KWS68>PUpd}&Js5${PF0IPs47EiBVl8`S94? zdDX~IM-FoaT&EHmD35|z(VxnvCj3}EF)d=(>!XwMd4{V9?hm791UgpWHP-5rrrjBE zkEXD>%)lXwxk`KG!B-?FM>r45bG`jOXoNXW&j_%8U7NG@P zr0FgcdfE;=4Cv}<7}P01vQ)+jPtQM z6bd%IAHE1;O89|O>))Vj#DsU3)`Ug7a&&gVlrqdKN7M+ZB)q;IQfG%ZBxn0TX?SFk2L>JAB(qw_Agv*IY z?c@68Am56pVEL%y0mq$v7b1cH!jKL-muvi~@v_Iv&D;z%6TtlL zrvk%npu)Y6*QG%Af9^Yi0ClIHWRv#fPwdxq0}V&^97!P~EnGJm69I z!D6J#00qJr|K~;G3${!D1S63JBKzBU#48X4Lo4wn1Yz}ydp|MxXK?(P9S3|=Tl=~4 z!Ft;}`uVwfIZOHlI!pe{`A^Kh_3_J!LO=lECL;jA{^v3PP#g&(4ns~Oe+B#&%1_2F V9R~o;{^N`@5ek)Irm+3m{1@5=Db@f0 diff --git a/py5/keyevent.py b/py5/keyevent.py index 11a0364..2fdae71 100644 --- a/py5/keyevent.py +++ b/py5/keyevent.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -24,6 +24,8 @@ from jpype.types import JInt, JChar +from . import spelling + def _convert_jchar_to_chr(f): @functools.wraps(f) @@ -56,10 +58,10 @@ class Py5KeyEvent: Datatype for providing information about key events. An instance of this class will be passed to user-defined key event functions if py5 detects those functions accept 1 (positional) argument, as demonstrated in the example code. - The key event functions can be any of ``key_pressed()``, ``key_typed()``, or - ``key_released()``. Key events can be generated faster than the frame rate of - the Sketch, making key event functions useful for capturing all of a user's - keyboard activity. + The key event functions can be any of `key_pressed()`, `key_typed()`, or + `key_released()`. Key events can be generated faster than the frame rate of the + Sketch, making key event functions useful for capturing all of a user's keyboard + activity. """ _py5_object_cache = weakref.WeakSet() @@ -73,6 +75,27 @@ def __new__(cls, pkeyevent): cls._py5_object_cache.add(o) return o + def __str__(self): + key = self.get_key() + action = self.get_action() + + action_str = 'UNKNOWN' + for k, v in Py5KeyEvent.__dict__.items(): + if k == k.upper() and action == v: + action_str = k + break + + if key == '\uffff': # py5.CODED + key = 'CODED' + + return f"Py5KeyEvent(key=" + key + ", action=" + action_str + ")" + + def __repr__(self): + return self.__str__() + + def __getattr__(self, name): + raise AttributeError(spelling.error_msg('Py5KeyEvent', name, self)) + ALT = 8 CTRL = 2 META = 4 @@ -103,9 +126,9 @@ def get_key(self) -> chr: Notes ----- - Return the key for the key event. If the value is ``CODED``, use - ``Py5KeyEvent.get_key_code()`` instead. This information can also be obtained - with ``key``. + Return the key for the key event. If the value is `CODED`, use + `Py5KeyEvent.get_key_code()` instead. This information can also be obtained with + `key`. """ return self._instance.getKey() @@ -120,7 +143,7 @@ def get_key_code(self) -> int: Return the key code for the key event. This method is important for key events involving coded keys such as the arrow or modifier keys. This information can - also be obtained with ``key_code``. + also be obtained with `key_code`. """ return self._instance.getKeyCode() @@ -164,8 +187,8 @@ def get_native(self) -> Any: system the Sketch is run on. Sometimes the native object can be used to access functionality not otherwise available through Processing or py5. - Be aware that it is possible for the native event object to be ``None``, such as - when interacting with a Sketch through ``py5_tools.sketch_portal()``. + Be aware that it is possible for the native event object to be `None`, such as + when interacting with a Sketch through `py5_tools.sketch_portal()`. """ return self._instance.getNative() diff --git a/py5/mixins/__init__.py b/py5/mixins/__init__.py index 1843854..2b6dbc6 100644 --- a/py5/mixins/__init__.py +++ b/py5/mixins/__init__.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by diff --git a/py5/mixins/data.py b/py5/mixins/data.py index 4aa7908..c380bfe 100644 --- a/py5/mixins/data.py +++ b/py5/mixins/data.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -51,14 +51,14 @@ def load_json( Load a JSON data file from a file or URL. When loading a file, the path can be in the data directory, relative to the current working directory - (``sketch_path()``), or an absolute path. When loading from a URL, the - ``json_path`` parameter must start with ``http://`` or ``https://``. + (`sketch_path()`), or an absolute path. When loading from a URL, the `json_path` + parameter must start with `http://` or `https://`. When loading JSON data from a URL, the data is retrieved using the Python - requests library with the ``get`` method, and any extra keyword arguments (the - ``kwargs`` parameter) are passed along to that method. When loading JSON data - from a file, the data is loaded using the Python json library with the ``load`` - method, and again any extra keyword arguments are passed along to that method.""" + requests library with the `get` method, and any extra keyword arguments (the + `kwargs` parameter) are passed along to that method. When loading JSON data from + a file, the data is loaded using the Python json library with the `load` method, + and again any extra keyword arguments are passed along to that method.""" if isinstance( json_path, str) and re.match( @@ -109,12 +109,12 @@ def save_json(self, Notes ----- - Save JSON data to a file. If ``filename`` is not an absolute path, it will be - saved relative to the current working directory (``sketch_path()``). The saved - file can be reloaded with ``load_json()``. + Save JSON data to a file. If `filename` is not an absolute path, it will be + saved relative to the current working directory (`sketch_path()`). The saved + file can be reloaded with `load_json()`. - The JSON data is saved using the Python json library with the ``dump`` method, - and the ``kwargs`` parameter is passed along to that method.""" + The JSON data is saved using the Python json library with the `dump` method, and + the `kwargs` parameter is passed along to that method.""" path = Path(filename) if not path.is_absolute(): cwd = self.sketch_path() @@ -141,10 +141,10 @@ def parse_json(cls, serialized_json: Any, **kwargs: dict[str, Any]) -> Any: ----- Parse serialized JSON data from a string. When reading JSON data from a file, - ``load_json()`` is the better choice. + `load_json()` is the better choice. - The JSON data is parsed using the Python json library with the ``loads`` method, - and the ``kwargs`` parameter is passed along to that method.""" + The JSON data is parsed using the Python json library with the `loads` method, + and the `kwargs` parameter is passed along to that method.""" return json.loads(serialized_json, **kwargs) def load_strings( @@ -167,13 +167,13 @@ def load_strings( Load a list of strings from a file or URL. When loading a file, the path can be in the data directory, relative to the current working directory - (``sketch_path()``), or an absolute path. When loading from a URL, the - ``string_path`` parameter must start with ``http://`` or ``https://``. + (`sketch_path()`), or an absolute path. When loading from a URL, the + `string_path` parameter must start with `http://` or `https://`. When loading string data from a URL, the data is retrieved using the Python - requests library with the ``get`` method, and any extra keyword arguments (the - ``kwargs`` parameter) are passed along to that method. When loading string data - from a file, the ``kwargs`` parameter is not used.""" + requests library with the `get` method, and any extra keyword arguments (the + `kwargs` parameter) are passed along to that method. When loading string data + from a file, the `kwargs` parameter is not used.""" if isinstance( string_path, str) and re.match( @@ -225,16 +225,16 @@ def save_strings(self, Notes ----- - Save a list of strings to a file. If ``filename`` is not an absolute path, it - will be saved relative to the current working directory (``sketch_path()``). If - the contents of the list are not already strings, it will be converted to - strings with the Python builtin ``str``. The saved file can be reloaded with - ``load_strings()``. + Save a list of strings to a file. If `filename` is not an absolute path, it will + be saved relative to the current working directory (`sketch_path()`). If the + contents of the list are not already strings, it will be converted to strings + with the Python builtin `str`. The saved file can be reloaded with + `load_strings()`. - Use the ``end`` parameter to set the line terminator for each string in the - list. If items in the list of strings already have line terminators, set the - ``end`` parameter to ``''`` to keep the output file from being saved with a - blank line after each item.""" + Use the `end` parameter to set the line terminator for each string in the list. + If items in the list of strings already have line terminators, set the `end` + parameter to `''` to keep the output file from being saved with a blank line + after each item.""" path = Path(filename) if not path.is_absolute(): path = self.sketch_path() / filename @@ -262,14 +262,14 @@ def load_bytes( ----- Load byte data from a file or URL. When loading a file, the path can be in the - data directory, relative to the current working directory (``sketch_path()``), - or an absolute path. When loading from a URL, the ``bytes_path`` parameter must - start with ``http://`` or ``https://``. + data directory, relative to the current working directory (`sketch_path()`), or + an absolute path. When loading from a URL, the `bytes_path` parameter must start + with `http://` or `https://`. When loading byte data from a URL, the data is retrieved using the Python - requests library with the ``get`` method, and any extra keyword arguments (the - ``kwargs`` parameter) are passed along to that method. When loading byte data - from a file, the ``kwargs`` parameter is not used.""" + requests library with the `get` method, and any extra keyword arguments (the + `kwargs` parameter) are passed along to that method. When loading byte data from + a file, the `kwargs` parameter is not used.""" if isinstance( bytes_path, str) and re.match( @@ -317,9 +317,9 @@ def save_bytes(self, Notes ----- - Save byte data to a file. If ``filename`` is not an absolute path, it will be - saved relative to the current working directory (``sketch_path()``). The saved - file can be reloaded with ``load_bytes()``.""" + Save byte data to a file. If `filename` is not an absolute path, it will be + saved relative to the current working directory (`sketch_path()`). The saved + file can be reloaded with `load_bytes()`.""" path = Path(filename) if not path.is_absolute(): path = self.sketch_path() / filename @@ -343,7 +343,7 @@ def load_pickle(self, pickle_path: Union[str, Path]) -> Any: ----- Load a pickled Python object from a file. The path can be in the data directory, - relative to the current working directory (``sketch_path()``), or an absolute + relative to the current working directory (`sketch_path()`), or an absolute path. There are security risks associated with Python pickle files. A pickle file can @@ -378,9 +378,9 @@ def save_pickle(self, obj: Any, filename: Union[str, Path]) -> None: Notes ----- - Pickle a Python object to a file. If ``filename`` is not an absolute path, it - will be saved relative to the current working directory (``sketch_path()``). The - saved file can be reloaded with ``load_pickle()``. + Pickle a Python object to a file. If `filename` is not an absolute path, it will + be saved relative to the current working directory (`sketch_path()`). The saved + file can be reloaded with `load_pickle()`. Object "pickling" is a method for serializing objects and saving them to a file for later retrieval. The recreated objects will be clones of the original diff --git a/py5/mixins/math.py b/py5/mixins/math.py index 8e52f32..25a47f1 100644 --- a/py5/mixins/math.py +++ b/py5/mixins/math.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -22,6 +22,7 @@ import warnings import traceback from pathlib import Path +import types from typing import overload, Union, Any import numpy as np @@ -65,13 +66,13 @@ def hex_color(cls, color: int) -> str: Convert a color value to a hex color string. Processing and py5 store color values in 32 bit integers that are inconvenient for a human to parse. To - interpret these values, one can use methods like ``red()``, ``green()``, and - ``blue()`` to extract color channel values from the 32 bit integers. This method + interpret these values, one can use methods like `red()`, `green()`, and + `blue()` to extract color channel values from the 32 bit integers. This method provides an alternative approach, converting the 32 bit integer into a string - such as ``'#0F3FF0FF'``. The hex string has 8 hexadecimal values following a - ``#`` character. The first two values represent the red value, the next two - green, the next two blue, and the last two alpha. This is consistent with CSS 8 - digit hex colors. + such as `'#0F3FF0FF'`. The hex string has 8 hexadecimal values following a `#` + character. The first two values represent the red value, the next two green, the + next two blue, and the last two alpha. This is consistent with CSS 8 digit hex + colors. Conveniently, the hex color string returned by this method can also be used as parameter for other methods that accept color values. Observe how this is done @@ -94,10 +95,10 @@ def sin(cls, angle: Union[float, npt.ArrayLike] ----- Calculates the sine of an angle. This function expects the values of the angle - parameter to be provided in radians (values from ``0`` to ``TWO_PI``). Values - are returned in the range -1 to 1. + parameter to be provided in radians (values from `0` to `TWO_PI`). Values are + returned in the range -1 to 1. - This function makes a call to the numpy ``sin()`` function.""" + This function makes a call to the numpy `sin()` function.""" return np.sin(angle) @classmethod @@ -115,10 +116,10 @@ def cos(cls, angle: Union[float, npt.ArrayLike] ----- Calculates the cosine of an angle. This function expects the values of the angle - parameter to be provided in radians (values from ``0`` to ``TWO_PI``). Values - are returned in the range -1 to 1. + parameter to be provided in radians (values from `0` to `TWO_PI`). Values are + returned in the range -1 to 1. - This function makes a call to the numpy ``cos()`` function.""" + This function makes a call to the numpy `cos()` function.""" return np.cos(angle) @classmethod @@ -136,16 +137,16 @@ def tan(cls, angle: Union[float, npt.ArrayLike] ----- Calculates the ratio of the sine and cosine of an angle. This function expects - the values of the angle parameter to be provided in radians (values from ``0`` - to ``TWO_PI``). Values are returned in the range infinity to -infinity. + the values of the angle parameter to be provided in radians (values from `0` to + `TWO_PI`). Values are returned in the range infinity to -infinity. - This function makes a call to the numpy ``tan()`` function.""" + This function makes a call to the numpy `tan()` function.""" return np.tan(angle) @classmethod def asin(cls, value: Union[float, npt.ArrayLike] ) -> Union[float, npt.NDArray]: - """The inverse of ``sin()``, returns the arc sine of a value. + """The inverse of `sin()`, returns the arc sine of a value. Parameters ---------- @@ -156,17 +157,17 @@ def asin(cls, value: Union[float, npt.ArrayLike] Notes ----- - The inverse of ``sin()``, returns the arc sine of a value. This function expects + The inverse of `sin()`, returns the arc sine of a value. This function expects the values in the range of -1 to 1 and values are returned in the range - ``-HALF_PI`` to ``HALF_PI``. + `-HALF_PI` to `HALF_PI`. - This function makes a call to the numpy ``asin()`` function.""" + This function makes a call to the numpy `asin()` function.""" return np.arcsin(value) @classmethod def acos(cls, value: Union[float, npt.ArrayLike] ) -> Union[float, npt.NDArray]: - """The inverse of ``cos()``, returns the arc cosine of a value. + """The inverse of `cos()`, returns the arc cosine of a value. Parameters ---------- @@ -177,17 +178,17 @@ def acos(cls, value: Union[float, npt.ArrayLike] Notes ----- - The inverse of ``cos()``, returns the arc cosine of a value. This function - expects the values in the range of -1 to 1 and values are returned in the range - ``0`` to ``PI``. + The inverse of `cos()`, returns the arc cosine of a value. This function expects + the values in the range of -1 to 1 and values are returned in the range `0` to + `PI`. - This function makes a call to the numpy ``acos()`` function.""" + This function makes a call to the numpy `acos()` function.""" return np.arccos(value) @classmethod def atan(cls, value: Union[float, npt.ArrayLike] ) -> Union[float, npt.NDArray]: - """The inverse of ``tan()``, returns the arc tangent of a value. + """The inverse of `tan()`, returns the arc tangent of a value. Parameters ---------- @@ -198,11 +199,11 @@ def atan(cls, value: Union[float, npt.ArrayLike] Notes ----- - The inverse of ``tan()``, returns the arc tangent of a value. This function + The inverse of `tan()`, returns the arc tangent of a value. This function expects the values in the range of -Infinity to Infinity and values are returned - in the range ``-HALF_PI`` to ``HALF_PI``. + in the range `-HALF_PI` to `HALF_PI`. - This function makes a call to the numpy ``atan()`` function.""" + This function makes a call to the numpy `atan()` function.""" return np.arctan(value) @classmethod @@ -229,12 +230,12 @@ def atan2(cls, Calculates the angle (in radians) from a specified point to the coordinate origin as measured from the positive x-axis. Values are returned as a float in - the range from ``PI`` to ``-PI``. The ``atan2()`` function is most often used - for orienting geometry to the position of the cursor. Note: The y-coordinate of - the point is the first parameter, and the x-coordinate is the second parameter, - due the the structure of calculating the tangent. + the range from `PI` to `-PI`. The `atan2()` function is most often used for + orienting geometry to the position of the cursor. Note: The y-coordinate of the + point is the first parameter, and the x-coordinate is the second parameter, due + the the structure of calculating the tangent. - This function makes a call to the numpy ``atan2()`` function.""" + This function makes a call to the numpy `atan2()` function.""" return np.arctan2(y, x) @classmethod @@ -255,11 +256,11 @@ def degrees(cls, Converts a radian measurement to its corresponding value in degrees. Radians and degrees are two ways of measuring the same thing. There are 360 degrees in a - circle and ``2*PI`` radians in a circle. For example, ``90° = PI/2 = - 1.5707964``. All trigonometric functions in py5 require their parameters to be - specified in radians. + circle and `2*PI` radians in a circle. For example, `90° = PI/2 = 1.5707964`. + All trigonometric functions in py5 require their parameters to be specified in + radians. - This function makes a call to the numpy ``degrees()`` function.""" + This function makes a call to the numpy `degrees()` function.""" return np.degrees(radians) @classmethod @@ -280,11 +281,11 @@ def radians(cls, Converts a degree measurement to its corresponding value in radians. Radians and degrees are two ways of measuring the same thing. There are 360 degrees in a - circle and ``2*PI`` radians in a circle. For example, ``90° = PI/2 = - 1.5707964``. All trigonometric functions in py5 require their parameters to be - specified in radians. + circle and `2*PI` radians in a circle. For example, `90° = PI/2 = 1.5707964`. + All trigonometric functions in py5 require their parameters to be specified in + radians. - This function makes a call to the numpy ``radians()`` function.""" + This function makes a call to the numpy `radians()` function.""" return np.radians(degrees) @classmethod @@ -356,14 +357,14 @@ def remap(cls, In the first example, the number 0.5 is converted from a value in the range of 0 to 1 into a value that ranges from the left edge of the window (0) to the right - edge (``width``). + edge (`width`). As shown in the second example, numbers outside of the range are not clamped to the minimum and maximum parameters values, because out-of-range values are often intentional and useful. If that isn't what you want, try pairing this function - with ``constrain()``. + with `constrain()`. - In Processing this functionality is provided by ``map()`` but was renamed in py5 + In Processing this functionality is provided by `map()` but was renamed in py5 because of a name conflict with a builtin Python function.""" denom = stop1 - start1 if denom == 0: @@ -537,13 +538,13 @@ def lerp(cls, Notes ----- - Calculates a number between two numbers at a specific increment. The ``amt`` + Calculates a number between two numbers at a specific increment. The `amt` parameter is the amount to interpolate between the two values where 0.0 equal to the first point, 0.1 is very near the first point, 0.5 is half-way in between, etc. The lerp function is convenient for creating motion along a straight path - and for drawing dotted lines. If the ``amt`` parameter is greater than 1.0 or - less than 0.0, the interpolated value will be outside of the range specified by - the ``start`` and ``stop`` parameter values.""" + and for drawing dotted lines. If the `amt` parameter is greater than 1.0 or less + than 0.0, the interpolated value will be outside of the range specified by the + `start` and `stop` parameter values.""" return amt * (stop - start) + start @overload @@ -577,8 +578,8 @@ def mag(cls, a: Union[float, npt.NDArray], Calculates the magnitude (or length) of a vector. A vector is a direction in space commonly used in computer graphics and linear algebra. Because it has no "start" position, the magnitude of a vector can be thought of as the distance - from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is - a shortcut for writing ``dist(0, 0, x, y)``.""" + from the coordinate `(0, 0)` to its `(x, y)` value. Therefore, `mag()` is a + shortcut for writing `dist(0, 0, x, y)`.""" pass @overload @@ -612,8 +613,8 @@ def mag(cls, a: Union[float, npt.NDArray], b: Union[float, Calculates the magnitude (or length) of a vector. A vector is a direction in space commonly used in computer graphics and linear algebra. Because it has no "start" position, the magnitude of a vector can be thought of as the distance - from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is - a shortcut for writing ``dist(0, 0, x, y)``.""" + from the coordinate `(0, 0)` to its `(x, y)` value. Therefore, `mag()` is a + shortcut for writing `dist(0, 0, x, y)`.""" pass @classmethod @@ -646,8 +647,8 @@ def mag(cls, *args: Union[float, npt.NDArray]) -> float: Calculates the magnitude (or length) of a vector. A vector is a direction in space commonly used in computer graphics and linear algebra. Because it has no "start" position, the magnitude of a vector can be thought of as the distance - from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is - a shortcut for writing ``dist(0, 0, x, y)``.""" + from the coordinate `(0, 0)` to its `(x, y)` value. Therefore, `mag()` is a + shortcut for writing `dist(0, 0, x, y)`.""" return sum([x * x for x in args])**0.5 @classmethod @@ -677,11 +678,11 @@ def norm(cls, ----- Normalizes a number from another range into a value between 0 and 1. Identical - to ``remap(value, low, high, 0, 1)``. + to `remap(value, low, high, 0, 1)`. Numbers outside of the range are not clamped to 0 and 1, because out-of-range values are often intentional and useful. (See the second example.) If that isn't - what you want, try pairing this function with ``constrain()``.""" + what you want, try pairing this function with `constrain()`.""" return (value - start) / (stop - start) @classmethod @@ -699,7 +700,7 @@ def sq(cls, value: Union[float, npt.NDArray]) -> Union[float, npt.NDArray]: Squares a number (multiplies a number by itself). The result is always a positive number, as multiplying two negative numbers always yields a positive - result. For example, ``-1 * -1 = 1``.""" + result. For example, `-1 * -1 = 1`.""" return value * value @classmethod @@ -718,14 +719,14 @@ def sqrt(cls, value: Union[float, npt.NDArray] Calculates the square root of a number. The square root of a positive number is always positive, even though there may be a valid negative root. The square root - of a negative number is a complex number. In either case, the square root ``s`` - of number ``a`` is such that ``s*s = a``. It is the opposite of squaring. + of a negative number is a complex number. In either case, the square root `s` of + number `a` is such that `s*s = a`. It is the opposite of squaring. Python supports complex numbers, but such values cannot be passed to py5 drawing - functions. When using the ``sqrt()`` function, you should check if the result is + functions. When using the `sqrt()` function, you should check if the result is complex before using the value. You can also extract the real and imaginary - components of the complex value with ``.real`` and ``.imag``. See the second - example to learn how to do both of these things.""" + components of the complex value with `.real` and `.imag`. See the second example + to learn how to do both of these things.""" return value**0.5 @classmethod @@ -746,7 +747,7 @@ def floor(cls, value: Union[float, npt.ArrayLike] Calculates the closest int value that is less than or equal to the value of the parameter. - This function makes a call to the numpy ``floor()`` function.""" + This function makes a call to the numpy `floor()` function.""" return np.floor(value).astype(np.int_) @classmethod @@ -767,14 +768,13 @@ def ceil(cls, value: Union[float, npt.ArrayLike] Calculates the closest int value that is greater than or equal to the value of the parameter. - This function makes a call to the numpy ``ceil()`` function.""" + This function makes a call to the numpy `ceil()` function.""" return np.ceil(value).astype(np.int_) @classmethod def exp(cls, value: Union[float, npt.ArrayLike] ) -> Union[float, npt.NDArray]: - """Returns Euler's number e (2.71828...) raised to the power of the ``n`` - parameter. + """Returns Euler's number e (2.71828...) raised to the power of the `n` parameter. Parameters ---------- @@ -785,10 +785,10 @@ def exp(cls, value: Union[float, npt.ArrayLike] Notes ----- - Returns Euler's number e (2.71828...) raised to the power of the ``n`` - parameter. This function is the compliment to ``log()``. + Returns Euler's number e (2.71828...) raised to the power of the `n` parameter. + This function is the compliment to `log()`. - This function makes a call to the numpy ``exp()`` function.""" + This function makes a call to the numpy `exp()` function.""" return np.exp(value) @classmethod @@ -806,12 +806,12 @@ def log(cls, value: Union[float, npt.ArrayLike] ----- Calculates the natural logarithm (the base-e logarithm) of a number. This - function expects the ``n`` parameter to be a value greater than 0.0. This - function is the compliment to ``exp()``. + function expects the `n` parameter to be a value greater than 0.0. This function + is the compliment to `exp()`. - This function makes a call to the numpy ``log()`` function. If the ``n`` - parameter is less than or equal to 0.0, you will see a ``RuntimeWarning`` and - the returned result will be numpy's Not-a-Number value, ``np.nan``.""" + This function makes a call to the numpy `log()` function. If the `n` parameter + is less than or equal to 0.0, you will see a `RuntimeWarning` and the returned + result will be numpy's Not-a-Number value, `np.nan`.""" return np.log(value) def _get_np_random(self) -> np.random.Generator: @@ -823,13 +823,13 @@ def _get_np_random(self) -> np.random.Generator: Access the numpy random number generator that py5 uses to provide random number functionality. Py5 uses a numpy random number generator to provide a breadth of - random number functions such as ``random_choice()``, ``random_gaussian()``, and - ``random_int()``. The functions py5 provides are the ones you are most likely to + random number functions such as `random_choice()`, `random_gaussian()`, and + `random_int()`. The functions py5 provides are the ones you are most likely to need, but numpy is capable of much more than what py5 makes available. Access this property to access all of numpy's random number functions. All of the random numbers generated through this property can be influenced by - ``random_seed()``.""" + `random_seed()`.""" return self._rng np_random: np.random.Generator = property( fget=_get_np_random, @@ -841,13 +841,13 @@ def _get_np_random(self) -> np.random.Generator: Access the numpy random number generator that py5 uses to provide random number functionality. Py5 uses a numpy random number generator to provide a breadth of - random number functions such as ``random_choice()``, ``random_gaussian()``, and - ``random_int()``. The functions py5 provides are the ones you are most likely to + random number functions such as `random_choice()`, `random_gaussian()`, and + `random_int()`. The functions py5 provides are the ones you are most likely to need, but numpy is capable of much more than what py5 makes available. Access this property to access all of numpy's random number functions. All of the random numbers generated through this property can be influenced by - ``random_seed()``.""") + `random_seed()`.""") def random_seed(self, seed: int) -> None: """Sets the seed value for py5's random functions. @@ -861,11 +861,11 @@ def random_seed(self, seed: int) -> None: Notes ----- - Sets the seed value for py5's random functions. This includes ``random()``, - ``random_int()``, ``random_choice()``, and ``random_gaussian()``. By default, - all of these functions would produce different results each time a program is - run. Set the seed parameter to a constant value to return the same pseudo-random - numbers each time the software is run.""" + Sets the seed value for py5's random functions. This includes `random()`, + `random_int()`, `random_choice()`, and `random_gaussian()`. By default, all of + these functions would produce different results each time a program is run. Set + the seed parameter to a constant value to return the same pseudo-random numbers + each time the software is run.""" self._rng = np.random.default_rng(seed) @overload @@ -893,22 +893,22 @@ def random(self) -> float: Notes ----- - Generates random numbers. Each time the ``random()`` function is called, it + Generates random numbers. Each time the `random()` function is called, it returns an unexpected value within the specified range. This function's - randomness can be influenced by ``random_seed()``. + randomness can be influenced by `random_seed()`. If no parameters are passed to the function, it will return a float between zero and one. If only one parameter is passed to the function, it will return a float between - zero and the value of the ``high`` parameter. For example, ``random(5)`` returns + zero and the value of the `high` parameter. For example, `random(5)` returns values between 0 and 5 (starting at zero, and up to, but not including, 5). If two parameters are specified, the function will return a float with a value - between the two values. For example, ``random(-5, 10.2)`` returns values - starting at -5 and up to (but not including) 10.2. To convert a floating-point - random number to an integer, use the ``int()`` function, or alternatively, - consider using ``random_int()``. + between the two values. For example, `random(-5, 10.2)` returns values starting + at -5 and up to (but not including) 10.2. To convert a floating-point random + number to an integer, use the `int()` function, or alternatively, consider using + `random_int()`. This function makes calls to numpy to generate the random values.""" pass @@ -938,22 +938,22 @@ def random(self, high: float, /) -> float: Notes ----- - Generates random numbers. Each time the ``random()`` function is called, it + Generates random numbers. Each time the `random()` function is called, it returns an unexpected value within the specified range. This function's - randomness can be influenced by ``random_seed()``. + randomness can be influenced by `random_seed()`. If no parameters are passed to the function, it will return a float between zero and one. If only one parameter is passed to the function, it will return a float between - zero and the value of the ``high`` parameter. For example, ``random(5)`` returns + zero and the value of the `high` parameter. For example, `random(5)` returns values between 0 and 5 (starting at zero, and up to, but not including, 5). If two parameters are specified, the function will return a float with a value - between the two values. For example, ``random(-5, 10.2)`` returns values - starting at -5 and up to (but not including) 10.2. To convert a floating-point - random number to an integer, use the ``int()`` function, or alternatively, - consider using ``random_int()``. + between the two values. For example, `random(-5, 10.2)` returns values starting + at -5 and up to (but not including) 10.2. To convert a floating-point random + number to an integer, use the `int()` function, or alternatively, consider using + `random_int()`. This function makes calls to numpy to generate the random values.""" pass @@ -983,22 +983,22 @@ def random(self, low: float, high: float, /) -> float: Notes ----- - Generates random numbers. Each time the ``random()`` function is called, it + Generates random numbers. Each time the `random()` function is called, it returns an unexpected value within the specified range. This function's - randomness can be influenced by ``random_seed()``. + randomness can be influenced by `random_seed()`. If no parameters are passed to the function, it will return a float between zero and one. If only one parameter is passed to the function, it will return a float between - zero and the value of the ``high`` parameter. For example, ``random(5)`` returns + zero and the value of the `high` parameter. For example, `random(5)` returns values between 0 and 5 (starting at zero, and up to, but not including, 5). If two parameters are specified, the function will return a float with a value - between the two values. For example, ``random(-5, 10.2)`` returns values - starting at -5 and up to (but not including) 10.2. To convert a floating-point - random number to an integer, use the ``int()`` function, or alternatively, - consider using ``random_int()``. + between the two values. For example, `random(-5, 10.2)` returns values starting + at -5 and up to (but not including) 10.2. To convert a floating-point random + number to an integer, use the `int()` function, or alternatively, consider using + `random_int()`. This function makes calls to numpy to generate the random values.""" pass @@ -1027,22 +1027,22 @@ def random(self, *args: float) -> float: Notes ----- - Generates random numbers. Each time the ``random()`` function is called, it + Generates random numbers. Each time the `random()` function is called, it returns an unexpected value within the specified range. This function's - randomness can be influenced by ``random_seed()``. + randomness can be influenced by `random_seed()`. If no parameters are passed to the function, it will return a float between zero and one. If only one parameter is passed to the function, it will return a float between - zero and the value of the ``high`` parameter. For example, ``random(5)`` returns + zero and the value of the `high` parameter. For example, `random(5)` returns values between 0 and 5 (starting at zero, and up to, but not including, 5). If two parameters are specified, the function will return a float with a value - between the two values. For example, ``random(-5, 10.2)`` returns values - starting at -5 and up to (but not including) 10.2. To convert a floating-point - random number to an integer, use the ``int()`` function, or alternatively, - consider using ``random_int()``. + between the two values. For example, `random(-5, 10.2)` returns values starting + at -5 and up to (but not including) 10.2. To convert a floating-point random + number to an integer, use the `int()` function, or alternatively, consider using + `random_int()`. This function makes calls to numpy to generate the random values.""" if len(args) == 0: @@ -1087,28 +1087,28 @@ def random_int(self) -> int: Notes ----- - Generates random integers. Each time the ``random_int()`` function is called, it + Generates random integers. Each time the `random_int()` function is called, it returns an unexpected integer within the specified range. This function's - randomness can be influenced by ``random_seed()``. + randomness can be influenced by `random_seed()`. If no parameters are passed to the function, it will return either 0 or 1. - Recall that in a Python boolean expression, 0 evaluates to ``False`` and 1 - evaluates to ``True``. This is equivalent to a coin toss. + Recall that in a Python boolean expression, 0 evaluates to `False` and 1 + evaluates to `True`. This is equivalent to a coin toss. If only one parameter is passed to the function, it will return an integer - between zero and the value of the ``high`` parameter, inclusive. For example, - ``random(5)`` returns one of 0, 1, 2, 3, 4, or 5. + between zero and the value of the `high` parameter, inclusive. For example, + `random(5)` returns one of 0, 1, 2, 3, 4, or 5. If two parameters are specified, the function will return an integer with a - value between the two values, inclusive. For example, ``random(2, 5)`` returns - one of 2, 3, 4, or 5. + value between the two values, inclusive. For example, `random(2, 5)` returns one + of 2, 3, 4, or 5. If you want to pick a random object from a list, recall that Python uses zero- indexing, so the first index value is 0 and the final index value is one less than the list length. Therefore, to pick a random index to use in the list - ``words``, your code should be ``random_int(len(words)-1)``. Omitting the ``-1`` - will (occasionally) result in an index out of range error. Alternatively, you - can also use ``random_choice()`` to pick a random object from a list. + `words`, your code should be `random_int(len(words)-1)`. Omitting the `-1` will + (occasionally) result in an index out of range error. Alternatively, you can + also use `random_choice()` to pick a random object from a list. This function makes calls to numpy to generate the random integers.""" pass @@ -1138,28 +1138,28 @@ def random_int(self, high: int, /) -> int: Notes ----- - Generates random integers. Each time the ``random_int()`` function is called, it + Generates random integers. Each time the `random_int()` function is called, it returns an unexpected integer within the specified range. This function's - randomness can be influenced by ``random_seed()``. + randomness can be influenced by `random_seed()`. If no parameters are passed to the function, it will return either 0 or 1. - Recall that in a Python boolean expression, 0 evaluates to ``False`` and 1 - evaluates to ``True``. This is equivalent to a coin toss. + Recall that in a Python boolean expression, 0 evaluates to `False` and 1 + evaluates to `True`. This is equivalent to a coin toss. If only one parameter is passed to the function, it will return an integer - between zero and the value of the ``high`` parameter, inclusive. For example, - ``random(5)`` returns one of 0, 1, 2, 3, 4, or 5. + between zero and the value of the `high` parameter, inclusive. For example, + `random(5)` returns one of 0, 1, 2, 3, 4, or 5. If two parameters are specified, the function will return an integer with a - value between the two values, inclusive. For example, ``random(2, 5)`` returns - one of 2, 3, 4, or 5. + value between the two values, inclusive. For example, `random(2, 5)` returns one + of 2, 3, 4, or 5. If you want to pick a random object from a list, recall that Python uses zero- indexing, so the first index value is 0 and the final index value is one less than the list length. Therefore, to pick a random index to use in the list - ``words``, your code should be ``random_int(len(words)-1)``. Omitting the ``-1`` - will (occasionally) result in an index out of range error. Alternatively, you - can also use ``random_choice()`` to pick a random object from a list. + `words`, your code should be `random_int(len(words)-1)`. Omitting the `-1` will + (occasionally) result in an index out of range error. Alternatively, you can + also use `random_choice()` to pick a random object from a list. This function makes calls to numpy to generate the random integers.""" pass @@ -1189,28 +1189,28 @@ def random_int(self, low: int, high: int, /) -> int: Notes ----- - Generates random integers. Each time the ``random_int()`` function is called, it + Generates random integers. Each time the `random_int()` function is called, it returns an unexpected integer within the specified range. This function's - randomness can be influenced by ``random_seed()``. + randomness can be influenced by `random_seed()`. If no parameters are passed to the function, it will return either 0 or 1. - Recall that in a Python boolean expression, 0 evaluates to ``False`` and 1 - evaluates to ``True``. This is equivalent to a coin toss. + Recall that in a Python boolean expression, 0 evaluates to `False` and 1 + evaluates to `True`. This is equivalent to a coin toss. If only one parameter is passed to the function, it will return an integer - between zero and the value of the ``high`` parameter, inclusive. For example, - ``random(5)`` returns one of 0, 1, 2, 3, 4, or 5. + between zero and the value of the `high` parameter, inclusive. For example, + `random(5)` returns one of 0, 1, 2, 3, 4, or 5. If two parameters are specified, the function will return an integer with a - value between the two values, inclusive. For example, ``random(2, 5)`` returns - one of 2, 3, 4, or 5. + value between the two values, inclusive. For example, `random(2, 5)` returns one + of 2, 3, 4, or 5. If you want to pick a random object from a list, recall that Python uses zero- indexing, so the first index value is 0 and the final index value is one less than the list length. Therefore, to pick a random index to use in the list - ``words``, your code should be ``random_int(len(words)-1)``. Omitting the ``-1`` - will (occasionally) result in an index out of range error. Alternatively, you - can also use ``random_choice()`` to pick a random object from a list. + `words`, your code should be `random_int(len(words)-1)`. Omitting the `-1` will + (occasionally) result in an index out of range error. Alternatively, you can + also use `random_choice()` to pick a random object from a list. This function makes calls to numpy to generate the random integers.""" pass @@ -1239,28 +1239,28 @@ def random_int(self, *args: int) -> int: Notes ----- - Generates random integers. Each time the ``random_int()`` function is called, it + Generates random integers. Each time the `random_int()` function is called, it returns an unexpected integer within the specified range. This function's - randomness can be influenced by ``random_seed()``. + randomness can be influenced by `random_seed()`. If no parameters are passed to the function, it will return either 0 or 1. - Recall that in a Python boolean expression, 0 evaluates to ``False`` and 1 - evaluates to ``True``. This is equivalent to a coin toss. + Recall that in a Python boolean expression, 0 evaluates to `False` and 1 + evaluates to `True`. This is equivalent to a coin toss. If only one parameter is passed to the function, it will return an integer - between zero and the value of the ``high`` parameter, inclusive. For example, - ``random(5)`` returns one of 0, 1, 2, 3, 4, or 5. + between zero and the value of the `high` parameter, inclusive. For example, + `random(5)` returns one of 0, 1, 2, 3, 4, or 5. If two parameters are specified, the function will return an integer with a - value between the two values, inclusive. For example, ``random(2, 5)`` returns - one of 2, 3, 4, or 5. + value between the two values, inclusive. For example, `random(2, 5)` returns one + of 2, 3, 4, or 5. If you want to pick a random object from a list, recall that Python uses zero- indexing, so the first index value is 0 and the final index value is one less than the list length. Therefore, to pick a random index to use in the list - ``words``, your code should be ``random_int(len(words)-1)``. Omitting the ``-1`` - will (occasionally) result in an index out of range error. Alternatively, you - can also use ``random_choice()`` to pick a random object from a list. + `words`, your code should be `random_int(len(words)-1)`. Omitting the `-1` will + (occasionally) result in an index out of range error. Alternatively, you can + also use `random_choice()` to pick a random object from a list. This function makes calls to numpy to generate the random integers.""" if len(args) == 0: @@ -1280,11 +1280,33 @@ def random_int(self, *args: int) -> int: raise TypeError( f'No matching overloads found for Sketch.random_int({types})') - def random_choice( + def random_choice(self, objects: list[Any]) -> Any: + """Select a random item from a list. + + Parameters + ---------- + + objects: list[Any] + list of objects to choose from + + Notes + ----- + + Select a random item from a list. The list items can be of any type. If the list + of objects is empty, `None` will be returned. + + This function's randomness can be influenced by `random_seed()`, and makes calls + to numpy to select the random items.""" + if len(objects): + return objects[self._rng.integers(0, len(objects))] + else: + return None + + def random_sample( self, objects: list[Any], size: int = 1, - replace: bool = True) -> Any: + replace: bool = True) -> list[Any]: """Select random items from a list. Parameters @@ -1304,12 +1326,32 @@ def random_choice( Select random items from a list. The list items can be of any type. If multiple items are selected, this function will by default allow the same item to be - selected multiple times. Set the ``replace`` parameter to ``False`` to prevent - the same item from being selected multiple times. - - This function's randomness can be influenced by ``random_seed()``, and makes - calls to numpy to select the random items.""" - return self._rng.choice(objects, size=size, replace=replace) + selected multiple times. Set the `replace` parameter to `False` to prevent the + same item from being selected multiple times. + + The returned value will always be a sequence such as a list or numpy array, even + if only one item is sampled. If you only want to sample one item, consider using + `random_choice()` instead. If the list of objects is empty, an empty list will + be returned. + + This function's randomness can be influenced by `random_seed()`, and makes calls + to numpy to select the random items.""" + if len(objects): + if isinstance(objects, types.GeneratorType): + objects = list(objects) + indices = self._rng.choice( + range( + len(objects)), + size=size, + replace=replace) + if not isinstance(objects, list): + try: + return objects[indices] + except BaseException: + pass + return [objects[idx] for idx in indices] + else: + return [] @overload def random_gaussian(self) -> float: @@ -1336,10 +1378,10 @@ def random_gaussian(self) -> float: Notes ----- - Generates random gaussian values. Each time the ``random_gaussian()`` function - is called, it returns an unexpected float with a probability distribution set by + Generates random gaussian values. Each time the `random_gaussian()` function is + called, it returns an unexpected float with a probability distribution set by the parameters. This function's randomness can be influenced by - ``random_seed()``. + `random_seed()`. If no parameters are passed to the function, returned values will have an average of 0 and a standard deviation of 1. Although there is theoretically no @@ -1380,10 +1422,10 @@ def random_gaussian(self, loc: float, /) -> float: Notes ----- - Generates random gaussian values. Each time the ``random_gaussian()`` function - is called, it returns an unexpected float with a probability distribution set by + Generates random gaussian values. Each time the `random_gaussian()` function is + called, it returns an unexpected float with a probability distribution set by the parameters. This function's randomness can be influenced by - ``random_seed()``. + `random_seed()`. If no parameters are passed to the function, returned values will have an average of 0 and a standard deviation of 1. Although there is theoretically no @@ -1424,10 +1466,10 @@ def random_gaussian(self, loc: float, scale: float, /) -> float: Notes ----- - Generates random gaussian values. Each time the ``random_gaussian()`` function - is called, it returns an unexpected float with a probability distribution set by + Generates random gaussian values. Each time the `random_gaussian()` function is + called, it returns an unexpected float with a probability distribution set by the parameters. This function's randomness can be influenced by - ``random_seed()``. + `random_seed()`. If no parameters are passed to the function, returned values will have an average of 0 and a standard deviation of 1. Although there is theoretically no @@ -1467,10 +1509,10 @@ def random_gaussian(self, *args: float) -> float: Notes ----- - Generates random gaussian values. Each time the ``random_gaussian()`` function - is called, it returns an unexpected float with a probability distribution set by + Generates random gaussian values. Each time the `random_gaussian()` function is + called, it returns an unexpected float with a probability distribution set by the parameters. This function's randomness can be influenced by - ``random_seed()``. + `random_seed()`. If no parameters are passed to the function, returned values will have an average of 0 and a standard deviation of 1. Although there is theoretically no @@ -1535,20 +1577,19 @@ def noise(self, x: Union[float, npt.NDArray], / Generate pseudo-random noise values for specific coodinates using Processing's noise algorithm. Noise functions are random sequence generators that produce a - more natural, harmonic succession of numbers compared to the ``random()`` - method. + more natural, harmonic succession of numbers compared to the `random()` method. - In contrast to the ``random()`` method, noise is defined in an n-dimensional + In contrast to the `random()` method, noise is defined in an n-dimensional space, in which each coordinate corresponds to a fixed pseudo-random value (fixed only for the lifespan of the program). The noise value can be animated by moving through the noise space, as demonstrated in the examples. Any dimension can also be interpreted as time. An easy way to animate the noise value is to - pass the ``noise()`` method the ``frame_count`` divided by a scaling factor, as - is done in a few of the examples. + pass the `noise()` method the `frame_count` divided by a scaling factor, as is + done in a few of the examples. The generated noise values for this method will typically be between 0 and 1, and can be generated in 1, 2, or 3 dimensions. Py5 also provides the - ``os_noise()`` method, which generates noise using the OpenSimplex 2 algorithm + `os_noise()` method, which generates noise using the OpenSimplex 2 algorithm (smooth version / SuperSimplex). That algorithm generates noise values between -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of these differences when modifying your code to switch from one to the other. @@ -1561,8 +1602,8 @@ def noise(self, x: Union[float, npt.NDArray], / both noise algorithms are computed over several octaves which are added together for the final result. - The nature of the noise values returned can be adjusted with ``noise_seed()`` - and ``noise_detail()``. + The nature of the noise values returned can be adjusted with `noise_seed()` and + `noise_detail()`. Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the method works within an infinite space, the value @@ -1572,9 +1613,9 @@ def noise(self, x: Union[float, npt.NDArray], / best for most applications, but this will differ depending on the use case and the noise settings. - Py5's ``noise()`` method can also accept numpy arrays as parameters. It will use + Py5's `noise()` method can also accept numpy arrays as parameters. It will use broadcasting when needed and calculate the values efficiently. Using numpy array - parameters will be much faster and efficient than calling the ``noise()`` method + parameters will be much faster and efficient than calling the `noise()` method repeatedly in a loop. See the examples to see how this can be done. Noise generation is a rich and complex topic, and there are many noise @@ -1625,20 +1666,19 @@ def noise(self, x: Union[float, npt.NDArray], y: Union[float, Generate pseudo-random noise values for specific coodinates using Processing's noise algorithm. Noise functions are random sequence generators that produce a - more natural, harmonic succession of numbers compared to the ``random()`` - method. + more natural, harmonic succession of numbers compared to the `random()` method. - In contrast to the ``random()`` method, noise is defined in an n-dimensional + In contrast to the `random()` method, noise is defined in an n-dimensional space, in which each coordinate corresponds to a fixed pseudo-random value (fixed only for the lifespan of the program). The noise value can be animated by moving through the noise space, as demonstrated in the examples. Any dimension can also be interpreted as time. An easy way to animate the noise value is to - pass the ``noise()`` method the ``frame_count`` divided by a scaling factor, as - is done in a few of the examples. + pass the `noise()` method the `frame_count` divided by a scaling factor, as is + done in a few of the examples. The generated noise values for this method will typically be between 0 and 1, and can be generated in 1, 2, or 3 dimensions. Py5 also provides the - ``os_noise()`` method, which generates noise using the OpenSimplex 2 algorithm + `os_noise()` method, which generates noise using the OpenSimplex 2 algorithm (smooth version / SuperSimplex). That algorithm generates noise values between -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of these differences when modifying your code to switch from one to the other. @@ -1651,8 +1691,8 @@ def noise(self, x: Union[float, npt.NDArray], y: Union[float, both noise algorithms are computed over several octaves which are added together for the final result. - The nature of the noise values returned can be adjusted with ``noise_seed()`` - and ``noise_detail()``. + The nature of the noise values returned can be adjusted with `noise_seed()` and + `noise_detail()`. Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the method works within an infinite space, the value @@ -1662,9 +1702,9 @@ def noise(self, x: Union[float, npt.NDArray], y: Union[float, best for most applications, but this will differ depending on the use case and the noise settings. - Py5's ``noise()`` method can also accept numpy arrays as parameters. It will use + Py5's `noise()` method can also accept numpy arrays as parameters. It will use broadcasting when needed and calculate the values efficiently. Using numpy array - parameters will be much faster and efficient than calling the ``noise()`` method + parameters will be much faster and efficient than calling the `noise()` method repeatedly in a loop. See the examples to see how this can be done. Noise generation is a rich and complex topic, and there are many noise @@ -1715,20 +1755,19 @@ def noise(self, x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], Generate pseudo-random noise values for specific coodinates using Processing's noise algorithm. Noise functions are random sequence generators that produce a - more natural, harmonic succession of numbers compared to the ``random()`` - method. + more natural, harmonic succession of numbers compared to the `random()` method. - In contrast to the ``random()`` method, noise is defined in an n-dimensional + In contrast to the `random()` method, noise is defined in an n-dimensional space, in which each coordinate corresponds to a fixed pseudo-random value (fixed only for the lifespan of the program). The noise value can be animated by moving through the noise space, as demonstrated in the examples. Any dimension can also be interpreted as time. An easy way to animate the noise value is to - pass the ``noise()`` method the ``frame_count`` divided by a scaling factor, as - is done in a few of the examples. + pass the `noise()` method the `frame_count` divided by a scaling factor, as is + done in a few of the examples. The generated noise values for this method will typically be between 0 and 1, and can be generated in 1, 2, or 3 dimensions. Py5 also provides the - ``os_noise()`` method, which generates noise using the OpenSimplex 2 algorithm + `os_noise()` method, which generates noise using the OpenSimplex 2 algorithm (smooth version / SuperSimplex). That algorithm generates noise values between -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of these differences when modifying your code to switch from one to the other. @@ -1741,8 +1780,8 @@ def noise(self, x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], both noise algorithms are computed over several octaves which are added together for the final result. - The nature of the noise values returned can be adjusted with ``noise_seed()`` - and ``noise_detail()``. + The nature of the noise values returned can be adjusted with `noise_seed()` and + `noise_detail()`. Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the method works within an infinite space, the value @@ -1752,9 +1791,9 @@ def noise(self, x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], best for most applications, but this will differ depending on the use case and the noise settings. - Py5's ``noise()`` method can also accept numpy arrays as parameters. It will use + Py5's `noise()` method can also accept numpy arrays as parameters. It will use broadcasting when needed and calculate the values efficiently. Using numpy array - parameters will be much faster and efficient than calling the ``noise()`` method + parameters will be much faster and efficient than calling the `noise()` method repeatedly in a loop. See the examples to see how this can be done. Noise generation is a rich and complex topic, and there are many noise @@ -1803,20 +1842,19 @@ def noise(self, *args) -> Union[float, npt.NDArray]: Generate pseudo-random noise values for specific coodinates using Processing's noise algorithm. Noise functions are random sequence generators that produce a - more natural, harmonic succession of numbers compared to the ``random()`` - method. + more natural, harmonic succession of numbers compared to the `random()` method. - In contrast to the ``random()`` method, noise is defined in an n-dimensional + In contrast to the `random()` method, noise is defined in an n-dimensional space, in which each coordinate corresponds to a fixed pseudo-random value (fixed only for the lifespan of the program). The noise value can be animated by moving through the noise space, as demonstrated in the examples. Any dimension can also be interpreted as time. An easy way to animate the noise value is to - pass the ``noise()`` method the ``frame_count`` divided by a scaling factor, as - is done in a few of the examples. + pass the `noise()` method the `frame_count` divided by a scaling factor, as is + done in a few of the examples. The generated noise values for this method will typically be between 0 and 1, and can be generated in 1, 2, or 3 dimensions. Py5 also provides the - ``os_noise()`` method, which generates noise using the OpenSimplex 2 algorithm + `os_noise()` method, which generates noise using the OpenSimplex 2 algorithm (smooth version / SuperSimplex). That algorithm generates noise values between -1 and 1, and can be generated in 2, 3, or 4 dimensions. Be aware of both of these differences when modifying your code to switch from one to the other. @@ -1829,8 +1867,8 @@ def noise(self, *args) -> Union[float, npt.NDArray]: both noise algorithms are computed over several octaves which are added together for the final result. - The nature of the noise values returned can be adjusted with ``noise_seed()`` - and ``noise_detail()``. + The nature of the noise values returned can be adjusted with `noise_seed()` and + `noise_detail()`. Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the method works within an infinite space, the value @@ -1840,9 +1878,9 @@ def noise(self, *args) -> Union[float, npt.NDArray]: best for most applications, but this will differ depending on the use case and the noise settings. - Py5's ``noise()`` method can also accept numpy arrays as parameters. It will use + Py5's `noise()` method can also accept numpy arrays as parameters. It will use broadcasting when needed and calculate the values efficiently. Using numpy array - parameters will be much faster and efficient than calling the ``noise()`` method + parameters will be much faster and efficient than calling the `noise()` method repeatedly in a loop. See the examples to see how this can be done. Noise generation is a rich and complex topic, and there are many noise @@ -1900,28 +1938,27 @@ def os_noise(self, x: Union[float, npt.NDArray], Generate pseudo-random noise values for specific coodinates using the OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are random sequence generators that produce a more natural, harmonic succession of - numbers compared to the ``random()`` method. + numbers compared to the `random()` method. - In contrast to the ``random()`` method, noise is defined in an n-dimensional + In contrast to the `random()` method, noise is defined in an n-dimensional space, in which each coordinate corresponds to a fixed pseudo-random value (fixed only for the lifespan of the program). The noise value can be animated by moving through the noise space, as demonstrated in the examples. Any dimension can also be interpreted as time. An easy way to animate the noise value is to - pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, - as is done in a few of the examples. + pass the `os_noise()` method the `frame_count` divided by a scaling factor, as + is done in a few of the examples. The generated noise values for this method will be between -1 and 1, and can be generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a constant value as an extra parameter, as shown in a few examples. Py5 also - provides the ``noise()`` method, which generates noise using Processing's noise + provides the `noise()` method, which generates noise using Processing's noise algorithm. That algorithm typically generates noise values between 0 and 1, and can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences when modifying your code to switch from one to the other. There are other differences in the character of the noise values generated by both methods, so you'll need to do some experimentation to get the results you want. - The nature of the noise values returned can be adjusted with - ``os_noise_seed()``. + The nature of the noise values returned can be adjusted with `os_noise_seed()`. Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the method works within an infinite space, the value @@ -1931,11 +1968,11 @@ def os_noise(self, x: Union[float, npt.NDArray], best for most applications, but this will differ depending on the use case and the noise settings. - Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will + Py5's `os_noise()` method can also accept numpy arrays as parameters. It will use broadcasting when needed and calculate the values efficiently. Using numpy - array parameters will be much faster and efficient than calling the - ``os_noise()`` method repeatedly in a loop. See the examples to see how this can - be done. The noise algorithm for this method is implemented in Java. + array parameters will be much faster and efficient than calling the `os_noise()` + method repeatedly in a loop. See the examples to see how this can be done. The + noise algorithm for this method is implemented in Java. Noise generation is a rich and complex topic, and there are many noise algorithms and libraries available that are worth learning about. Early versions @@ -1987,28 +2024,27 @@ def os_noise(self, x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], Generate pseudo-random noise values for specific coodinates using the OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are random sequence generators that produce a more natural, harmonic succession of - numbers compared to the ``random()`` method. + numbers compared to the `random()` method. - In contrast to the ``random()`` method, noise is defined in an n-dimensional + In contrast to the `random()` method, noise is defined in an n-dimensional space, in which each coordinate corresponds to a fixed pseudo-random value (fixed only for the lifespan of the program). The noise value can be animated by moving through the noise space, as demonstrated in the examples. Any dimension can also be interpreted as time. An easy way to animate the noise value is to - pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, - as is done in a few of the examples. + pass the `os_noise()` method the `frame_count` divided by a scaling factor, as + is done in a few of the examples. The generated noise values for this method will be between -1 and 1, and can be generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a constant value as an extra parameter, as shown in a few examples. Py5 also - provides the ``noise()`` method, which generates noise using Processing's noise + provides the `noise()` method, which generates noise using Processing's noise algorithm. That algorithm typically generates noise values between 0 and 1, and can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences when modifying your code to switch from one to the other. There are other differences in the character of the noise values generated by both methods, so you'll need to do some experimentation to get the results you want. - The nature of the noise values returned can be adjusted with - ``os_noise_seed()``. + The nature of the noise values returned can be adjusted with `os_noise_seed()`. Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the method works within an infinite space, the value @@ -2018,11 +2054,11 @@ def os_noise(self, x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], best for most applications, but this will differ depending on the use case and the noise settings. - Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will + Py5's `os_noise()` method can also accept numpy arrays as parameters. It will use broadcasting when needed and calculate the values efficiently. Using numpy - array parameters will be much faster and efficient than calling the - ``os_noise()`` method repeatedly in a loop. See the examples to see how this can - be done. The noise algorithm for this method is implemented in Java. + array parameters will be much faster and efficient than calling the `os_noise()` + method repeatedly in a loop. See the examples to see how this can be done. The + noise algorithm for this method is implemented in Java. Noise generation is a rich and complex topic, and there are many noise algorithms and libraries available that are worth learning about. Early versions @@ -2083,28 +2119,27 @@ def os_noise(self, Generate pseudo-random noise values for specific coodinates using the OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are random sequence generators that produce a more natural, harmonic succession of - numbers compared to the ``random()`` method. + numbers compared to the `random()` method. - In contrast to the ``random()`` method, noise is defined in an n-dimensional + In contrast to the `random()` method, noise is defined in an n-dimensional space, in which each coordinate corresponds to a fixed pseudo-random value (fixed only for the lifespan of the program). The noise value can be animated by moving through the noise space, as demonstrated in the examples. Any dimension can also be interpreted as time. An easy way to animate the noise value is to - pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, - as is done in a few of the examples. + pass the `os_noise()` method the `frame_count` divided by a scaling factor, as + is done in a few of the examples. The generated noise values for this method will be between -1 and 1, and can be generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a constant value as an extra parameter, as shown in a few examples. Py5 also - provides the ``noise()`` method, which generates noise using Processing's noise + provides the `noise()` method, which generates noise using Processing's noise algorithm. That algorithm typically generates noise values between 0 and 1, and can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences when modifying your code to switch from one to the other. There are other differences in the character of the noise values generated by both methods, so you'll need to do some experimentation to get the results you want. - The nature of the noise values returned can be adjusted with - ``os_noise_seed()``. + The nature of the noise values returned can be adjusted with `os_noise_seed()`. Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the method works within an infinite space, the value @@ -2114,11 +2149,11 @@ def os_noise(self, best for most applications, but this will differ depending on the use case and the noise settings. - Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will + Py5's `os_noise()` method can also accept numpy arrays as parameters. It will use broadcasting when needed and calculate the values efficiently. Using numpy - array parameters will be much faster and efficient than calling the - ``os_noise()`` method repeatedly in a loop. See the examples to see how this can - be done. The noise algorithm for this method is implemented in Java. + array parameters will be much faster and efficient than calling the `os_noise()` + method repeatedly in a loop. See the examples to see how this can be done. The + noise algorithm for this method is implemented in Java. Noise generation is a rich and complex topic, and there are many noise algorithms and libraries available that are worth learning about. Early versions @@ -2168,28 +2203,27 @@ def os_noise(self, *args) -> Union[float, npt.NDArray]: Generate pseudo-random noise values for specific coodinates using the OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are random sequence generators that produce a more natural, harmonic succession of - numbers compared to the ``random()`` method. + numbers compared to the `random()` method. - In contrast to the ``random()`` method, noise is defined in an n-dimensional + In contrast to the `random()` method, noise is defined in an n-dimensional space, in which each coordinate corresponds to a fixed pseudo-random value (fixed only for the lifespan of the program). The noise value can be animated by moving through the noise space, as demonstrated in the examples. Any dimension can also be interpreted as time. An easy way to animate the noise value is to - pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, - as is done in a few of the examples. + pass the `os_noise()` method the `frame_count` divided by a scaling factor, as + is done in a few of the examples. The generated noise values for this method will be between -1 and 1, and can be generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a constant value as an extra parameter, as shown in a few examples. Py5 also - provides the ``noise()`` method, which generates noise using Processing's noise + provides the `noise()` method, which generates noise using Processing's noise algorithm. That algorithm typically generates noise values between 0 and 1, and can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences when modifying your code to switch from one to the other. There are other differences in the character of the noise values generated by both methods, so you'll need to do some experimentation to get the results you want. - The nature of the noise values returned can be adjusted with - ``os_noise_seed()``. + The nature of the noise values returned can be adjusted with `os_noise_seed()`. Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the method works within an infinite space, the value @@ -2199,11 +2233,11 @@ def os_noise(self, *args) -> Union[float, npt.NDArray]: best for most applications, but this will differ depending on the use case and the noise settings. - Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will + Py5's `os_noise()` method can also accept numpy arrays as parameters. It will use broadcasting when needed and calculate the values efficiently. Using numpy - array parameters will be much faster and efficient than calling the - ``os_noise()`` method repeatedly in a loop. See the examples to see how this can - be done. The noise algorithm for this method is implemented in Java. + array parameters will be much faster and efficient than calling the `os_noise()` + method repeatedly in a loop. See the examples to see how this can be done. The + noise algorithm for this method is implemented in Java. Noise generation is a rich and complex topic, and there are many noise algorithms and libraries available that are worth learning about. Early versions diff --git a/py5/mixins/pixels.py b/py5/mixins/pixels.py index a97c08a..8a2ed60 100644 --- a/py5/mixins/pixels.py +++ b/py5/mixins/pixels.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -36,7 +36,7 @@ class PixelArray: - """The ``pixels[]`` array contains the values for all the pixels in the display + """The `pixels[]` array contains the values for all the pixels in the display window. Underlying Processing field: PApplet.pixels @@ -44,19 +44,19 @@ class PixelArray: Notes ----- - The ``pixels[]`` array contains the values for all the pixels in the display + The `pixels[]` array contains the values for all the pixels in the display window. These values are of the color datatype. This array is defined by the size of the display window. For example, if the window is 100 x 100 pixels, there will be 10,000 values and if the window is 200 x 300 pixels, there will be 60,000 values. When the pixel density is set to higher than 1 with the - ``pixel_density()`` function, these values will change. See the reference for - ``pixel_width`` or ``pixel_height`` for more information. - - Before accessing this array, the data must loaded with the ``load_pixels()`` - function. Failure to do so may result in a Java ``NullPointerException``. - Subsequent changes to the display window will not be reflected in ``pixels`` - until ``load_pixels()`` is called again. After ``pixels`` has been modified, the - ``update_pixels()`` function must be run to update the content of the display + `pixel_density()` function, these values will change. See the reference for + `pixel_width` or `pixel_height` for more information. + + Before accessing this array, the data must loaded with the `load_pixels()` + function. Failure to do so may result in a Java `NullPointerException`. + Subsequent changes to the display window will not be reflected in `pixels` until + `load_pixels()` is called again. After `pixels` has been modified, the + `update_pixels()` function must be run to update the content of the display window.""" def __init__(self, instance): @@ -113,127 +113,124 @@ def _init_np_pixels(self): # *** BEGIN METHODS *** def load_np_pixels(self) -> None: - """Loads the pixel data of the current display window into the ``np_pixels[]`` - array. + """Loads the pixel data of the current display window into the `np_pixels[]` array. Notes ----- - Loads the pixel data of the current display window into the ``np_pixels[]`` - array. This method must always be called before reading from or writing to - ``np_pixels[]``. Subsequent changes to the display window will not be reflected - in ``np_pixels[]`` until ``load_np_pixels()`` is called again. - - The ``load_np_pixels()`` method is similar to ``load_pixels()`` in that - ``load_np_pixels()`` must be called before reading from or writing to - ``np_pixels[]`` just as ``load_pixels()`` must be called before reading from or - writing to ``pixels[]``. - - Note that ``load_np_pixels()`` will as a side effect call ``load_pixels()``, so - if your code needs to read ``np_pixels[]`` and ``pixels[]`` simultaneously, - there is no need for a separate call to ``load_pixels()``. However, be aware - that modifying both ``np_pixels[]`` and ``pixels[]`` simultaneously will likely - result in the updates to ``pixels[]`` being discarded.""" + Loads the pixel data of the current display window into the `np_pixels[]` array. + This method must always be called before reading from or writing to + `np_pixels[]`. Subsequent changes to the display window will not be reflected in + `np_pixels[]` until `load_np_pixels()` is called again. + + The `load_np_pixels()` method is similar to `load_pixels()` in that + `load_np_pixels()` must be called before reading from or writing to + `np_pixels[]` just as `load_pixels()` must be called before reading from or + writing to `pixels[]`. + + Note that `load_np_pixels()` will as a side effect call `load_pixels()`, so if + your code needs to read `np_pixels[]` and `pixels[]` simultaneously, there is no + need for a separate call to `load_pixels()`. However, be aware that modifying + both `np_pixels[]` and `pixels[]` simultaneously will likely result in the + updates to `pixels[]` being discarded.""" if self._np_pixels is None: self._init_np_pixels() self._instance.loadPixels() self._java_bb.asIntBuffer().put(self._instance.pixels) def update_np_pixels(self) -> None: - """Updates the display window with the data in the ``np_pixels[]`` array. + """Updates the display window with the data in the `np_pixels[]` array. Notes ----- - Updates the display window with the data in the ``np_pixels[]`` array. Use in - conjunction with ``load_np_pixels()``. If you're only reading pixels from the - array, there's no need to call ``update_np_pixels()`` — updating is only - necessary to apply changes. + Updates the display window with the data in the `np_pixels[]` array. Use in + conjunction with `load_np_pixels()`. If you're only reading pixels from the + array, there's no need to call `update_np_pixels()` — updating is only necessary + to apply changes. - The ``update_np_pixels()`` method is similar to ``update_pixels()`` in that - ``update_np_pixels()`` must be called after modifying ``np_pixels[]`` just as - ``update_pixels()`` must be called after modifying ``pixels[]``.""" + The `update_np_pixels()` method is similar to `update_pixels()` in that + `update_np_pixels()` must be called after modifying `np_pixels[]` just as + `update_pixels()` must be called after modifying `pixels[]`.""" if self._np_pixels is None: self._init_np_pixels() self._java_bb.asIntBuffer().get(self._instance.pixels) self._instance.updatePixels() def _get_np_pixels(self) -> npt.NDArray[np.uint8]: - """The ``np_pixels[]`` array contains the values for all the pixels in the display + """The `np_pixels[]` array contains the values for all the pixels in the display window. Notes ----- - The ``np_pixels[]`` array contains the values for all the pixels in the display - window. Unlike the one dimensional array ``pixels[]``, the ``np_pixels[]`` array + The `np_pixels[]` array contains the values for all the pixels in the display + window. Unlike the one dimensional array `pixels[]`, the `np_pixels[]` array organizes the color data in a 3 dimensional numpy array. The size of the array's dimensions are defined by the size of the display window. The first dimension is the height, the second is the width, and the third represents the color channels. The color channels are ordered alpha, red, green, blue (ARGB). Every - value in ``np_pixels[]`` is an integer between 0 and 255. + value in `np_pixels[]` is an integer between 0 and 255. This numpy array is very similar to the image arrays used by other popular Python image libraries, but note that many of them will arrange the channels in a different order such as RGBA or BGR. - When the pixel density is set to higher than 1 with the ``pixel_density()`` - function, the size of ``np_pixels[]``'s height and width dimensions will change. - See the reference for ``pixel_width`` or ``pixel_height`` for more information. - Nothing about ``np_pixels[]`` will change as a result of calls to - ``color_mode()``. - - Much like the ``pixels[]`` array, there are load and update methods that must be - called before and after making changes to the data in ``np_pixels[]``. Before - accessing ``np_pixels[]``, the data must be loaded with the ``load_np_pixels()`` - method. If this is not done, ``np_pixels`` will be equal to ``None`` and your - code will likely result in Python exceptions. After ``np_pixels[]`` has been - modified, the ``update_np_pixels()`` method must be called to update the content - of the display window. - - To set the entire contents of ``np_pixels[]`` to the contents of another - properly sized numpy array, consider using ``set_np_pixels()``.""" + When the pixel density is set to higher than 1 with the `pixel_density()` + function, the size of `np_pixels[]`'s height and width dimensions will change. + See the reference for `pixel_width` or `pixel_height` for more information. + Nothing about `np_pixels[]` will change as a result of calls to `color_mode()`. + + Much like the `pixels[]` array, there are load and update methods that must be + called before and after making changes to the data in `np_pixels[]`. Before + accessing `np_pixels[]`, the data must be loaded with the `load_np_pixels()` + method. If this is not done, `np_pixels` will be equal to `None` and your code + will likely result in Python exceptions. After `np_pixels[]` has been modified, + the `update_np_pixels()` method must be called to update the content of the + display window. + + To set the entire contents of `np_pixels[]` to the contents of another properly + sized numpy array, consider using `set_np_pixels()`.""" return self._np_pixels np_pixels: npt.NDArray[np.uint8] = property( - fget=_get_np_pixels, doc="""The ``np_pixels[]`` array contains the values for all the pixels in the display + fget=_get_np_pixels, doc="""The `np_pixels[]` array contains the values for all the pixels in the display window. Notes ----- - The ``np_pixels[]`` array contains the values for all the pixels in the display - window. Unlike the one dimensional array ``pixels[]``, the ``np_pixels[]`` array + The `np_pixels[]` array contains the values for all the pixels in the display + window. Unlike the one dimensional array `pixels[]`, the `np_pixels[]` array organizes the color data in a 3 dimensional numpy array. The size of the array's dimensions are defined by the size of the display window. The first dimension is the height, the second is the width, and the third represents the color channels. The color channels are ordered alpha, red, green, blue (ARGB). Every - value in ``np_pixels[]`` is an integer between 0 and 255. + value in `np_pixels[]` is an integer between 0 and 255. This numpy array is very similar to the image arrays used by other popular Python image libraries, but note that many of them will arrange the channels in a different order such as RGBA or BGR. - When the pixel density is set to higher than 1 with the ``pixel_density()`` - function, the size of ``np_pixels[]``'s height and width dimensions will change. - See the reference for ``pixel_width`` or ``pixel_height`` for more information. - Nothing about ``np_pixels[]`` will change as a result of calls to - ``color_mode()``. + When the pixel density is set to higher than 1 with the `pixel_density()` + function, the size of `np_pixels[]`'s height and width dimensions will change. + See the reference for `pixel_width` or `pixel_height` for more information. + Nothing about `np_pixels[]` will change as a result of calls to `color_mode()`. - Much like the ``pixels[]`` array, there are load and update methods that must be - called before and after making changes to the data in ``np_pixels[]``. Before - accessing ``np_pixels[]``, the data must be loaded with the ``load_np_pixels()`` - method. If this is not done, ``np_pixels`` will be equal to ``None`` and your - code will likely result in Python exceptions. After ``np_pixels[]`` has been - modified, the ``update_np_pixels()`` method must be called to update the content - of the display window. + Much like the `pixels[]` array, there are load and update methods that must be + called before and after making changes to the data in `np_pixels[]`. Before + accessing `np_pixels[]`, the data must be loaded with the `load_np_pixels()` + method. If this is not done, `np_pixels` will be equal to `None` and your code + will likely result in Python exceptions. After `np_pixels[]` has been modified, + the `update_np_pixels()` method must be called to update the content of the + display window. - To set the entire contents of ``np_pixels[]`` to the contents of another - properly sized numpy array, consider using ``set_np_pixels()``.""") + To set the entire contents of `np_pixels[]` to the contents of another properly + sized numpy array, consider using `set_np_pixels()`.""") def set_np_pixels(self, array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None: - """Set the entire contents of ``np_pixels[]`` to the contents of another properly + """Set the entire contents of `np_pixels[]` to the contents of another properly sized and typed numpy array. Parameters @@ -248,38 +245,47 @@ def set_np_pixels(self, Notes ----- - Set the entire contents of ``np_pixels[]`` to the contents of another properly - sized and typed numpy array. The size of ``array``'s first and second dimensions + Set the entire contents of `np_pixels[]` to the contents of another properly + sized and typed numpy array. The size of `array`'s first and second dimensions must match the height and width of the Sketch window, respectively. The array's - ``dtype`` must be ``np.uint8``. + `dtype` must be `np.uint8`. - The ``bands`` parameter is used to interpret the ``array``'s color channel - dimension (the array's third dimension). It can be one of ``'L'`` (single- - channel grayscale), ``'ARGB'``, ``'RGB'``, or ``'RGBA'``. If there is no alpha - channel, ``array`` is assumed to have no transparency, but recall that the - display window's pixels can never be transparent so any transparency in - ``array`` will have no effect. If the ``bands`` parameter is ``'L'``, - ``array``'s third dimension is optional. + The `bands` parameter is used to interpret the `array`'s color channel dimension + (the array's third dimension). It can be one of `'L'` (single-channel + grayscale), `'ARGB'`, `'RGB'`, or `'RGBA'`. If there is no alpha channel, + `array` is assumed to have no transparency, but recall that the display window's + pixels can never be transparent so any transparency in `array` will have no + effect. If the `bands` parameter is `'L'`, `array`'s third dimension is + optional. - This method makes its own calls to ``load_np_pixels()`` and - ``update_np_pixels()`` so there is no need to call either explicitly. + This method makes its own calls to `load_np_pixels()` and `update_np_pixels()` + so there is no need to call either explicitly. This method exists because setting the array contents with the code - ``py5.np_pixels = array`` will cause an error, while the correct syntax, - ``py5.np_pixels[:] = array``, might also be unintuitive for beginners.""" + `py5.np_pixels = array` will cause an error, while the correct syntax, + `py5.np_pixels[:] = array`, might also be unintuitive for beginners.""" self.load_np_pixels() if bands == 'L': self._np_pixels[:, :, 0] = 255 self._np_pixels[:, :, 1:] = array[:, :, None] if array.ndim == 2 else array elif bands == 'ARGB': - self._np_pixels[:] = array + self._np_pixels[:] = array[:, :, :4] elif bands == 'RGB': self._np_pixels[:, :, 0] = 255 - self._np_pixels[:, :, 1:] = array + self._np_pixels[:, :, 1:] = array[:, :, :3] elif bands == 'RGBA': self._np_pixels[:, :, 0] = array[:, :, 3] self._np_pixels[:, :, 1:] = array[:, :, :3] + elif bands == 'BGR': + self._np_pixels[:, :, 0] = 255 + self._np_pixels[:, :, 1:] = array[:, :, 2::-1] + elif bands == 'BGRA': + self._np_pixels[:, :, 0] = array[:, :, 3] + self._np_pixels[:, :, 1:] = array[:, :, 2::-1] + else: + raise RuntimeError( + f"Unknown `bands` value '{bands}'. Supported values are 'L', 'ARGB', 'RGB', 'RGBA', 'BGR', and 'BGRA'.") self.update_np_pixels() def save(self, @@ -318,14 +324,14 @@ def save(self, Pillow to write the image, so it can save images in any format that that library supports. - Use the ``drop_alpha`` parameter to drop the alpha channel from the image. This - defaults to ``True``. Some image formats such as JPG do not support alpha + Use the `drop_alpha` parameter to drop the alpha channel from the image. This + defaults to `True`. Some image formats such as JPG do not support alpha channels, and Pillow will throw an error if you try to save an image with the alpha channel in that format. - The ``use_thread`` parameter will save the image in a separate Python thread. - This improves performance by returning before the image has actually been - written to the file.""" + The `use_thread` parameter will save the image in a separate Python thread. This + improves performance by returning before the image has actually been written to + the file.""" sketch_instance = self._instance if isinstance( self._instance, _Sketch) else self._instance.parent if not isinstance(filename, BytesIO): @@ -360,151 +366,147 @@ class PixelPy5GraphicsMixin(PixelMixin): def load_np_pixels(self) -> None: """Loads the pixel data of the current Py5Graphics drawing surface into the - ``Py5Graphics.np_pixels[]`` array. + `Py5Graphics.np_pixels[]` array. Notes ----- Loads the pixel data of the current Py5Graphics drawing surface into the - ``Py5Graphics.np_pixels[]`` array. This method must always be called before - reading from or writing to ``Py5Graphics.np_pixels[]``. It should only be used - between calls to ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. + `Py5Graphics.np_pixels[]` array. This method must always be called before + reading from or writing to `Py5Graphics.np_pixels[]`. It should only be used + between calls to `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. Subsequent changes to the Py5Graphics drawing surface will not be reflected in - ``Py5Graphics.np_pixels[]`` until ``load_np_pixels()`` is called again. - - The ``load_np_pixels()`` method is similar to ``Py5Graphics.load_pixels()`` in - that ``load_np_pixels()`` must be called before reading from or writing to - ``Py5Graphics.np_pixels[]`` just as ``Py5Graphics.load_pixels()`` must be called - before reading from or writing to ``Py5Graphics.pixels[]``. - - Note that ``load_np_pixels()`` will as a side effect call - ``Py5Graphics.load_pixels()``, so if your code needs to read - ``Py5Graphics.np_pixels[]`` and ``Py5Graphics.pixels[]`` simultaneously, there - is no need for a separate call to ``Py5Graphics.load_pixels()``. However, be - aware that modifying both ``Py5Graphics.np_pixels[]`` and - ``Py5Graphics.pixels[]`` simultaneously will likely result in the updates to - ``Py5Graphics.pixels[]`` being discarded. - - This method is the same as ``load_np_pixels()`` but linked to a ``Py5Graphics`` + `Py5Graphics.np_pixels[]` until `load_np_pixels()` is called again. + + The `load_np_pixels()` method is similar to `Py5Graphics.load_pixels()` in that + `load_np_pixels()` must be called before reading from or writing to + `Py5Graphics.np_pixels[]` just as `Py5Graphics.load_pixels()` must be called + before reading from or writing to `Py5Graphics.pixels[]`. + + Note that `load_np_pixels()` will as a side effect call + `Py5Graphics.load_pixels()`, so if your code needs to read + `Py5Graphics.np_pixels[]` and `Py5Graphics.pixels[]` simultaneously, there is no + need for a separate call to `Py5Graphics.load_pixels()`. However, be aware that + modifying both `Py5Graphics.np_pixels[]` and `Py5Graphics.pixels[]` + simultaneously will likely result in the updates to `Py5Graphics.pixels[]` being + discarded. + + This method is the same as `load_np_pixels()` but linked to a `Py5Graphics` object.""" return super().load_np_pixels() def update_np_pixels(self) -> None: """Updates the Py5Graphics drawing surface with the data in the - ``Py5Graphics.np_pixels[]`` array. + `Py5Graphics.np_pixels[]` array. Notes ----- Updates the Py5Graphics drawing surface with the data in the - ``Py5Graphics.np_pixels[]`` array. Use in conjunction with - ``Py5Graphics.load_np_pixels()``. If you're only reading pixels from the array, - there's no need to call ``update_np_pixels()`` — updating is only necessary to - apply changes. Working with ``Py5Graphics.np_pixels[]`` can only be done between - calls to ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. - - The ``update_np_pixels()`` method is similar to ``Py5Graphics.update_pixels()`` - in that ``update_np_pixels()`` must be called after modifying - ``Py5Graphics.np_pixels[]`` just as ``Py5Graphics.update_pixels()`` must be - called after modifying ``Py5Graphics.pixels[]``. - - This method is the same as ``update_np_pixels()`` but linked to a - ``Py5Graphics`` object.""" + `Py5Graphics.np_pixels[]` array. Use in conjunction with + `Py5Graphics.load_np_pixels()`. If you're only reading pixels from the array, + there's no need to call `update_np_pixels()` — updating is only necessary to + apply changes. Working with `Py5Graphics.np_pixels[]` can only be done between + calls to `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. + + The `update_np_pixels()` method is similar to `Py5Graphics.update_pixels()` in + that `update_np_pixels()` must be called after modifying + `Py5Graphics.np_pixels[]` just as `Py5Graphics.update_pixels()` must be called + after modifying `Py5Graphics.pixels[]`. + + This method is the same as `update_np_pixels()` but linked to a `Py5Graphics` + object.""" return super().update_np_pixels() def _get_np_pixels(self) -> npt.NDArray[np.uint8]: - """The ``np_pixels[]`` array contains the values for all the pixels in the + """The `np_pixels[]` array contains the values for all the pixels in the Py5Graphics drawing surface. Notes ----- - The ``np_pixels[]`` array contains the values for all the pixels in the + The `np_pixels[]` array contains the values for all the pixels in the Py5Graphics drawing surface. Unlike the one dimensional array - ``Py5Graphics.pixels[]``, the ``np_pixels[]`` array organizes the color data in - a 3 dimensional numpy array. The size of the array's dimensions are defined by - the size of the Py5Graphics drawing surface. The first dimension is the height, - the second is the width, and the third represents the color channels. The color + `Py5Graphics.pixels[]`, the `np_pixels[]` array organizes the color data in a 3 + dimensional numpy array. The size of the array's dimensions are defined by the + size of the Py5Graphics drawing surface. The first dimension is the height, the + second is the width, and the third represents the color channels. The color channels are ordered alpha, red, green, blue (ARGB). Every value in - ``np_pixels[]`` is an integer between 0 and 255. + `np_pixels[]` is an integer between 0 and 255. This numpy array is very similar to the image arrays used by other popular Python image libraries, but note that some of them like opencv will by default order the color channels as RGBA. When the pixel density is set to higher than 1 with the - ``Py5Graphics.pixel_density`` function, the size of ``np_pixels[]``'s height and - width dimensions will change. See the reference for ``Py5Graphics.pixel_width`` - or ``Py5Graphics.pixel_height`` for more information. Nothing about - ``np_pixels[]`` will change as a result of calls to - ``Py5Graphics.color_mode()``. + `Py5Graphics.pixel_density` function, the size of `np_pixels[]`'s height and + width dimensions will change. See the reference for `Py5Graphics.pixel_width` or + `Py5Graphics.pixel_height` for more information. Nothing about `np_pixels[]` + will change as a result of calls to `Py5Graphics.color_mode()`. - Much like the ``Py5Graphics.pixels[]`` array, there are load and update methods + Much like the `Py5Graphics.pixels[]` array, there are load and update methods that must be called before and after making changes to the data in - ``np_pixels[]``. Before accessing ``np_pixels[]``, the data must be loaded with - the ``Py5Graphics.load_np_pixels()`` method. If this is not done, ``np_pixels`` - will be equal to ``None`` and your code will likely result in Python exceptions. - After ``np_pixels[]`` has been modified, the ``Py5Graphics.update_np_pixels()`` - method must be called to update the content of the Py5Graphics drawing surface. + `np_pixels[]`. Before accessing `np_pixels[]`, the data must be loaded with the + `Py5Graphics.load_np_pixels()` method. If this is not done, `np_pixels` will be + equal to `None` and your code will likely result in Python exceptions. After + `np_pixels[]` has been modified, the `Py5Graphics.update_np_pixels()` method + must be called to update the content of the Py5Graphics drawing surface. - Working with ``Py5Graphics.np_pixels[]`` can only be done between calls to - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. + Working with `Py5Graphics.np_pixels[]` can only be done between calls to + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. - To set the entire contents of ``np_pixels[]`` to the contents of another - properly sized numpy array, consider using ``Py5Graphics.set_np_pixels()``. + To set the entire contents of `np_pixels[]` to the contents of another properly + sized numpy array, consider using `Py5Graphics.set_np_pixels()`. - This field is the same as ``np_pixels[]`` but linked to a ``Py5Graphics`` - object.""" + This field is the same as `np_pixels[]` but linked to a `Py5Graphics` object.""" return super()._get_np_pixels() np_pixels: npt.NDArray[np.uint8] = property( - fget=_get_np_pixels, doc="""The ``np_pixels[]`` array contains the values for all the pixels in the + fget=_get_np_pixels, doc="""The `np_pixels[]` array contains the values for all the pixels in the Py5Graphics drawing surface. Notes ----- - The ``np_pixels[]`` array contains the values for all the pixels in the + The `np_pixels[]` array contains the values for all the pixels in the Py5Graphics drawing surface. Unlike the one dimensional array - ``Py5Graphics.pixels[]``, the ``np_pixels[]`` array organizes the color data in - a 3 dimensional numpy array. The size of the array's dimensions are defined by - the size of the Py5Graphics drawing surface. The first dimension is the height, - the second is the width, and the third represents the color channels. The color + `Py5Graphics.pixels[]`, the `np_pixels[]` array organizes the color data in a 3 + dimensional numpy array. The size of the array's dimensions are defined by the + size of the Py5Graphics drawing surface. The first dimension is the height, the + second is the width, and the third represents the color channels. The color channels are ordered alpha, red, green, blue (ARGB). Every value in - ``np_pixels[]`` is an integer between 0 and 255. + `np_pixels[]` is an integer between 0 and 255. This numpy array is very similar to the image arrays used by other popular Python image libraries, but note that some of them like opencv will by default order the color channels as RGBA. When the pixel density is set to higher than 1 with the - ``Py5Graphics.pixel_density`` function, the size of ``np_pixels[]``'s height and - width dimensions will change. See the reference for ``Py5Graphics.pixel_width`` - or ``Py5Graphics.pixel_height`` for more information. Nothing about - ``np_pixels[]`` will change as a result of calls to - ``Py5Graphics.color_mode()``. + `Py5Graphics.pixel_density` function, the size of `np_pixels[]`'s height and + width dimensions will change. See the reference for `Py5Graphics.pixel_width` or + `Py5Graphics.pixel_height` for more information. Nothing about `np_pixels[]` + will change as a result of calls to `Py5Graphics.color_mode()`. - Much like the ``Py5Graphics.pixels[]`` array, there are load and update methods + Much like the `Py5Graphics.pixels[]` array, there are load and update methods that must be called before and after making changes to the data in - ``np_pixels[]``. Before accessing ``np_pixels[]``, the data must be loaded with - the ``Py5Graphics.load_np_pixels()`` method. If this is not done, ``np_pixels`` - will be equal to ``None`` and your code will likely result in Python exceptions. - After ``np_pixels[]`` has been modified, the ``Py5Graphics.update_np_pixels()`` - method must be called to update the content of the Py5Graphics drawing surface. + `np_pixels[]`. Before accessing `np_pixels[]`, the data must be loaded with the + `Py5Graphics.load_np_pixels()` method. If this is not done, `np_pixels` will be + equal to `None` and your code will likely result in Python exceptions. After + `np_pixels[]` has been modified, the `Py5Graphics.update_np_pixels()` method + must be called to update the content of the Py5Graphics drawing surface. - Working with ``Py5Graphics.np_pixels[]`` can only be done between calls to - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. + Working with `Py5Graphics.np_pixels[]` can only be done between calls to + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. - To set the entire contents of ``np_pixels[]`` to the contents of another - properly sized numpy array, consider using ``Py5Graphics.set_np_pixels()``. + To set the entire contents of `np_pixels[]` to the contents of another properly + sized numpy array, consider using `Py5Graphics.set_np_pixels()`. - This field is the same as ``np_pixels[]`` but linked to a ``Py5Graphics`` - object.""") + This field is the same as `np_pixels[]` but linked to a `Py5Graphics` object.""") def set_np_pixels(self, array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None: - """Set the entire contents of ``Py5Graphics.np_pixels[]`` to the contents of - another properly sized and typed numpy array. + """Set the entire contents of `Py5Graphics.np_pixels[]` to the contents of another + properly sized and typed numpy array. Parameters ---------- @@ -518,30 +520,28 @@ def set_np_pixels(self, Notes ----- - Set the entire contents of ``Py5Graphics.np_pixels[]`` to the contents of - another properly sized and typed numpy array. The size of ``array``'s first and - second dimensions must match the height and width of the Py5Graphics drawing - surface, respectively. The array's ``dtype`` must be ``np.uint8``. This must be - used after ``Py5Graphics.begin_draw()`` but can be used after - ``Py5Graphics.end_draw()``. - - The ``bands`` parameter is used to interpret the ``array``'s color channel - dimension (the array's third dimension). It can be one of ``'L'`` (single- - channel grayscale), ``'ARGB'``, ``'RGB'``, or ``'RGBA'``. If there is no alpha - channel, ``array`` is assumed to have no transparency. Unlike the main drawing - window, a Py5Graphics drawing surface's pixels can be transparent so using the - alpha channel will work properly. If the ``bands`` parameter is ``'L'``, - ``array``'s third dimension is optional. - - This method makes its own calls to ``Py5Graphics.load_np_pixels()`` and - ``Py5Graphics.update_np_pixels()`` so there is no need to call either - explicitly. + Set the entire contents of `Py5Graphics.np_pixels[]` to the contents of another + properly sized and typed numpy array. The size of `array`'s first and second + dimensions must match the height and width of the Py5Graphics drawing surface, + respectively. The array's `dtype` must be `np.uint8`. This must be used after + `Py5Graphics.begin_draw()` but can be used after `Py5Graphics.end_draw()`. - This method exists because setting the array contents with the code - ``g.np_pixels = array`` will cause an error, while the correct syntax, - ``g.np_pixels[:] = array``, might also be unintuitive for beginners. + The `bands` parameter is used to interpret the `array`'s color channel dimension + (the array's third dimension). It can be one of `'L'` (single-channel + grayscale), `'ARGB'`, `'RGB'`, or `'RGBA'`. If there is no alpha channel, + `array` is assumed to have no transparency. Unlike the main drawing window, a + Py5Graphics drawing surface's pixels can be transparent so using the alpha + channel will work properly. If the `bands` parameter is `'L'`, `array`'s third + dimension is optional. + + This method makes its own calls to `Py5Graphics.load_np_pixels()` and + `Py5Graphics.update_np_pixels()` so there is no need to call either explicitly. - This method is the same as ``set_np_pixels()`` but linked to a ``Py5Graphics`` + This method exists because setting the array contents with the code `g.np_pixels + = array` will cause an error, while the correct syntax, `g.np_pixels[:] = + array`, might also be unintuitive for beginners. + + This method is the same as `set_np_pixels()` but linked to a `Py5Graphics` object.""" return super().set_np_pixels(array, bands) @@ -581,17 +581,17 @@ def save(self, Python library Pillow to write the image, so it can save images in any format that that library supports. - Use the ``drop_alpha`` parameter to drop the alpha channel from the image. This - defaults to ``True``. Some image formats such as JPG do not support alpha + Use the `drop_alpha` parameter to drop the alpha channel from the image. This + defaults to `True`. Some image formats such as JPG do not support alpha channels, and Pillow will throw an error if you try to save an image with the alpha channel in that format. - The ``use_thread`` parameter will save the image in a separate Python thread. - This improves performance by returning before the image has actually been - written to the file. + The `use_thread` parameter will save the image in a separate Python thread. This + improves performance by returning before the image has actually been written to + the file. - This method is the same as ``save()`` but linked to a ``Py5Graphics`` object. To - see example code for how it can be used, see ``save()``.""" + This method is the same as `save()` but linked to a `Py5Graphics` object. To see + example code for how it can be used, see `save()`.""" return super().save( filename, format=format, @@ -603,108 +603,108 @@ def save(self, class PixelPy5ImageMixin(PixelMixin): def load_np_pixels(self) -> None: - """Loads the pixel data of the image into the ``Py5Image.np_pixels[]`` array. + """Loads the pixel data of the image into the `Py5Image.np_pixels[]` array. Notes ----- - Loads the pixel data of the image into the ``Py5Image.np_pixels[]`` array. This + Loads the pixel data of the image into the `Py5Image.np_pixels[]` array. This method must always be called before reading from or writing to - ``Py5Image.np_pixels[]``. Subsequent changes to the image will not be reflected - in ``Py5Image.np_pixels[]`` until ``py5image_load_np_pixels()`` is called again. - - The ``load_np_pixels()`` method is similar to ``Py5Image.load_pixels()`` in that - ``load_np_pixels()`` must be called before reading from or writing to - ``Py5Image.np_pixels[]`` just as ``Py5Image.load_pixels()`` must be called - before reading from or writing to ``Py5Image.pixels[]``. - - Note that ``load_np_pixels()`` will as a side effect call - ``Py5Image.load_pixels()``, so if your code needs to read - ``Py5Image.np_pixels[]`` and ``Py5Image.pixels[]`` simultaneously, there is no - need for a separate call to ``Py5Image.load_pixels()``. However, be aware that - modifying both ``Py5Image.np_pixels[]`` and ``Py5Image.pixels[]`` simultaneously - will likely result in the updates to ``Py5Image.pixels[]`` being discarded.""" + `Py5Image.np_pixels[]`. Subsequent changes to the image will not be reflected in + `Py5Image.np_pixels[]` until `py5image_load_np_pixels()` is called again. + + The `load_np_pixels()` method is similar to `Py5Image.load_pixels()` in that + `load_np_pixels()` must be called before reading from or writing to + `Py5Image.np_pixels[]` just as `Py5Image.load_pixels()` must be called before + reading from or writing to `Py5Image.pixels[]`. + + Note that `load_np_pixels()` will as a side effect call + `Py5Image.load_pixels()`, so if your code needs to read `Py5Image.np_pixels[]` + and `Py5Image.pixels[]` simultaneously, there is no need for a separate call to + `Py5Image.load_pixels()`. However, be aware that modifying both + `Py5Image.np_pixels[]` and `Py5Image.pixels[]` simultaneously will likely result + in the updates to `Py5Image.pixels[]` being discarded.""" return super().load_np_pixels() def update_np_pixels(self) -> None: - """Updates the image with the data in the ``Py5Image.np_pixels[]`` array. + """Updates the image with the data in the `Py5Image.np_pixels[]` array. Notes ----- - Updates the image with the data in the ``Py5Image.np_pixels[]`` array. Use in - conjunction with ``Py5Image.load_np_pixels()``. If you're only reading pixels - from the array, there's no need to call ``update_np_pixels()`` — updating is - only necessary to apply changes. + Updates the image with the data in the `Py5Image.np_pixels[]` array. Use in + conjunction with `Py5Image.load_np_pixels()`. If you're only reading pixels from + the array, there's no need to call `update_np_pixels()` — updating is only + necessary to apply changes. - The ``update_np_pixels()`` method is similar to ``Py5Image.update_pixels()`` in - that ``update_np_pixels()`` must be called after modifying - ``Py5Image.np_pixels[]`` just as ``Py5Image.update_pixels()`` must be called - after modifying ``Py5Image.pixels[]``.""" + The `update_np_pixels()` method is similar to `Py5Image.update_pixels()` in that + `update_np_pixels()` must be called after modifying `Py5Image.np_pixels[]` just + as `Py5Image.update_pixels()` must be called after modifying + `Py5Image.pixels[]`.""" return super().update_np_pixels() def _get_np_pixels(self) -> npt.NDArray[np.uint8]: - """The ``np_pixels[]`` array contains the values for all the pixels in the image. + """The `np_pixels[]` array contains the values for all the pixels in the image. Notes ----- - The ``np_pixels[]`` array contains the values for all the pixels in the image. - Unlike the one dimensional array ``Py5Image.pixels[]``, the ``np_pixels[]`` - array organizes the color data in a 3 dimensional numpy array. The size of the - array's dimensions are defined by the size of the image. The first dimension is - the height, the second is the width, and the third represents the color - channels. The color channels are ordered alpha, red, green, blue (ARGB). Every - value in ``np_pixels[]`` is an integer between 0 and 255. + The `np_pixels[]` array contains the values for all the pixels in the image. + Unlike the one dimensional array `Py5Image.pixels[]`, the `np_pixels[]` array + organizes the color data in a 3 dimensional numpy array. The size of the array's + dimensions are defined by the size of the image. The first dimension is the + height, the second is the width, and the third represents the color channels. + The color channels are ordered alpha, red, green, blue (ARGB). Every value in + `np_pixels[]` is an integer between 0 and 255. This numpy array is very similar to the image arrays used by other popular Python image libraries, but note that some of them like opencv will by default order the color channels as RGBA. - Much like the ``Py5Image.pixels[]`` array, there are load and update methods - that must be called before and after making changes to the data in - ``np_pixels[]``. Before accessing ``np_pixels[]``, the data must be loaded with - the ``Py5Image.load_np_pixels()`` method. If this is not done, ``np_pixels`` - will be equal to ``None`` and your code will likely result in Python exceptions. - After ``np_pixels[]`` has been modified, the ``Py5Image.update_np_pixels()`` - method must be called to update the content of the display window. - - To set the entire contents of ``np_pixels[]`` to the contents of another equally - sized numpy array, consider using ``Py5Image.set_np_pixels()``.""" + Much like the `Py5Image.pixels[]` array, there are load and update methods that + must be called before and after making changes to the data in `np_pixels[]`. + Before accessing `np_pixels[]`, the data must be loaded with the + `Py5Image.load_np_pixels()` method. If this is not done, `np_pixels` will be + equal to `None` and your code will likely result in Python exceptions. After + `np_pixels[]` has been modified, the `Py5Image.update_np_pixels()` method must + be called to update the content of the display window. + + To set the entire contents of `np_pixels[]` to the contents of another equally + sized numpy array, consider using `Py5Image.set_np_pixels()`.""" return super()._get_np_pixels() np_pixels: npt.NDArray[np.uint8] = property( - fget=_get_np_pixels, doc="""The ``np_pixels[]`` array contains the values for all the pixels in the image. + fget=_get_np_pixels, doc="""The `np_pixels[]` array contains the values for all the pixels in the image. Notes ----- - The ``np_pixels[]`` array contains the values for all the pixels in the image. - Unlike the one dimensional array ``Py5Image.pixels[]``, the ``np_pixels[]`` - array organizes the color data in a 3 dimensional numpy array. The size of the - array's dimensions are defined by the size of the image. The first dimension is - the height, the second is the width, and the third represents the color - channels. The color channels are ordered alpha, red, green, blue (ARGB). Every - value in ``np_pixels[]`` is an integer between 0 and 255. + The `np_pixels[]` array contains the values for all the pixels in the image. + Unlike the one dimensional array `Py5Image.pixels[]`, the `np_pixels[]` array + organizes the color data in a 3 dimensional numpy array. The size of the array's + dimensions are defined by the size of the image. The first dimension is the + height, the second is the width, and the third represents the color channels. + The color channels are ordered alpha, red, green, blue (ARGB). Every value in + `np_pixels[]` is an integer between 0 and 255. This numpy array is very similar to the image arrays used by other popular Python image libraries, but note that some of them like opencv will by default order the color channels as RGBA. - Much like the ``Py5Image.pixels[]`` array, there are load and update methods - that must be called before and after making changes to the data in - ``np_pixels[]``. Before accessing ``np_pixels[]``, the data must be loaded with - the ``Py5Image.load_np_pixels()`` method. If this is not done, ``np_pixels`` - will be equal to ``None`` and your code will likely result in Python exceptions. - After ``np_pixels[]`` has been modified, the ``Py5Image.update_np_pixels()`` - method must be called to update the content of the display window. + Much like the `Py5Image.pixels[]` array, there are load and update methods that + must be called before and after making changes to the data in `np_pixels[]`. + Before accessing `np_pixels[]`, the data must be loaded with the + `Py5Image.load_np_pixels()` method. If this is not done, `np_pixels` will be + equal to `None` and your code will likely result in Python exceptions. After + `np_pixels[]` has been modified, the `Py5Image.update_np_pixels()` method must + be called to update the content of the display window. - To set the entire contents of ``np_pixels[]`` to the contents of another equally - sized numpy array, consider using ``Py5Image.set_np_pixels()``.""") + To set the entire contents of `np_pixels[]` to the contents of another equally + sized numpy array, consider using `Py5Image.set_np_pixels()`.""") def set_np_pixels(self, array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None: - """Set the entire contents of ``Py5Image.np_pixels[]`` to the contents of another + """Set the entire contents of `Py5Image.np_pixels[]` to the contents of another properly sized and typed numpy array. Parameters @@ -719,26 +719,26 @@ def set_np_pixels(self, Notes ----- - Set the entire contents of ``Py5Image.np_pixels[]`` to the contents of another - properly sized and typed numpy array. The size of ``array``'s first and second + Set the entire contents of `Py5Image.np_pixels[]` to the contents of another + properly sized and typed numpy array. The size of `array`'s first and second dimensions must match the height and width of the image, respectively. The - array's ``dtype`` must be ``np.uint8``. + array's `dtype` must be `np.uint8`. - The ``bands`` parameter is used to interpret the ``array``'s color channel - dimension (the array's third dimension). It can be one of ``'L'`` (single- - channel grayscale), ``'ARGB'``, ``'RGB'``, or ``'RGBA'``. If there is no alpha - channel, ``array`` is assumed to have no transparency. If the ``bands`` - parameter is ``'L'``, ``array``'s third dimension is optional. + The `bands` parameter is used to interpret the `array`'s color channel dimension + (the array's third dimension). It can be one of `'L'` (single-channel + grayscale), `'ARGB'`, `'RGB'`, or `'RGBA'`. If there is no alpha channel, + `array` is assumed to have no transparency. If the `bands` parameter is `'L'`, + `array`'s third dimension is optional. - This method makes its own calls to ``Py5Image.load_np_pixels()`` and - ``Py5Image.update_np_pixels()`` so there is no need to call either explicitly. + This method makes its own calls to `Py5Image.load_np_pixels()` and + `Py5Image.update_np_pixels()` so there is no need to call either explicitly. This method exists because setting the array contents with the code - ``img.np_pixels = array`` will cause an error, while the correct syntax, - ``img.np_pixels[:] = array``, might also be unintuitive for beginners. + `img.np_pixels = array` will cause an error, while the correct syntax, + `img.np_pixels[:] = array`, might also be unintuitive for beginners. - Note that the ``convert_image()`` method can also be used to convert a numpy - array into a new Py5Image object.""" + Note that the `convert_image()` method can also be used to convert a numpy array + into a new Py5Image object.""" return super().set_np_pixels(array, bands) def save(self, @@ -777,14 +777,14 @@ def save(self, Pillow to write the image, so it can save images in any format that that library supports. - Use the ``drop_alpha`` parameter to drop the alpha channel from the image. This - defaults to ``True``. Some image formats such as JPG do not support alpha + Use the `drop_alpha` parameter to drop the alpha channel from the image. This + defaults to `True`. Some image formats such as JPG do not support alpha channels, and Pillow will throw an error if you try to save an image with the alpha channel in that format. - The ``use_thread`` parameter will save the image in a separate Python thread. - This improves performance by returning before the image has actually been - written to the file.""" + The `use_thread` parameter will save the image in a separate Python thread. This + improves performance by returning before the image has actually been written to + the file.""" return super().save( filename, format=format, diff --git a/py5/mixins/print_tools.py b/py5/mixins/print_tools.py index cf8308e..f38c64e 100644 --- a/py5/mixins/print_tools.py +++ b/py5/mixins/print_tools.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -34,7 +34,7 @@ def _init_println_stream(self): # *** BEGIN METHODS *** def set_println_stream(self, println_stream: Any) -> None: - """Customize where the output of ``println()`` goes. + """Customize where the output of `println()` goes. Parameters ---------- @@ -45,18 +45,17 @@ def set_println_stream(self, println_stream: Any) -> None: Notes ----- - Customize where the output of ``println()`` goes. + Customize where the output of `println()` goes. - When running a Sketch asynchronously through Jupyter Notebook, any ``print`` + When running a Sketch asynchronously through Jupyter Notebook, any `print` statements using Python's builtin function will always appear in the output of the currently active cell. This will rarely be desirable, as the active cell will keep changing as the user executes code elsewhere in the notebook. The - ``println()`` method was created to provide users with print functionality in a + `println()` method was created to provide users with print functionality in a Sketch without having to cope with output moving from one cell to the next. Use - ``set_println_stream`` to change how the output is handled. The - ``println_stream`` object must provide ``init()`` and ``print()`` methods, as - shown in the example. The example demonstrates how to configure py5 to output - text to an IPython Widget.""" + `set_println_stream` to change how the output is handled. The `println_stream` + object must provide `init()` and `print()` methods, as shown in the example. The + example demonstrates how to configure py5 to output text to an IPython Widget.""" self._println_stream = println_stream def println( @@ -87,17 +86,17 @@ def println( Print text or other values to the screen. For a Sketch running outside of a Jupyter Notebook, this method will behave the same as the Python's builtin - ``print`` method. For Sketches running in a Jupyter Notebook, this will place - text in the output of the cell that made the ``run_sketch()`` call. + `print` method. For Sketches running in a Jupyter Notebook, this will place text + in the output of the cell that made the `run_sketch()` call. - When running a Sketch asynchronously through Jupyter Notebook, any ``print`` + When running a Sketch asynchronously through Jupyter Notebook, any `print` statements using Python's builtin function will always appear in the output of the currently active cell. This will rarely be desirable, as the active cell will keep changing as the user executes code elsewhere in the notebook. This method was created to provide users with print functionality in a Sketch without having to cope with output moving from one cell to the next. - Use ``set_println_stream()`` to customize the behavior of ``println()``.""" + Use `set_println_stream()` to customize the behavior of `println()`.""" msg = sep.join(str(x) for x in args) if self._println_stream is None: print(msg, end=end, file=sys.stderr if stderr else sys.stdout) diff --git a/py5/mixins/threads.py b/py5/mixins/threads.py index 8daa138..70611ef 100644 --- a/py5/mixins/threads.py +++ b/py5/mixins/threads.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -177,23 +177,23 @@ def launch_thread( This can be useful for executing non-py5 code that would otherwise slow down the animation thread and reduce the Sketch's frame rate. - The ``name`` parameter is optional but useful if you want to monitor the thread - with other methods such as ``has_thread()``. If the provided ``name`` is - identical to an already running thread, the running thread will first be stopped - with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. + The `name` parameter is optional but useful if you want to monitor the thread + with other methods such as `has_thread()`. If the provided `name` is identical + to an already running thread, the running thread will first be stopped with a + call to `stop_thread()` with the `wait` parameter equal to `True`. - Use the ``args`` and ``kwargs`` parameters to pass positional and keyword - arguments to the function. + Use the `args` and `kwargs` parameters to pass positional and keyword arguments + to the function. - Use the ``daemon`` parameter to make the launched thread a daemon that will run - without blocking Python from exiting. This parameter defaults to ``True``, - meaning that function execution can be interupted if the Python process exits. - Note that if the Python process continues running after the Sketch exits, which - is typically the case when using a Jupyter Notebook, this parameter won't have - any effect unless if you try to restart the Notebook kernel. Generally speaking, - setting this parameter to ``False`` causes problems but it is available for - those who really need it. See ``stop_all_threads()`` for a better approach to - exit threads. + Use the `daemon` parameter to make the launched thread a daemon that will run + without blocking Python from exiting. This parameter defaults to `True`, meaning + that function execution can be interupted if the Python process exits. Note that + if the Python process continues running after the Sketch exits, which is + typically the case when using a Jupyter Notebook, this parameter won't have any + effect unless if you try to restart the Notebook kernel. Generally speaking, + setting this parameter to `False` causes problems but it is available for those + who really need it. See `stop_all_threads()` for a better approach to exit + threads. The new thread is a Python thread, so all the usual caveats about the Global Interpreter Lock (GIL) apply here.""" @@ -210,7 +210,7 @@ def launch_promise_thread( daemon: bool = True, args: tuple = None, kwargs: dict = None) -> Py5Promise: - """Create a ``Py5Promise`` object that will store the returned result of a function + """Create a `Py5Promise` object that will store the returned result of a function when that function completes. Parameters @@ -234,32 +234,32 @@ def launch_promise_thread( Notes ----- - Create a ``Py5Promise`` object that will store the returned result of a function + Create a `Py5Promise` object that will store the returned result of a function when that function completes. This can be useful for executing non-py5 code that would otherwise slow down the animation thread and reduce the Sketch's frame rate. - The ``Py5Promise`` object has an ``is_ready`` property that will be ``True`` - when the ``result`` property contains the value function ``f`` returned. Before - then, the ``result`` property will be ``None``. + The `Py5Promise` object has an `is_ready` property that will be `True` when the + `result` property contains the value function `f` returned. Before then, the + `result` property will be `None`. - The ``name`` parameter is optional but useful if you want to monitor the thread - with other methods such as ``has_thread()``. If the provided ``name`` is - identical to an already running thread, the running thread will first be stopped - with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. + The `name` parameter is optional but useful if you want to monitor the thread + with other methods such as `has_thread()`. If the provided `name` is identical + to an already running thread, the running thread will first be stopped with a + call to `stop_thread()` with the `wait` parameter equal to `True`. - Use the ``args`` and ``kwargs`` parameters to pass positional and keyword - arguments to the function. + Use the `args` and `kwargs` parameters to pass positional and keyword arguments + to the function. - Use the ``daemon`` parameter to make the launched thread a daemon that will run - without blocking Python from exiting. This parameter defaults to ``True``, - meaning that function execution can be interupted if the Python process exits. - Note that if the Python process continues running after the Sketch exits, which - is typically the case when using a Jupyter Notebook, this parameter won't have - any effect unless if you try to restart the Notebook kernel. Generally speaking, - setting this parameter to ``False`` causes problems but it is available for - those who really need it. See ``stop_all_threads()`` for a better approach to - exit threads. + Use the `daemon` parameter to make the launched thread a daemon that will run + without blocking Python from exiting. This parameter defaults to `True`, meaning + that function execution can be interupted if the Python process exits. Note that + if the Python process continues running after the Sketch exits, which is + typically the case when using a Jupyter Notebook, this parameter won't have any + effect unless if you try to restart the Notebook kernel. Generally speaking, + setting this parameter to `False` causes problems but it is available for those + who really need it. See `stop_all_threads()` for a better approach to exit + threads. The new thread is a Python thread, so all the usual caveats about the Global Interpreter Lock (GIL) apply here.""" @@ -310,30 +310,29 @@ def launch_repeating_thread( your Sketch code. This can be useful for executing non-py5 code that would otherwise slow down the animation thread and reduce the Sketch's frame rate. - Use the ``time_delay`` parameter to set the time in seconds between one call to - function ``f`` and the next call. Set this parameter to ``0`` if you want each - call to happen immediately after the previous call finishes. If the function - ``f`` takes longer than expected to finish, py5 will wait for it to finish - before making the next call. There will not be overlapping calls to function - ``f``. - - The ``name`` parameter is optional but useful if you want to monitor the thread - with other methods such as ``has_thread()``. If the provided ``name`` is - identical to an already running thread, the running thread will first be stopped - with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. - - Use the ``args`` and ``kwargs`` parameters to pass positional and keyword - arguments to the function. - - Use the ``daemon`` parameter to make the launched thread a daemon that will run - without blocking Python from exiting. This parameter defaults to ``True``, - meaning that function execution can be interupted if the Python process exits. - Note that if the Python process continues running after the Sketch exits, which - is typically the case when using a Jupyter Notebook, this parameter won't have - any effect unless if you try to restart the Notebook kernel. Generally speaking, - setting this parameter to ``False`` causes problems but it is available for - those who really need it. See ``stop_all_threads()`` for a better approach to - exit threads. + Use the `time_delay` parameter to set the time in seconds between one call to + function `f` and the next call. Set this parameter to `0` if you want each call + to happen immediately after the previous call finishes. If the function `f` + takes longer than expected to finish, py5 will wait for it to finish before + making the next call. There will not be overlapping calls to function `f`. + + The `name` parameter is optional but useful if you want to monitor the thread + with other methods such as `has_thread()`. If the provided `name` is identical + to an already running thread, the running thread will first be stopped with a + call to `stop_thread()` with the `wait` parameter equal to `True`. + + Use the `args` and `kwargs` parameters to pass positional and keyword arguments + to the function. + + Use the `daemon` parameter to make the launched thread a daemon that will run + without blocking Python from exiting. This parameter defaults to `True`, meaning + that function execution can be interupted if the Python process exits. Note that + if the Python process continues running after the Sketch exits, which is + typically the case when using a Jupyter Notebook, this parameter won't have any + effect unless if you try to restart the Notebook kernel. Generally speaking, + setting this parameter to `False` causes problems but it is available for those + who really need it. See `stop_all_threads()` for a better approach to exit + threads. The new thread is a Python thread, so all the usual caveats about the Global Interpreter Lock (GIL) apply here.""" @@ -361,7 +360,7 @@ def has_thread(self, name: str) -> None: ----- Determine if a thread of a given name exists and is currently running. You can - get the list of all currently running threads with ``list_threads()``.""" + get the list of all currently running threads with `list_threads()`.""" self._remove_dead_threads() return name in self._py5threads @@ -381,15 +380,15 @@ def join_thread(self, name: str, *, timeout: float = None) -> bool: ----- Join the Python thread associated with the given thread name. The - ``join_thread()`` method will wait until the named thread has finished executing - before returning. Use the ``timeout`` parameter to set an upper limit for the + `join_thread()` method will wait until the named thread has finished executing + before returning. Use the `timeout` parameter to set an upper limit for the number of seconds to wait. This method will return right away if the named thread does not exist or the thread has already finished executing. You can get - the list of all currently running threads with ``list_threads()``. + the list of all currently running threads with `list_threads()`. - This method will return ``True`` if the named thread has completed execution and - ``False`` if the named thread is still executing. It will only return ``False`` - if you use the ``timeout`` parameter and the method is not able to join with the + This method will return `True` if the named thread has completed execution and + `False` if the named thread is still executing. It will only return `False` if + you use the `timeout` parameter and the method is not able to join with the thread within that time limit.""" self._remove_dead_threads() if name in self._py5threads: @@ -411,21 +410,20 @@ def stop_thread(self, name: str, wait: bool = False) -> None: Notes ----- - Stop a thread of a given name. The ``wait`` parameter determines if the method + Stop a thread of a given name. The `wait` parameter determines if the method call will return right away or wait for the thread to exit. This won't do anything useful if the thread was launched with either - ``launch_thread()`` or ``launch_promise_thread()`` and the ``wait`` parameter is - ``False``. Non-repeating threads are executed once and will stop when they - complete execution. Setting the ``wait`` parameter to ``True`` will merely block + `launch_thread()` or `launch_promise_thread()` and the `wait` parameter is + `False`. Non-repeating threads are executed once and will stop when they + complete execution. Setting the `wait` parameter to `True` will merely block until the thread exits on its own. Killing off a running thread in Python is complicated and py5 cannot do that for you. If you want a thread to perform some - action repeatedly and be interuptable, use ``launch_repeating_thread()`` - instead. + action repeatedly and be interuptable, use `launch_repeating_thread()` instead. - Use ``has_thread()`` to determine if a thread of a given name exists and - ``list_threads()`` to get a list of all thread names. Use ``stop_all_threads()`` - to stop all threads.""" + Use `has_thread()` to determine if a thread of a given name exists and + `list_threads()` to get a list of all thread names. Use `stop_all_threads()` to + stop all threads.""" if name in self._py5threads: t, py5thread = self._py5threads[name] py5thread.stop() @@ -444,12 +442,12 @@ def stop_all_threads(self, wait: bool = False) -> None: Notes ----- - Stop all running threads. The ``wait`` parameter determines if the method call + Stop all running threads. The `wait` parameter determines if the method call will return right away or wait for the threads to exit. - When the Sketch shuts down, ``stop_all_threads(wait=False)`` is called for you. - If you would rather the Sketch waited for threads to exit, create an ``exiting`` - method and make a call to ``stop_all_threads(wait=True)``.""" + When the Sketch shuts down, `stop_all_threads(wait=False)` is called for you. If + you would rather the Sketch waited for threads to exit, create an `exiting` + method and make a call to `stop_all_threads(wait=True)`.""" current_thread_name = threading.current_thread().name for name in self.list_threads(): if name == current_thread_name: diff --git a/py5/mouseevent.py b/py5/mouseevent.py index 314d807..ed780e7 100644 --- a/py5/mouseevent.py +++ b/py5/mouseevent.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -21,6 +21,8 @@ import weakref +from . import spelling + class Py5MouseEvent: """Datatype for providing information about mouse events. @@ -33,11 +35,11 @@ class Py5MouseEvent: Datatype for providing information about mouse events. An instance of this class will be passed to user-defined mouse event functions if py5 detects those functions accept 1 (positional) argument, as demonstrated in the example code. - The mouse event functions can be any of ``mouse_clicked()``, - ``mouse_dragged()``, ``mouse_moved()``, ``mouse_entered()``, ``mouse_exited()``, - ``mouse_pressed()``, ``mouse_released()``, or ``mouse_wheel()``. Mouse events - can be generated faster than the frame rate of the Sketch, making mouse event - functions useful for capturing all of a user's mouse activity. + The mouse event functions can be any of `mouse_clicked()`, `mouse_dragged()`, + `mouse_moved()`, `mouse_entered()`, `mouse_exited()`, `mouse_pressed()`, + `mouse_released()`, or `mouse_wheel()`. Mouse events can be generated faster + than the frame rate of the Sketch, making mouse event functions useful for + capturing all of a user's mouse activity. """ _py5_object_cache = weakref.WeakSet() @@ -51,6 +53,22 @@ def __new__(cls, pmouseevent): cls._py5_object_cache.add(o) return o + def __str__(self): + action = self.get_action() + action_str = 'UNKNOWN' + for k, v in Py5MouseEvent.__dict__.items(): + if k == k.upper() and action == v: + action_str = k + break + return f"Py5MouseEvent(x=" + str(self.get_x()) + ", y=" + \ + str(self.get_y()) + ", action=" + action_str + ")" + + def __repr__(self): + return self.__str__() + + def __getattr__(self, name): + raise AttributeError(spelling.error_msg('Py5MouseEvent', name, self)) + ALT = 8 CLICK = 3 CTRL = 2 @@ -85,8 +103,8 @@ def get_button(self) -> int: Notes ----- - Identify the mouse button used in the event. This can be ``LEFT``, ``CENTER``, - or ``RIGHT``. + Identify the mouse button used in the event. This can be `LEFT`, `CENTER`, or + `RIGHT`. """ return self._instance.getButton() @@ -143,8 +161,8 @@ def get_native(self) -> Any: system the Sketch is run on. Sometimes the native object can be used to access functionality not otherwise available through Processing or py5. - Be aware that it is possible for the native event object to be ``None``, such as - when interacting with a Sketch through ``py5_tools.sketch_portal()``. + Be aware that it is possible for the native event object to be `None`, such as + when interacting with a Sketch through `py5_tools.sketch_portal()`. """ return self._instance.getNative() @@ -157,7 +175,7 @@ def get_x(self) -> int: ----- Return the x position of the mouse at the time of this mouse event. This - information can also be obtained with ``mouse_x``. + information can also be obtained with `mouse_x`. """ return self._instance.getX() @@ -170,7 +188,7 @@ def get_y(self) -> int: ----- Return the y position of the mouse at the time of this mouse event. This - information can also be obtained with ``mouse_y``. + information can also be obtained with `mouse_y`. """ return self._instance.getY() diff --git a/py5/natives/windows-amd64/fenster.exe b/py5/natives/windows-amd64/fenster.exe index 8108d17aa7a47c12c467ccfb1c2a6b255f85657a..f4a7bbd6a0041d4e16933eca76fa0a1ac28669f6 100644 GIT binary patch literal 41472 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 Sb)$J>A^Jn~$KU@?6!>5L59k~K literal 8704 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. # # ***************************************************************************** +import pathlib + import numpy as np from jpype import JClass, JArray, _jcustomizer from .sketch import _Sketch, Sketch, Py5Graphics, Py5Image, Py5Font, Py5Shape, Py5Shader, Py5KeyEvent, Py5MouseEvent -from .pmath import _py5vector_to_pvector_converter, _numpy_to_pvector_converter, _numpy_to_pmatrix_converter +from .pmath import _py5vector_to_pvector_converter, _numpy_to_pvector_converter, _numpy_to_pmatrix_converter, _PVector, _PMatrix2D, _PMatrix3D, _pvector_to_py5vector, _pmatrix_to_numpy from .vector import Py5Vector @@ -48,6 +50,9 @@ (JClass("processing.opengl.PShader"), Py5Shader), (JClass("processing.event.KeyEvent"), Py5KeyEvent), (JClass("processing.event.MouseEvent"), Py5MouseEvent), + (_PVector, _pvector_to_py5vector), + (_PMatrix2D, _pmatrix_to_numpy), + (_PMatrix3D, _pmatrix_to_numpy), ] _String = JClass("java.lang.String") @@ -70,20 +75,44 @@ def convert(jcls, obj): _jcustomizer.JConversion( 'processing.core.PMatrix', np.ndarray)(_numpy_to_pmatrix_converter) + _jcustomizer.JConversion( + 'java.lang.String', + pathlib.Path)( + lambda jcls, + path: _String( + path.as_posix())) -def convert_to_python_types(params): - for p in params: - for jclass, py5class in PROCESSING_TO_PY5_CLASS_MAP: - if isinstance(p, jclass): - yield py5class(p) - break +def convert_to_java_type(obj): + for _, py5class in JCONVERSION_CLASS_MAP: + if isinstance(obj, py5class): + return obj._instance + + if isinstance(obj, Py5Vector): + if obj.dim == 4: + return obj._data else: - if isinstance(p, _String): - yield str(p) - elif isinstance(p, _Sketch): - yield Sketch(_instance=p) - elif isinstance(p, JArray): - yield np.asarray(p) - else: - yield p + return _py5vector_to_pvector_converter(obj) + elif isinstance(obj, pathlib.Path): + return _String(obj.as_posix()) + elif isinstance(obj, np.ndarray): + return JArray.of(obj) + else: + return obj + + +def convert_to_python_type(obj): + for jclass, py5class in PROCESSING_TO_PY5_CLASS_MAP: + if isinstance(obj, jclass): + return py5class(obj) + + if isinstance(obj, _String): + return str(obj) + elif isinstance(obj, _Sketch): + return Sketch(_instance=obj) + else: + return obj + + +def convert_to_python_types(params): + return [convert_to_python_type(p) for p in params] diff --git a/py5/pmath.py b/py5/pmath.py index 5476e66..8029083 100644 --- a/py5/pmath.py +++ b/py5/pmath.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -57,7 +57,7 @@ def _numpy_to_pmatrix3d(array): # the next three functions are only used for the jpype conversion customizer -# they are registered in java_conversion.py +# they are registered in object_conversion.py def _numpy_to_pvector_converter(jcls, array): return _numpy_to_pvector(array) diff --git a/py5/reference.py b/py5/reference.py index 8474c05..1ac7a21 100644 --- a/py5/reference.py +++ b/py5/reference.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -120,7 +120,7 @@ (('Sketch', 'frame_rate'), ['(fps: float, /) -> None']), (('Sketch', 'frustum'), ['(left: float, right: float, bottom: float, top: float, near: float, far: float, /) -> None']), (('Sketch', 'full_screen'), ['() -> None', '(display: int, /) -> None', '(renderer: str, /) -> None', '(renderer: str, display: int, /) -> None']), - (('Sketch', 'get'), ['() -> Py5Image', '(x: int, y: int, /) -> int', '(x: int, y: int, w: int, h: int, /) -> Py5Image']), + (('Sketch', 'get_pixels'), ['() -> Py5Image', '(x: int, y: int, /) -> int', '(x: int, y: int, w: int, h: int, /) -> Py5Image']), (('Sketch', 'get_frame_rate'), ['() -> float']), (('Sketch', 'get_graphics'), ['() -> Py5Graphics']), (('Sketch', 'get_matrix'), ['() -> npt.NDArray[np.floating]', '(target: npt.NDArray[np.floating], /) -> npt.NDArray[np.floating]']), @@ -194,6 +194,7 @@ (('Sketch', 'screen_y'), ['(x: float, y: float, /) -> float', '(x: float, y: float, z: float, /) -> float']), (('Sketch', 'screen_z'), ['(x: float, y: float, z: float, /) -> float']), (('Sketch', 'second'), ['() -> int']), + (('Sketch', 'set_pixels'), ['(x: int, y: int, c: int, /) -> None', '(x: int, y: int, img: Py5Image, /) -> None']), (('Sketch', 'set_matrix'), ['(source: npt.NDArray[np.floating], /) -> None']), (('Sketch', 'shader'), ['(shader: Py5Shader, /) -> None', '(shader: Py5Shader, kind: int, /) -> None']), (('Sketch', 'shape'), ['(shape: Py5Shape, /) -> None', '(shape: Py5Shape, x: float, y: float, /) -> None', '(shape: Py5Shape, a: float, b: float, c: float, d: float, /) -> None']), @@ -236,6 +237,29 @@ (('Sketch', 'window_resize'), ['(new_width: int, new_height: int, /) -> None']), (('Sketch', 'window_title'), ['(title: str, /) -> None']), (('Sketch', 'year'), ['() -> int']), + (('Sketch', 'load_json'), ['(json_path: Union[str, Path], **kwargs: dict[str, Any]) -> Any']), + (('Sketch', 'save_json'), ['(json_data: Any, filename: Union[str, Path], **kwargs: dict[str, Any]) -> None']), + (('Sketch', 'parse_json'), ['(serialized_json: Any, **kwargs: dict[str, Any]) -> Any']), + (('Sketch', 'load_strings'), ['(string_path: Union[str, Path], **kwargs: dict[str, Any]) -> list[str]']), + (('Sketch', 'save_strings'), ["(string_data: list[str], filename: Union[str, Path], *, end: str = '\\n') -> None"]), + (('Sketch', 'load_bytes'), ['(bytes_path: Union[str, Path], **kwargs: dict[str, Any]) -> bytearray']), + (('Sketch', 'save_bytes'), ['(bytes_data: Union[bytes, bytearray], filename: Union[str, Path]) -> None']), + (('Sketch', 'load_pickle'), ['(pickle_path: Union[str, Path]) -> Any']), + (('Sketch', 'save_pickle'), ['(obj: Any, filename: Union[str, Path]) -> None']), + (('Sketch', 'set_println_stream'), ['(println_stream: Any) -> None']), + (('Sketch', 'println'), ["(*args, sep: str = ' ', end: str = '\\n', stderr: bool = False) -> None"]), + (('Sketch', 'launch_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> str']), + (('Sketch', 'launch_promise_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> Py5Promise']), + (('Sketch', 'launch_repeating_thread'), ['(f: Callable, name: str = None, *, time_delay: float = 0, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> str']), + (('Sketch', 'has_thread'), ['(name: str) -> None']), + (('Sketch', 'join_thread'), ['(name: str, *, timeout: float = None) -> bool']), + (('Sketch', 'stop_thread'), ['(name: str, wait: bool = False) -> None']), + (('Sketch', 'stop_all_threads'), ['(wait: bool = False) -> None']), + (('Sketch', 'list_threads'), ['() -> None']), + (('Sketch', 'load_np_pixels'), ['() -> None']), + (('Sketch', 'update_np_pixels'), ['() -> None']), + (('Sketch', 'set_np_pixels'), ["(array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None"]), + (('Sketch', 'save'), ['(filename: Union[str, Path, BytesIO], *, format: str = None, drop_alpha: bool = True, use_thread: bool = False, **params) -> None']), (('Sketch', 'hex_color'), ['(color: int) -> str']), (('Sketch', 'sin'), ['(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]']), (('Sketch', 'cos'), ['(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]']), @@ -261,33 +285,11 @@ (('Sketch', 'random_seed'), ['(seed: int) -> None']), (('Sketch', 'random'), ['() -> float', '(high: float, /) -> float', '(low: float, high: float, /) -> float']), (('Sketch', 'random_int'), ['() -> int', '(high: int, /) -> int', '(low: int, high: int, /) -> int']), - (('Sketch', 'random_choice'), ['(objects: list[Any], size: int=1, replace: bool=True) -> Any']), + (('Sketch', 'random_choice'), ['(objects: list[Any]) -> Any']), + (('Sketch', 'random_sample'), ['(objects: list[Any], size: int=1, replace: bool=True) -> list[Any]']), (('Sketch', 'random_gaussian'), ['() -> float', '(loc: float, /) -> float', '(loc: float, scale: float, /) -> float']), (('Sketch', 'noise'), ['(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]']), (('Sketch', 'os_noise'), ['(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]']), - (('Sketch', 'load_np_pixels'), ['() -> None']), - (('Sketch', 'update_np_pixels'), ['() -> None']), - (('Sketch', 'set_np_pixels'), ["(array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None"]), - (('Sketch', 'save'), ['(filename: Union[str, Path, BytesIO], *, format: str = None, drop_alpha: bool = True, use_thread: bool = False, **params) -> None']), - (('Sketch', 'set_println_stream'), ['(println_stream: Any) -> None']), - (('Sketch', 'println'), ["(*args, sep: str = ' ', end: str = '\\n', stderr: bool = False) -> None"]), - (('Sketch', 'load_json'), ['(json_path: Union[str, Path], **kwargs: dict[str, Any]) -> Any']), - (('Sketch', 'save_json'), ['(json_data: Any, filename: Union[str, Path], **kwargs: dict[str, Any]) -> None']), - (('Sketch', 'parse_json'), ['(serialized_json: Any, **kwargs: dict[str, Any]) -> Any']), - (('Sketch', 'load_strings'), ['(string_path: Union[str, Path], **kwargs: dict[str, Any]) -> list[str]']), - (('Sketch', 'save_strings'), ["(string_data: list[str], filename: Union[str, Path], *, end: str = '\\n') -> None"]), - (('Sketch', 'load_bytes'), ['(bytes_path: Union[str, Path], **kwargs: dict[str, Any]) -> bytearray']), - (('Sketch', 'save_bytes'), ['(bytes_data: Union[bytes, bytearray], filename: Union[str, Path]) -> None']), - (('Sketch', 'load_pickle'), ['(pickle_path: Union[str, Path]) -> Any']), - (('Sketch', 'save_pickle'), ['(obj: Any, filename: Union[str, Path]) -> None']), - (('Sketch', 'launch_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> str']), - (('Sketch', 'launch_promise_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> Py5Promise']), - (('Sketch', 'launch_repeating_thread'), ['(f: Callable, name: str = None, *, time_delay: float = 0, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> str']), - (('Sketch', 'has_thread'), ['(name: str) -> None']), - (('Sketch', 'join_thread'), ['(name: str, *, timeout: float = None) -> bool']), - (('Sketch', 'stop_thread'), ['(name: str, wait: bool = False) -> None']), - (('Sketch', 'stop_all_threads'), ['(wait: bool = False) -> None']), - (('Sketch', 'list_threads'), ['() -> None']), (('Sketch', 'sketch_path'), ['() -> Path', '(where: str, /) -> Path']), (('Sketch', 'hot_reload_draw'), ['(draw: Callable) -> None']), (('Sketch', 'profile_functions'), ['(function_names: list[str]) -> None']), @@ -469,7 +471,7 @@ (('Py5Graphics', 'apply_filter'), ['(kind: int, /) -> None', '(kind: int, param: float, /) -> None', '(shader: Py5Shader, /) -> None']), (('Py5Graphics', 'flush'), ['() -> None']), (('Py5Graphics', 'frustum'), ['(left: float, right: float, bottom: float, top: float, near: float, far: float, /) -> None']), - (('Py5Graphics', 'get'), ['() -> Py5Image', '(x: int, y: int, /) -> int', '(x: int, y: int, w: int, h: int, /) -> Py5Image']), + (('Py5Graphics', 'get_pixels'), ['() -> Py5Image', '(x: int, y: int, /) -> int', '(x: int, y: int, w: int, h: int, /) -> Py5Image']), (('Py5Graphics', 'get_matrix'), ['() -> npt.NDArray[np.floating]', '(target: npt.NDArray[np.floating], /) -> npt.NDArray[np.floating]']), (('Py5Graphics', 'green'), ['(rgb: int, /) -> float']), (('Py5Graphics', 'hint'), ['(which: int, /) -> None']), @@ -524,6 +526,7 @@ (('Py5Graphics', 'screen_x'), ['(x: float, y: float, /) -> float', '(x: float, y: float, z: float, /) -> float']), (('Py5Graphics', 'screen_y'), ['(x: float, y: float, /) -> float', '(x: float, y: float, z: float, /) -> float']), (('Py5Graphics', 'screen_z'), ['(x: float, y: float, z: float, /) -> float']), + (('Py5Graphics', 'set_pixels'), ['(x: int, y: int, c: int, /) -> None', '(x: int, y: int, img: Py5Image, /) -> None']), (('Py5Graphics', 'set_matrix'), ['(source: npt.NDArray[np.floating], /) -> None']), (('Py5Graphics', 'shader'), ['(shader: Py5Shader, /) -> None', '(shader: Py5Shader, kind: int, /) -> None']), (('Py5Graphics', 'shape'), ['(shape: Py5Shape, /) -> None', '(shape: Py5Shape, x: float, y: float, /) -> None', '(shape: Py5Shape, a: float, b: float, c: float, d: float, /) -> None']), @@ -562,9 +565,10 @@ (('Py5Image', 'blend'), ['(sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, mode: int, /) -> None', '(src: Py5Image, sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, mode: int, /) -> None']), (('Py5Image', 'copy'), ['() -> Py5Image', '(sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, /) -> None', '(src: Py5Image, sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, /) -> None']), (('Py5Image', 'apply_filter'), ['(kind: int, /) -> None', '(kind: int, param: float, /) -> None']), - (('Py5Image', 'get'), ['() -> Py5Image', '(x: int, y: int, /) -> int', '(x: int, y: int, w: int, h: int, /) -> Py5Image']), + (('Py5Image', 'get_pixels'), ['() -> Py5Image', '(x: int, y: int, /) -> int', '(x: int, y: int, w: int, h: int, /) -> Py5Image']), (('Py5Image', 'load_pixels'), ['() -> None']), (('Py5Image', 'mask'), ['(mask_array: npt.NDArray[np.integer], /) -> None', '(img: Py5Image, /) -> None']), + (('Py5Image', 'set_pixels'), ['(x: int, y: int, c: int, /) -> None', '(x: int, y: int, img: Py5Image, /) -> None']), (('Py5Image', 'update_pixels'), ['() -> None', '(x: int, y: int, w: int, h: int, /) -> None']), (('Py5KeyEvent', 'get_action'), ['() -> int']), (('Py5KeyEvent', 'get_key'), ['() -> chr']), @@ -605,10 +609,10 @@ (('Py5Vector', 'random'), ['(dim: int, *, dtype: type = np.float_) -> Py5Vector']), (('Py5Vector', 'rotate'), ['(angle: float) -> Py5Vector2D', '(angle: float, dim: Union[int, str]) -> Py5Vector3D']), (('Py5Vector', 'rotate_around'), ['(angle: float, v: Py5Vector3D) -> Py5Vector3D']), - (('Sketch', 'run_sketch'), ['(block: bool = None, *, py5_options: list[str] = None, sketch_args: list[str] = None, sketch_functions: dict[str, Callable] = None) -> None']), + (('Sketch', 'run_sketch'), ['(block: bool = None, *, py5_options: list[str] = None, sketch_args: list[str] = None, sketch_functions: dict[str, Callable] = None, jclassname: str = None) -> None']), (('Py5Functions', 'create_font_file'), ['(font_name: str, font_size: int, filename: str = None, characters: str = None, pause: bool = True) -> None']), (('Py5Functions', 'get_current_sketch'), ['() -> Sketch']), - (('Py5Functions', 'reset_py5'), ['() -> bool']), + (('Py5Functions', 'reset_py5'), ['(jclassname: str = None) -> bool']), (('Py5Functions', 'prune_tracebacks'), ['(prune: bool) -> None']), (('Py5Functions', 'set_stackprinter_style'), ['(style: str) -> None']), (('Py5Functions', 'render_frame'), ['(draw: Callable, width: int, height: int, renderer: str = Sketch.HIDDEN, *, draw_args: tuple = None, draw_kwargs: dict = None, use_py5graphics: bool = False) -> Image']), @@ -621,9 +625,10 @@ (('Py5Tools', 'get_classpath'), ['() -> str']), (('Py5Tools', 'add_classpath'), ['(classpath: Union[Path, str]) -> None']), (('Py5Tools', 'add_jars'), ['(path: Union[Path, str]) -> None']), + (('Py5Tools', 'register_processing_mode_key'), ['(key: str, value: Union[Callable, ModuleType], *, callback_once: bool = False) -> None']), (('Py5Tools', 'get_jvm_debug_info'), ['() -> dict[str, Any]']), (('Py5Tools', 'screenshot'), ['(*, sketch: Sketch = None, hook_post_draw: bool = False) -> PIL.Image']), - (('Py5Tools', 'save_frames'), ["(dirname: str, *, filename: str = 'frame_####.png', period: float = 0.0, start: int = None, limit: int = 0, sketch: Sketch = None, hook_post_draw: bool = False, block: bool = False) -> None"]), + (('Py5Tools', 'save_frames'), ["(dirname: str, *, filename: str = 'frame_####.png', period: float = 0.0, start: int = None, limit: int = 0, sketch: Sketch = None, hook_post_draw: bool = False, block: bool = False, display_progress: bool = True) -> None"]), (('Py5Tools', 'animated_gif'), ['(filename: str, count: int, period: float, duration: float, *, loop: int = 0, optimize: bool = True, sketch: Sketch = None, hook_post_draw: bool = False, block: bool = False) -> None']), (('Py5Tools', 'offline_frame_processing'), ['(func: Callable[[npt.NDArray[np.uint8]], None], *, limit: int = 0, period: float = 0.0, batch_size: int = 1, complete_func: Callable[[], None] = None, stop_processing_func: Callable[[], bool] = None, sketch: Sketch = None, hook_post_draw: bool = False, queue_limit: int = None, block: bool = False) -> None']), (('Py5Tools', 'capture_frames'), ['(count: float, *, period: float = 0.0, sketch: Sketch = None, hook_post_draw: bool = False, block: bool = False) -> list[PIL.Image]']), diff --git a/py5/render_helper.py b/py5/render_helper.py index e6e4d09..a63ab57 100644 --- a/py5/render_helper.py +++ b/py5/render_helper.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -163,7 +163,7 @@ def render_frame(draw: Callable, width: int, height: int, renderer: str = Sketch.HIDDEN, *, draw_args: tuple = None, draw_kwargs: dict = None, use_py5graphics=False) -> PIL.ImageFile.ImageFile: - """Helper function to render a single frame using the passed ``draw`` function + """Helper function to render a single frame using the passed `draw` function argument. Parameters @@ -193,30 +193,29 @@ def render_frame(draw: Callable, width: int, height: int, Notes ----- - Helper function to render a single frame using the passed ``draw`` function - argument. The output is returned as a ``PIL.Image`` object. + Helper function to render a single frame using the passed `draw` function + argument. The output is returned as a `PIL.Image` object. - The passed function's first parameter must be either a ``py5.Sketch`` object or - a ``py5.Py5Graphics`` object, depending on the parameter ``use_py5graphics``. - That object must be used for all of the function's py5 commands. The function - can have additional positional and keyword arguments. To use them, pass the - desired values as ``render_frame``'s ``draw_args`` and ``draw_kwargs`` - arguments. + The passed function's first parameter must be either a `py5.Sketch` object or a + `py5.Py5Graphics` object, depending on the parameter `use_py5graphics`. That + object must be used for all of the function's py5 commands. The function can + have additional positional and keyword arguments. To use them, pass the desired + values as `render_frame`'s `draw_args` and `draw_kwargs` arguments. On OSX, only the default renderer is currently supported. Other platforms support the default renderer and the OpenGL renderers (P2D and P3D). The rendered frame can have transparent pixels if and only if the - ``use_py5graphics`` parameter is ``True`` because only a ``py5.Py5Graphics`` - object can create an image with transparency. There is no need to call - ``Py5Graphics.begin_draw()`` or ``Py5Graphics.end_draw()`` in the passed - function as ``render_frame()`` does that for you. + `use_py5graphics` parameter is `True` because only a `py5.Py5Graphics` object + can create an image with transparency. There is no need to call + `Py5Graphics.begin_draw()` or `Py5Graphics.end_draw()` in the passed function as + `render_frame()` does that for you. This function facilitates the creation and execution of a py5 Sketch, and as a result makes it easy to run a Sketch inside of another Sketch. This is discouraged, and may fail catastrophically. - This function is available in decorator form as ``@render()``.""" + This function is available in decorator form as `@render()`.""" if msg := _check_allowed_renderer(renderer): print(msg, file=sys.stderr) return None @@ -243,8 +242,8 @@ def render_frame_sequence(draw: Callable, draw_args: tuple = None, draw_kwargs: dict = None, use_py5graphics=False) -> list[PIL.ImageFile.ImageFile]: - """Helper function to render a sequence of frames using the passed ``draw`` - function argument. + """Helper function to render a sequence of frames using the passed `draw` function + argument. Parameters ---------- @@ -285,37 +284,37 @@ def render_frame_sequence(draw: Callable, Notes ----- - Helper function to render a sequence of frames using the passed ``draw`` - function argument. The output is returned as a list of ``PIL.Image`` objects. - Use the ``limit`` keyword argument to specify the number of frames to return. + Helper function to render a sequence of frames using the passed `draw` function + argument. The output is returned as a list of `PIL.Image` objects. Use the + `limit` keyword argument to specify the number of frames to return. - The passed ``draw`` function's first parameter must be either a ``py5.Sketch`` - object or a ``py5.Py5Graphics`` object, depending on the parameter - ``use_py5graphics``. That object must be used for all py5 commands. The function + The passed `draw` function's first parameter must be either a `py5.Sketch` + object or a `py5.Py5Graphics` object, depending on the parameter + `use_py5graphics`. That object must be used for all py5 commands. The function can have additional positional and keyword arguments. To use them, pass the - desired values to ``render_frame_sequence``'s ``draw_args`` and ``draw_kwargs`` + desired values to `render_frame_sequence`'s `draw_args` and `draw_kwargs` arguments. On OSX, only the default renderer is currently supported. Other platforms support the default renderer and the OpenGL renderers (P2D and P3D). The rendered frames can have transparent pixels if and only if the - ``use_py5graphics`` parameter is ``True`` because only a ``py5.Py5Graphics`` - object can create an image with transparency. If you need to clear the canvas - between one frame and the next, use ``Py5Graphics.clear()``. There is no need to - call ``Py5Graphics.begin_draw()`` or ``Py5Graphics.end_draw()`` in the passed - ``draw`` function as ``render_frame_sequence()`` does that for you. + `use_py5graphics` parameter is `True` because only a `py5.Py5Graphics` object + can create an image with transparency. If you need to clear the canvas between + one frame and the next, use `Py5Graphics.clear()`. There is no need to call + `Py5Graphics.begin_draw()` or `Py5Graphics.end_draw()` in the passed `draw` + function as `render_frame_sequence()` does that for you. - Optionally the caller can pass a ``setup`` function, along with corresponding - ``setup_args`` and ``setup_kwargs`` arguments. This will be called once, just - like it would for any other py5 Sketch. The type of the first parameter must - also depend on the ``use_py5graphics`` parameter. + Optionally the caller can pass a `setup` function, along with corresponding + `setup_args` and `setup_kwargs` arguments. This will be called once, just like + it would for any other py5 Sketch. The type of the first parameter must also + depend on the `use_py5graphics` parameter. This function facilitates the creation and execution of a py5 Sketch, and as a result makes it easy to run a Sketch inside of another Sketch. This is discouraged, and may fail catastrophically. - This function is available in decorator form as ``@render_sequence()``.""" + This function is available in decorator form as `@render_sequence()`.""" if msg := _check_allowed_renderer(renderer): print(msg, file=sys.stderr) return None @@ -333,8 +332,7 @@ def render_frame_sequence(draw: Callable, def render(width: int, height: int, renderer: str = Sketch.HIDDEN, *, use_py5graphics=False) -> PIL.ImageFile.ImageFile: - """Decorator function to render a single frame using the decorated ``draw`` - function. + """Decorator function to render a single frame using the decorated `draw` function. Parameters ---------- @@ -354,12 +352,12 @@ def render(width: int, height: int, renderer: str = Sketch.HIDDEN, *, Notes ----- - Decorator function to render a single frame using the decorated ``draw`` - function. The output is returned as a ``PIL.Image`` object. + Decorator function to render a single frame using the decorated `draw` function. + The output is returned as a `PIL.Image` object. - The decorated draw function's first parameter must be either a ``py5.Sketch`` - object or a ``py5.Py5Graphics`` object, depending on the parameter - ``use_py5graphics``. That object must be used for all of the function's py5 + The decorated draw function's first parameter must be either a `py5.Sketch` + object or a `py5.Py5Graphics` object, depending on the parameter + `use_py5graphics`. That object must be used for all of the function's py5 commands. The function can have additional positional and keyword arguments. To use them, pass the desired values when you call the decorated function as you would to any other Python function. @@ -368,16 +366,16 @@ def render(width: int, height: int, renderer: str = Sketch.HIDDEN, *, support the default renderer and the OpenGL renderers (P2D and P3D). The rendered frame can have transparent pixels if and only if the - ``use_py5graphics`` parameter is ``True`` because only a ``py5.Py5Graphics`` - object can create an image with transparency. There is no need to call - ``Py5Graphics.begin_draw()`` or ``Py5Graphics.end_draw()`` in the decorated - function as ``@render()`` does that for you. + `use_py5graphics` parameter is `True` because only a `py5.Py5Graphics` object + can create an image with transparency. There is no need to call + `Py5Graphics.begin_draw()` or `Py5Graphics.end_draw()` in the decorated function + as `@render()` does that for you. This function facilitates the creation and execution of a py5 Sketch, and as a result makes it easy to run a Sketch inside of another Sketch. This is discouraged, and may fail catastrophically. - This function is available in non-decorator form as ``render_frame()``.""" + This function is available in non-decorator form as `render_frame()`.""" if msg := _check_allowed_renderer(renderer): raise RuntimeError(msg) renderer = _osx_renderer_check(renderer) @@ -396,7 +394,7 @@ def render_sequence(width: int, height: int, renderer: str = Sketch.HIDDEN, *, limit: int = 1, setup: Callable = None, setup_args: tuple = None, setup_kwargs: dict = None, use_py5graphics=False) -> list[PIL.ImageFile.ImageFile]: - """Decorator function to render a sequence of frames using the decorated ``draw`` + """Decorator function to render a sequence of frames using the decorated `draw` function. Parameters @@ -429,36 +427,36 @@ def render_sequence(width: int, height: int, renderer: str = Sketch.HIDDEN, *, Notes ----- - Decorator function to render a sequence of frames using the decorated ``draw`` - function. The output is returned as a list of ``PIL.Image`` objects. Use the - ``limit`` keyword argument to specify the number of frames to return. + Decorator function to render a sequence of frames using the decorated `draw` + function. The output is returned as a list of `PIL.Image` objects. Use the + `limit` keyword argument to specify the number of frames to return. - The decorated function's first parameter must be either a ``py5.Sketch`` object - or a ``py5.Py5Graphics`` object, depending on the parameter ``use_py5graphics``. - That object must be used for all py5 commands. The function can have additional + The decorated function's first parameter must be either a `py5.Sketch` object or + a `py5.Py5Graphics` object, depending on the parameter `use_py5graphics`. That + object must be used for all py5 commands. The function can have additional positional and keyword arguments. To use them, pass the desired values when you call the decorated function as you would to any other Python function. - Optionally, the caller can pass the decorator a ``setup`` function, along with - corresponding ``setup_args`` and ``setup_kwargs`` arguments. This will be called + Optionally, the caller can pass the decorator a `setup` function, along with + corresponding `setup_args` and `setup_kwargs` arguments. This will be called once, just like it would for any other py5 Sketch. The type of the first - parameter must also depend on the ``use_py5graphics`` parameter. + parameter must also depend on the `use_py5graphics` parameter. On OSX, only the default renderer is currently supported. Other platforms support the default renderer and the OpenGL renderers (P2D and P3D). The rendered frames can have transparent pixels if and only if the - ``use_py5graphics`` parameter is ``True`` because only a ``py5.Py5Graphics`` - object can create an image with transparency. If you need to clear the canvas - between one frame and the next, use ``Py5Graphics.clear()``. There is no need to - call ``Py5Graphics.begin_draw()`` or ``Py5Graphics.end_draw()`` in the decorated - function as ``@render_sequence()`` does that for you. + `use_py5graphics` parameter is `True` because only a `py5.Py5Graphics` object + can create an image with transparency. If you need to clear the canvas between + one frame and the next, use `Py5Graphics.clear()`. There is no need to call + `Py5Graphics.begin_draw()` or `Py5Graphics.end_draw()` in the decorated function + as `@render_sequence()` does that for you. This function facilitates the creation and execution of a py5 Sketch, and as a result makes it easy to run a Sketch inside of another Sketch. This is discouraged, and may fail catastrophically. - This function is available in non-decorator form as ``render_frame_sequence()``.""" + This function is available in non-decorator form as `render_frame_sequence()`.""" if msg := _check_allowed_renderer(renderer): raise RuntimeError(msg) renderer = _osx_renderer_check(renderer) diff --git a/py5/shader.py b/py5/shader.py index 4480214..816f8e8 100644 --- a/py5/shader.py +++ b/py5/shader.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -31,6 +31,7 @@ from jpype.types import JException, JArray, JBoolean, JInt, JFloat # noqa from .pmath import _py5vector_to_pvector, _numpy_to_pvector, _numpy_to_pmatrix2d, _numpy_to_pmatrix3d # noqa from .vector import Py5Vector +from . import spelling def _return_py5shader(f): @@ -92,9 +93,9 @@ class Py5Shader: ----- This class encapsulates a GLSL shader program, including a vertex and a fragment - shader. It's compatible with the ``P2D`` and ``P3D`` renderers, but not with the - default renderer. Use the ``load_shader()`` function to load your shader code - and create ``Py5Shader`` objects. + shader. It's compatible with the `P2D` and `P3D` renderers, but not with the + default renderer. Use the `load_shader()` function to load your shader code and + create `Py5Shader` objects. """ _py5_object_cache = weakref.WeakSet() @@ -108,6 +109,15 @@ def __new__(cls, pshader): cls._py5_object_cache.add(o) return o + def __str__(self) -> str: + return f"Py5Shader(id=" + str(id(self)) + ")" + + def __repr__(self) -> str: + return self.__str__() + + def __getattr__(self, name): + raise AttributeError(spelling.error_msg('Py5Shader', name, self)) + @overload def set(self, name: str, x: bool, /) -> None: """Sets the uniform variables inside the shader to modify the effect while the diff --git a/py5/shape.py b/py5/shape.py index 8aca973..712da26 100644 --- a/py5/shape.py +++ b/py5/shape.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -32,6 +32,7 @@ from .pmath import _get_pvector_wrapper # noqa from .decorators import _ret_str, _convert_hex_color, _convert_hex_color2, _context_wrapper # noqa +from . import spelling def _return_list_py5shapes(f): @@ -98,20 +99,20 @@ class Py5Shape: ----- Datatype for storing shapes. Before a shape is used, it must be loaded with the - ``load_shape()`` or created with the ``create_shape()``. The ``shape()`` - function is used to draw the shape to the display window. Py5 can currently load - and display SVG (Scalable Vector Graphics) and OBJ shapes. OBJ files can only be - opened using the ``P3D`` renderer. The ``load_shape()`` function supports SVG - files created with Inkscape and Adobe Illustrator. It is not a full SVG - implementation, but offers some straightforward support for handling vector - data. A more complete SVG implementation can be provided by ``convert_image()`` - if Cairo is installed. See installation instructions for additional detail. - - The ``Py5Shape`` object contains a group of methods that can operate on the - shape data. - - To create a new shape, use the ``create_shape()`` function. Do not use the - syntax ``Py5Shape()``. + `load_shape()` or created with the `create_shape()`. The `shape()` function is + used to draw the shape to the display window. Py5 can currently load and display + SVG (Scalable Vector Graphics) and OBJ shapes. OBJ files can only be opened + using the `P3D` renderer. The `load_shape()` function supports SVG files created + with Inkscape and Adobe Illustrator. It is not a full SVG implementation, but + offers some straightforward support for handling vector data. A more complete + SVG implementation can be provided by `convert_image()` if Cairo is installed. + See installation instructions for additional detail. + + The `Py5Shape` object contains a group of methods that can operate on the shape + data. + + To create a new shape, use the `create_shape()` function. Do not use the syntax + `Py5Shape()`. """ _py5_object_cache = weakref.WeakSet() @@ -125,6 +126,16 @@ def __new__(cls, pshape): cls._py5_object_cache.add(o) return o + def __str__(self): + name = "'" + self.get_name() + "'" if self.get_name() else str(None) + return f"Py5Shape(name=" + name + ")" + + def __repr__(self): + return self.__str__() + + def __getattr__(self, name): + raise AttributeError(spelling.error_msg('Py5Shape', name, self)) + ARC = 32 BEZIER_VERTEX = 1 BOX = 41 @@ -157,8 +168,8 @@ def __new__(cls, pshape): @overload def add_child(self, who: Py5Shape, /) -> None: - """Adds a child ``Py5Shape`` object to a parent ``Py5Shape`` object that is defined - as a ``GROUP``. + """Adds a child `Py5Shape` object to a parent `Py5Shape` object that is defined as + a `GROUP`. Underlying Processing method: PShape.addChild @@ -182,17 +193,16 @@ def add_child(self, who: Py5Shape, /) -> None: Notes ----- - Adds a child ``Py5Shape`` object to a parent ``Py5Shape`` object that is defined - as a ``GROUP``. In the example, the three shapes ``path``, ``rectangle``, and - ``circle`` are added to a parent ``Py5Shape`` variable named ``house`` that is a - ``GROUP``. + Adds a child `Py5Shape` object to a parent `Py5Shape` object that is defined as + a `GROUP`. In the example, the three shapes `path`, `rectangle`, and `circle` + are added to a parent `Py5Shape` variable named `house` that is a `GROUP`. """ pass @overload def add_child(self, who: Py5Shape, idx: int, /) -> None: - """Adds a child ``Py5Shape`` object to a parent ``Py5Shape`` object that is defined - as a ``GROUP``. + """Adds a child `Py5Shape` object to a parent `Py5Shape` object that is defined as + a `GROUP`. Underlying Processing method: PShape.addChild @@ -216,16 +226,15 @@ def add_child(self, who: Py5Shape, idx: int, /) -> None: Notes ----- - Adds a child ``Py5Shape`` object to a parent ``Py5Shape`` object that is defined - as a ``GROUP``. In the example, the three shapes ``path``, ``rectangle``, and - ``circle`` are added to a parent ``Py5Shape`` variable named ``house`` that is a - ``GROUP``. + Adds a child `Py5Shape` object to a parent `Py5Shape` object that is defined as + a `GROUP`. In the example, the three shapes `path`, `rectangle`, and `circle` + are added to a parent `Py5Shape` variable named `house` that is a `GROUP`. """ pass def add_child(self, *args): - """Adds a child ``Py5Shape`` object to a parent ``Py5Shape`` object that is defined - as a ``GROUP``. + """Adds a child `Py5Shape` object to a parent `Py5Shape` object that is defined as + a `GROUP`. Underlying Processing method: PShape.addChild @@ -249,16 +258,15 @@ def add_child(self, *args): Notes ----- - Adds a child ``Py5Shape`` object to a parent ``Py5Shape`` object that is defined - as a ``GROUP``. In the example, the three shapes ``path``, ``rectangle``, and - ``circle`` are added to a parent ``Py5Shape`` variable named ``house`` that is a - ``GROUP``. + Adds a child `Py5Shape` object to a parent `Py5Shape` object that is defined as + a `GROUP`. In the example, the three shapes `path`, `rectangle`, and `circle` + are added to a parent `Py5Shape` variable named `house` that is a `GROUP`. """ return self._instance.addChild(*args) @overload def ambient(self, gray: float, /) -> None: - """Sets a ``Py5Shape`` object's ambient reflectance. + """Sets a `Py5Shape` object's ambient reflectance. Underlying Processing method: PShape.ambient @@ -292,23 +300,23 @@ def ambient(self, gray: float, /) -> None: Notes ----- - Sets a ``Py5Shape`` object's ambient reflectance. This is combined with the + Sets a `Py5Shape` object's ambient reflectance. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color mode, - setting ``ambient(255, 127, 0)``, would cause all the red light to reflect and + setting `ambient(255, 127, 0)`, would cause all the red light to reflect and half of the green light to reflect. Use in combination with - ``Py5Shape.emissive()``, ``Py5Shape.specular()``, and ``Py5Shape.shininess()`` - to set the material properties of a ``Py5Shape`` object. + `Py5Shape.emissive()`, `Py5Shape.specular()`, and `Py5Shape.shininess()` to set + the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The ambient color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The ambient color setting will be applied to vertices added after the call to this method. """ pass @overload def ambient(self, x: float, y: float, z: float, /) -> None: - """Sets a ``Py5Shape`` object's ambient reflectance. + """Sets a `Py5Shape` object's ambient reflectance. Underlying Processing method: PShape.ambient @@ -342,23 +350,23 @@ def ambient(self, x: float, y: float, z: float, /) -> None: Notes ----- - Sets a ``Py5Shape`` object's ambient reflectance. This is combined with the + Sets a `Py5Shape` object's ambient reflectance. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color mode, - setting ``ambient(255, 127, 0)``, would cause all the red light to reflect and + setting `ambient(255, 127, 0)`, would cause all the red light to reflect and half of the green light to reflect. Use in combination with - ``Py5Shape.emissive()``, ``Py5Shape.specular()``, and ``Py5Shape.shininess()`` - to set the material properties of a ``Py5Shape`` object. + `Py5Shape.emissive()`, `Py5Shape.specular()`, and `Py5Shape.shininess()` to set + the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The ambient color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The ambient color setting will be applied to vertices added after the call to this method. """ pass @overload def ambient(self, rgb: int, /) -> None: - """Sets a ``Py5Shape`` object's ambient reflectance. + """Sets a `Py5Shape` object's ambient reflectance. Underlying Processing method: PShape.ambient @@ -392,23 +400,23 @@ def ambient(self, rgb: int, /) -> None: Notes ----- - Sets a ``Py5Shape`` object's ambient reflectance. This is combined with the + Sets a `Py5Shape` object's ambient reflectance. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color mode, - setting ``ambient(255, 127, 0)``, would cause all the red light to reflect and + setting `ambient(255, 127, 0)`, would cause all the red light to reflect and half of the green light to reflect. Use in combination with - ``Py5Shape.emissive()``, ``Py5Shape.specular()``, and ``Py5Shape.shininess()`` - to set the material properties of a ``Py5Shape`` object. + `Py5Shape.emissive()`, `Py5Shape.specular()`, and `Py5Shape.shininess()` to set + the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The ambient color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The ambient color setting will be applied to vertices added after the call to this method. """ pass @_convert_hex_color() def ambient(self, *args): - """Sets a ``Py5Shape`` object's ambient reflectance. + """Sets a `Py5Shape` object's ambient reflectance. Underlying Processing method: PShape.ambient @@ -442,16 +450,16 @@ def ambient(self, *args): Notes ----- - Sets a ``Py5Shape`` object's ambient reflectance. This is combined with the + Sets a `Py5Shape` object's ambient reflectance. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color mode, - setting ``ambient(255, 127, 0)``, would cause all the red light to reflect and + setting `ambient(255, 127, 0)`, would cause all the red light to reflect and half of the green light to reflect. Use in combination with - ``Py5Shape.emissive()``, ``Py5Shape.specular()``, and ``Py5Shape.shininess()`` - to set the material properties of a ``Py5Shape`` object. + `Py5Shape.emissive()`, `Py5Shape.specular()`, and `Py5Shape.shininess()` to set + the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The ambient color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The ambient color setting will be applied to vertices added after the call to this method. """ return self._instance.ambient(*args) @@ -459,7 +467,7 @@ def ambient(self, *args): @overload def apply_matrix(self, n00: float, n01: float, n02: float, n10: float, n11: float, n12: float, /) -> None: - """Apply a transformation matrix to a ``Py5Shape`` object. + """Apply a transformation matrix to a `Py5Shape` object. Underlying Processing method: PShape.applyMatrix @@ -529,15 +537,15 @@ def apply_matrix(self, n00: float, n01: float, n02: float, Notes ----- - Apply a transformation matrix to a ``Py5Shape`` object. This can be used to - scale, rotate, and translate a shape with one call. + Apply a transformation matrix to a `Py5Shape` object. This can be used to scale, + rotate, and translate a shape with one call. Making productive use of this method requires some knowledge of 2D or 3D transformation matrices, and perhaps some knowledge of Processing's source code. Transformations are cummulative and therefore will be applied on top of existing - transformations. Use ``Py5Shape.reset_matrix()`` to set the transformation - matrix to the identity matrix. + transformations. Use `Py5Shape.reset_matrix()` to set the transformation matrix + to the identity matrix. """ pass @@ -561,7 +569,7 @@ def apply_matrix( n32: float, n33: float, /) -> None: - """Apply a transformation matrix to a ``Py5Shape`` object. + """Apply a transformation matrix to a `Py5Shape` object. Underlying Processing method: PShape.applyMatrix @@ -631,21 +639,21 @@ def apply_matrix( Notes ----- - Apply a transformation matrix to a ``Py5Shape`` object. This can be used to - scale, rotate, and translate a shape with one call. + Apply a transformation matrix to a `Py5Shape` object. This can be used to scale, + rotate, and translate a shape with one call. Making productive use of this method requires some knowledge of 2D or 3D transformation matrices, and perhaps some knowledge of Processing's source code. Transformations are cummulative and therefore will be applied on top of existing - transformations. Use ``Py5Shape.reset_matrix()`` to set the transformation - matrix to the identity matrix. + transformations. Use `Py5Shape.reset_matrix()` to set the transformation matrix + to the identity matrix. """ pass @overload def apply_matrix(self, source: npt.NDArray[np.floating], /) -> None: - """Apply a transformation matrix to a ``Py5Shape`` object. + """Apply a transformation matrix to a `Py5Shape` object. Underlying Processing method: PShape.applyMatrix @@ -715,20 +723,20 @@ def apply_matrix(self, source: npt.NDArray[np.floating], /) -> None: Notes ----- - Apply a transformation matrix to a ``Py5Shape`` object. This can be used to - scale, rotate, and translate a shape with one call. + Apply a transformation matrix to a `Py5Shape` object. This can be used to scale, + rotate, and translate a shape with one call. Making productive use of this method requires some knowledge of 2D or 3D transformation matrices, and perhaps some knowledge of Processing's source code. Transformations are cummulative and therefore will be applied on top of existing - transformations. Use ``Py5Shape.reset_matrix()`` to set the transformation - matrix to the identity matrix. + transformations. Use `Py5Shape.reset_matrix()` to set the transformation matrix + to the identity matrix. """ pass def apply_matrix(self, *args): - """Apply a transformation matrix to a ``Py5Shape`` object. + """Apply a transformation matrix to a `Py5Shape` object. Underlying Processing method: PShape.applyMatrix @@ -798,51 +806,50 @@ def apply_matrix(self, *args): Notes ----- - Apply a transformation matrix to a ``Py5Shape`` object. This can be used to - scale, rotate, and translate a shape with one call. + Apply a transformation matrix to a `Py5Shape` object. This can be used to scale, + rotate, and translate a shape with one call. Making productive use of this method requires some knowledge of 2D or 3D transformation matrices, and perhaps some knowledge of Processing's source code. Transformations are cummulative and therefore will be applied on top of existing - transformations. Use ``Py5Shape.reset_matrix()`` to set the transformation - matrix to the identity matrix. + transformations. Use `Py5Shape.reset_matrix()` to set the transformation matrix + to the identity matrix. """ return self._instance.applyMatrix(*args) @_context_wrapper('end_contour') def begin_contour(self) -> None: - """Use the ``begin_contour()`` and ``Py5Shape.end_contour()`` methods to create - negative shapes within a ``Py5Shape`` object such as the center of the letter - 'O'. + """Use the `begin_contour()` and `Py5Shape.end_contour()` methods to create + negative shapes within a `Py5Shape` object such as the center of the letter 'O'. Underlying Processing method: PShape.beginContour Notes ----- - Use the ``begin_contour()`` and ``Py5Shape.end_contour()`` methods to create - negative shapes within a ``Py5Shape`` object such as the center of the letter - 'O'. The ``begin_contour()`` method begins recording vertices for the shape and - ``Py5Shape.end_contour()`` stops recording. The vertices that define a negative + Use the `begin_contour()` and `Py5Shape.end_contour()` methods to create + negative shapes within a `Py5Shape` object such as the center of the letter 'O'. + The `begin_contour()` method begins recording vertices for the shape and + `Py5Shape.end_contour()` stops recording. The vertices that define a negative shape must "wind" in the opposite direction from the exterior shape. First draw vertices for the exterior shape in clockwise order, then for internal shapes, draw vertices counterclockwise. - These methods can only be used within a ``Py5Shape.begin_shape()`` & - ``Py5Shape.end_shape()`` pair and transformations such as - ``Py5Shape.translate()``, ``Py5Shape.rotate()``, and ``Py5Shape.scale()`` do not - work within a ``begin_contour()`` & ``Py5Shape.end_contour()`` pair. It is also - not possible to use other shapes, such as ``ellipse()`` or ``rect()`` within. + These methods can only be used within a `Py5Shape.begin_shape()` & + `Py5Shape.end_shape()` pair and transformations such as `Py5Shape.translate()`, + `Py5Shape.rotate()`, and `Py5Shape.scale()` do not work within a + `begin_contour()` & `Py5Shape.end_contour()` pair. It is also not possible to + use other shapes, such as `ellipse()` or `rect()` within. This method can be used as a context manager to ensure that - ``Py5Shape.end_contour()`` always gets called, as shown in the second example. + `Py5Shape.end_contour()` always gets called, as shown in the second example. """ return self._instance.beginContour() @overload def begin_shape(self) -> None: - """This method is used to start a custom shape created with the ``create_shape()`` + """This method is used to start a custom shape created with the `create_shape()` function. Underlying Processing method: PShape.beginShape @@ -864,20 +871,20 @@ def begin_shape(self) -> None: Notes ----- - This method is used to start a custom shape created with the ``create_shape()`` - function. It's always and only used with ``create_shape()``. + This method is used to start a custom shape created with the `create_shape()` + function. It's always and only used with `create_shape()`. Drawing commands to a custom shape must always conclude with a call to the - ``Py5Shape.end_shape()`` method. This method can be used as a context manager to - ensure that ``Py5Shape.end_shape()`` always gets called, as shown in the second - example. Use ``Py5Shape.begin_closed_shape()`` to create a context manager that - will pass the ``CLOSE`` parameter to ``end_shape()``, closing the shape. + `Py5Shape.end_shape()` method. This method can be used as a context manager to + ensure that `Py5Shape.end_shape()` always gets called, as shown in the second + example. Use `Py5Shape.begin_closed_shape()` to create a context manager that + will pass the `CLOSE` parameter to `end_shape()`, closing the shape. """ pass @overload def begin_shape(self, kind: int, /) -> None: - """This method is used to start a custom shape created with the ``create_shape()`` + """This method is used to start a custom shape created with the `create_shape()` function. Underlying Processing method: PShape.beginShape @@ -899,20 +906,20 @@ def begin_shape(self, kind: int, /) -> None: Notes ----- - This method is used to start a custom shape created with the ``create_shape()`` - function. It's always and only used with ``create_shape()``. + This method is used to start a custom shape created with the `create_shape()` + function. It's always and only used with `create_shape()`. Drawing commands to a custom shape must always conclude with a call to the - ``Py5Shape.end_shape()`` method. This method can be used as a context manager to - ensure that ``Py5Shape.end_shape()`` always gets called, as shown in the second - example. Use ``Py5Shape.begin_closed_shape()`` to create a context manager that - will pass the ``CLOSE`` parameter to ``end_shape()``, closing the shape. + `Py5Shape.end_shape()` method. This method can be used as a context manager to + ensure that `Py5Shape.end_shape()` always gets called, as shown in the second + example. Use `Py5Shape.begin_closed_shape()` to create a context manager that + will pass the `CLOSE` parameter to `end_shape()`, closing the shape. """ pass @_context_wrapper('end_shape') def begin_shape(self, *args): - """This method is used to start a custom shape created with the ``create_shape()`` + """This method is used to start a custom shape created with the `create_shape()` function. Underlying Processing method: PShape.beginShape @@ -934,21 +941,21 @@ def begin_shape(self, *args): Notes ----- - This method is used to start a custom shape created with the ``create_shape()`` - function. It's always and only used with ``create_shape()``. + This method is used to start a custom shape created with the `create_shape()` + function. It's always and only used with `create_shape()`. Drawing commands to a custom shape must always conclude with a call to the - ``Py5Shape.end_shape()`` method. This method can be used as a context manager to - ensure that ``Py5Shape.end_shape()`` always gets called, as shown in the second - example. Use ``Py5Shape.begin_closed_shape()`` to create a context manager that - will pass the ``CLOSE`` parameter to ``end_shape()``, closing the shape. + `Py5Shape.end_shape()` method. This method can be used as a context manager to + ensure that `Py5Shape.end_shape()` always gets called, as shown in the second + example. Use `Py5Shape.begin_closed_shape()` to create a context manager that + will pass the `CLOSE` parameter to `end_shape()`, closing the shape. """ return self._instance.beginShape(*args) @overload def begin_closed_shape(self) -> None: """This method is used to start a custom closed shape created with the - ``create_shape()`` function. + `create_shape()` function. Underlying Processing method: PShape.beginShape @@ -970,23 +977,23 @@ def begin_closed_shape(self) -> None: ----- This method is used to start a custom closed shape created with the - ``create_shape()`` function. It's always and only used with ``create_shape()``. + `create_shape()` function. It's always and only used with `create_shape()`. This method should only be used as a context manager, as shown in the example. - When used as a context manager, this will ensure that ``Py5Shape.end_shape()`` - always gets called, just like when using ``Py5Shape.begin_shape()`` as a context - manager. The difference is that when exiting, the parameter ``CLOSE`` will be - passed to ``Py5Shape.end_shape()``, connecting the last vertex to the first. - This will close the shape. If this method were to be used not as a context - manager, it won't be able to close the shape by making the call to - ``Py5Shape.end_shape()``. + When used as a context manager, this will ensure that `Py5Shape.end_shape()` + always gets called, just like when using `Py5Shape.begin_shape()` as a context + manager. The difference is that when exiting, the parameter `CLOSE` will be + passed to `Py5Shape.end_shape()`, connecting the last vertex to the first. This + will close the shape. If this method were to be used not as a context manager, + it won't be able to close the shape by making the call to + `Py5Shape.end_shape()`. """ pass @overload def begin_closed_shape(self, kind: int, /) -> None: """This method is used to start a custom closed shape created with the - ``create_shape()`` function. + `create_shape()` function. Underlying Processing method: PShape.beginShape @@ -1008,23 +1015,23 @@ def begin_closed_shape(self, kind: int, /) -> None: ----- This method is used to start a custom closed shape created with the - ``create_shape()`` function. It's always and only used with ``create_shape()``. + `create_shape()` function. It's always and only used with `create_shape()`. This method should only be used as a context manager, as shown in the example. - When used as a context manager, this will ensure that ``Py5Shape.end_shape()`` - always gets called, just like when using ``Py5Shape.begin_shape()`` as a context - manager. The difference is that when exiting, the parameter ``CLOSE`` will be - passed to ``Py5Shape.end_shape()``, connecting the last vertex to the first. - This will close the shape. If this method were to be used not as a context - manager, it won't be able to close the shape by making the call to - ``Py5Shape.end_shape()``. + When used as a context manager, this will ensure that `Py5Shape.end_shape()` + always gets called, just like when using `Py5Shape.begin_shape()` as a context + manager. The difference is that when exiting, the parameter `CLOSE` will be + passed to `Py5Shape.end_shape()`, connecting the last vertex to the first. This + will close the shape. If this method were to be used not as a context manager, + it won't be able to close the shape by making the call to + `Py5Shape.end_shape()`. """ pass @_context_wrapper('end_shape', exit_attr_args=('CLOSE',)) def begin_closed_shape(self, *args): """This method is used to start a custom closed shape created with the - ``create_shape()`` function. + `create_shape()` function. Underlying Processing method: PShape.beginShape @@ -1046,21 +1053,21 @@ def begin_closed_shape(self, *args): ----- This method is used to start a custom closed shape created with the - ``create_shape()`` function. It's always and only used with ``create_shape()``. + `create_shape()` function. It's always and only used with `create_shape()`. This method should only be used as a context manager, as shown in the example. - When used as a context manager, this will ensure that ``Py5Shape.end_shape()`` - always gets called, just like when using ``Py5Shape.begin_shape()`` as a context - manager. The difference is that when exiting, the parameter ``CLOSE`` will be - passed to ``Py5Shape.end_shape()``, connecting the last vertex to the first. - This will close the shape. If this method were to be used not as a context - manager, it won't be able to close the shape by making the call to - ``Py5Shape.end_shape()``. + When used as a context manager, this will ensure that `Py5Shape.end_shape()` + always gets called, just like when using `Py5Shape.begin_shape()` as a context + manager. The difference is that when exiting, the parameter `CLOSE` will be + passed to `Py5Shape.end_shape()`, connecting the last vertex to the first. This + will close the shape. If this method were to be used not as a context manager, + it won't be able to close the shape by making the call to + `Py5Shape.end_shape()`. """ return self._instance.beginShape(*args) def bezier_detail(self, detail: int, /) -> None: - """Sets a ``Py5Shape`` object's resolution at which Beziers display. + """Sets a `Py5Shape` object's resolution at which Beziers display. Underlying Processing method: PShape.bezierDetail @@ -1073,23 +1080,22 @@ def bezier_detail(self, detail: int, /) -> None: Notes ----- - Sets a ``Py5Shape`` object's resolution at which Beziers display. The default + Sets a `Py5Shape` object's resolution at which Beziers display. The default value is 20. - Drawing 2D bezier curves requires using the ``P2D`` renderer and drawing 3D - bezier curves requires using the ``P3D`` renderer. When drawing directly with - ``Py5Shape`` objects, bezier curves do not work at all using the default - renderer. + Drawing 2D bezier curves requires using the `P2D` renderer and drawing 3D bezier + curves requires using the `P3D` renderer. When drawing directly with `Py5Shape` + objects, bezier curves do not work at all using the default renderer. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ return self._instance.bezierDetail(detail) @overload def bezier_vertex(self, x2: float, y2: float, x3: float, y3: float, x4: float, y4: float, /) -> None: - """Specifies a ``Py5Shape`` object's vertex coordinates for Bezier curves. + """Specifies a `Py5Shape` object's vertex coordinates for Bezier curves. Underlying Processing method: PShape.bezierVertex @@ -1134,26 +1140,25 @@ def bezier_vertex(self, x2: float, y2: float, x3: float, Notes ----- - Specifies a ``Py5Shape`` object's vertex coordinates for Bezier curves. Each - call to ``bezier_vertex()`` defines the position of two control points and one - anchor point of a Bezier curve, adding a new segment to a line or shape. The - first time ``bezier_vertex()`` is used within a ``Py5Shape.begin_shape()`` call, - it must be prefaced with a call to ``Py5Shape.vertex()`` to set the first anchor - point. This method must be used between ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` and only when there is no ``MODE`` parameter specified - to ``Py5Shape.begin_shape()``. + Specifies a `Py5Shape` object's vertex coordinates for Bezier curves. Each call + to `bezier_vertex()` defines the position of two control points and one anchor + point of a Bezier curve, adding a new segment to a line or shape. The first time + `bezier_vertex()` is used within a `Py5Shape.begin_shape()` call, it must be + prefaced with a call to `Py5Shape.vertex()` to set the first anchor point. This + method must be used between `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` + and only when there is no `MODE` parameter specified to + `Py5Shape.begin_shape()`. - Drawing 2D bezier curves requires using the ``P2D`` renderer and drawing 3D - bezier curves requires using the ``P3D`` renderer. When drawing directly with - ``Py5Shape`` objects, bezier curves do not work at all using the default - renderer. + Drawing 2D bezier curves requires using the `P2D` renderer and drawing 3D bezier + curves requires using the `P3D` renderer. When drawing directly with `Py5Shape` + objects, bezier curves do not work at all using the default renderer. """ pass @overload def bezier_vertex(self, x2: float, y2: float, z2: float, x3: float, y3: float, z3: float, x4: float, y4: float, z4: float, /) -> None: - """Specifies a ``Py5Shape`` object's vertex coordinates for Bezier curves. + """Specifies a `Py5Shape` object's vertex coordinates for Bezier curves. Underlying Processing method: PShape.bezierVertex @@ -1198,24 +1203,23 @@ def bezier_vertex(self, x2: float, y2: float, z2: float, x3: float, Notes ----- - Specifies a ``Py5Shape`` object's vertex coordinates for Bezier curves. Each - call to ``bezier_vertex()`` defines the position of two control points and one - anchor point of a Bezier curve, adding a new segment to a line or shape. The - first time ``bezier_vertex()`` is used within a ``Py5Shape.begin_shape()`` call, - it must be prefaced with a call to ``Py5Shape.vertex()`` to set the first anchor - point. This method must be used between ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` and only when there is no ``MODE`` parameter specified - to ``Py5Shape.begin_shape()``. + Specifies a `Py5Shape` object's vertex coordinates for Bezier curves. Each call + to `bezier_vertex()` defines the position of two control points and one anchor + point of a Bezier curve, adding a new segment to a line or shape. The first time + `bezier_vertex()` is used within a `Py5Shape.begin_shape()` call, it must be + prefaced with a call to `Py5Shape.vertex()` to set the first anchor point. This + method must be used between `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` + and only when there is no `MODE` parameter specified to + `Py5Shape.begin_shape()`. - Drawing 2D bezier curves requires using the ``P2D`` renderer and drawing 3D - bezier curves requires using the ``P3D`` renderer. When drawing directly with - ``Py5Shape`` objects, bezier curves do not work at all using the default - renderer. + Drawing 2D bezier curves requires using the `P2D` renderer and drawing 3D bezier + curves requires using the `P3D` renderer. When drawing directly with `Py5Shape` + objects, bezier curves do not work at all using the default renderer. """ pass def bezier_vertex(self, *args): - """Specifies a ``Py5Shape`` object's vertex coordinates for Bezier curves. + """Specifies a `Py5Shape` object's vertex coordinates for Bezier curves. Underlying Processing method: PShape.bezierVertex @@ -1260,25 +1264,24 @@ def bezier_vertex(self, *args): Notes ----- - Specifies a ``Py5Shape`` object's vertex coordinates for Bezier curves. Each - call to ``bezier_vertex()`` defines the position of two control points and one - anchor point of a Bezier curve, adding a new segment to a line or shape. The - first time ``bezier_vertex()`` is used within a ``Py5Shape.begin_shape()`` call, - it must be prefaced with a call to ``Py5Shape.vertex()`` to set the first anchor - point. This method must be used between ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` and only when there is no ``MODE`` parameter specified - to ``Py5Shape.begin_shape()``. + Specifies a `Py5Shape` object's vertex coordinates for Bezier curves. Each call + to `bezier_vertex()` defines the position of two control points and one anchor + point of a Bezier curve, adding a new segment to a line or shape. The first time + `bezier_vertex()` is used within a `Py5Shape.begin_shape()` call, it must be + prefaced with a call to `Py5Shape.vertex()` to set the first anchor point. This + method must be used between `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` + and only when there is no `MODE` parameter specified to + `Py5Shape.begin_shape()`. - Drawing 2D bezier curves requires using the ``P2D`` renderer and drawing 3D - bezier curves requires using the ``P3D`` renderer. When drawing directly with - ``Py5Shape`` objects, bezier curves do not work at all using the default - renderer. + Drawing 2D bezier curves requires using the `P2D` renderer and drawing 3D bezier + curves requires using the `P3D` renderer. When drawing directly with `Py5Shape` + objects, bezier curves do not work at all using the default renderer. """ return self._instance.bezierVertex(*args) def contains(self, x: float, y: float, /) -> bool: """Boolean value reflecting if the given coordinates are or are not contained - within the ``Py5Shape`` object. + within the `Py5Shape` object. Underlying Processing method: PShape.contains @@ -1295,20 +1298,20 @@ def contains(self, x: float, y: float, /) -> bool: ----- Boolean value reflecting if the given coordinates are or are not contained - within the ``Py5Shape`` object. This method will only work for a ``Py5Shape`` - object that is a ``PATH`` shape or a ``GROUP`` of ``PATH`` shapes. Use - ``Py5Shape.get_family()`` to determine how a ``Py5Shape`` object was defined. + within the `Py5Shape` object. This method will only work for a `Py5Shape` object + that is a `PATH` shape or a `GROUP` of `PATH` shapes. Use + `Py5Shape.get_family()` to determine how a `Py5Shape` object was defined. This method uses a coordinate system that is unique to the shape and how the paths were created. To get the range of relevant coordinates, start by finding - the minimum and maximum values for the vertices using - ``Py5Shape.get_vertex_x()`` and ``Py5Shape.get_vertex_y()``. Do not use - ``Py5Shape.get_width()`` or ``Py5Shape.get_height()``. + the minimum and maximum values for the vertices using `Py5Shape.get_vertex_x()` + and `Py5Shape.get_vertex_y()`. Do not use `Py5Shape.get_width()` or + `Py5Shape.get_height()`. """ return self._instance.contains(x, y) def curve_detail(self, detail: int, /) -> None: - """Sets the resolution at which a ``Py5Shape`` object's curves display. + """Sets the resolution at which a `Py5Shape` object's curves display. Underlying Processing method: PShape.curveDetail @@ -1321,21 +1324,21 @@ def curve_detail(self, detail: int, /) -> None: Notes ----- - Sets the resolution at which a ``Py5Shape`` object's curves display. The default + Sets the resolution at which a `Py5Shape` object's curves display. The default value is 20. - Drawing 2D curves requires using the ``P2D`` renderer and drawing 3D curves - requires using the ``P3D`` renderer. When drawing directly with ``Py5Shape`` + Drawing 2D curves requires using the `P2D` renderer and drawing 3D curves + requires using the `P3D` renderer. When drawing directly with `Py5Shape` objects, curves do not work at all using the default renderer. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ return self._instance.curveDetail(detail) def curve_tightness(self, tightness: float, /) -> None: - """Modifies the quality of a ``Py5Shape`` object's forms created with - ``Py5Shape.curve_vertex()``. + """Modifies the quality of a `Py5Shape` object's forms created with + `Py5Shape.curve_vertex()`. Underlying Processing method: PShape.curveTightness @@ -1348,26 +1351,26 @@ def curve_tightness(self, tightness: float, /) -> None: Notes ----- - Modifies the quality of a ``Py5Shape`` object's forms created with - ``Py5Shape.curve_vertex()``. The parameter ``tightness`` determines how the - curve fits to the vertex points. The value 0.0 is the default value for - ``tightness`` (this value defines the curves to be Catmull-Rom splines) and the - value 1.0 connects all the points with straight lines. Values within the range - -5.0 and 5.0 will deform the curves but will leave them recognizable and as - values increase in magnitude, they will continue to deform. + Modifies the quality of a `Py5Shape` object's forms created with + `Py5Shape.curve_vertex()`. The parameter `tightness` determines how the curve + fits to the vertex points. The value 0.0 is the default value for `tightness` + (this value defines the curves to be Catmull-Rom splines) and the value 1.0 + connects all the points with straight lines. Values within the range -5.0 and + 5.0 will deform the curves but will leave them recognizable and as values + increase in magnitude, they will continue to deform. - Drawing 2D curves requires using the ``P2D`` renderer and drawing 3D curves - requires using the ``P3D`` renderer. When drawing directly with ``Py5Shape`` + Drawing 2D curves requires using the `P2D` renderer and drawing 3D curves + requires using the `P3D` renderer. When drawing directly with `Py5Shape` objects, curves do not work at all using the default renderer. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ return self._instance.curveTightness(tightness) @overload def curve_vertex(self, x: float, y: float, /) -> None: - """Specifies a ``Py5Shape`` object's vertex coordinates for curves. + """Specifies a `Py5Shape` object's vertex coordinates for curves. Underlying Processing method: PShape.curveVertex @@ -1394,28 +1397,27 @@ def curve_vertex(self, x: float, y: float, /) -> None: Notes ----- - Specifies a ``Py5Shape`` object's vertex coordinates for curves. This method may - only be used between ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` and - only when there is no ``MODE`` parameter specified to - ``Py5Shape.begin_shape()``. The first and last points in a series of - ``curve_vertex()`` lines will be used to guide the beginning and end of the - curve. A minimum of four points is required to draw a tiny curve between the - second and third points. Adding a fifth point with ``curve_vertex()`` will draw - the curve between the second, third, and fourth points. The ``curve_vertex()`` - method is an implementation of Catmull-Rom splines. + Specifies a `Py5Shape` object's vertex coordinates for curves. This method may + only be used between `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` and + only when there is no `MODE` parameter specified to `Py5Shape.begin_shape()`. + The first and last points in a series of `curve_vertex()` lines will be used to + guide the beginning and end of the curve. A minimum of four points is required + to draw a tiny curve between the second and third points. Adding a fifth point + with `curve_vertex()` will draw the curve between the second, third, and fourth + points. The `curve_vertex()` method is an implementation of Catmull-Rom splines. - Drawing 2D curves requires using the ``P2D`` renderer and drawing 3D curves - requires using the ``P3D`` renderer. When drawing directly with ``Py5Shape`` + Drawing 2D curves requires using the `P2D` renderer and drawing 3D curves + requires using the `P3D` renderer. When drawing directly with `Py5Shape` objects, curves do not work at all using the default renderer. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ pass @overload def curve_vertex(self, x: float, y: float, z: float, /) -> None: - """Specifies a ``Py5Shape`` object's vertex coordinates for curves. + """Specifies a `Py5Shape` object's vertex coordinates for curves. Underlying Processing method: PShape.curveVertex @@ -1442,27 +1444,26 @@ def curve_vertex(self, x: float, y: float, z: float, /) -> None: Notes ----- - Specifies a ``Py5Shape`` object's vertex coordinates for curves. This method may - only be used between ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` and - only when there is no ``MODE`` parameter specified to - ``Py5Shape.begin_shape()``. The first and last points in a series of - ``curve_vertex()`` lines will be used to guide the beginning and end of the - curve. A minimum of four points is required to draw a tiny curve between the - second and third points. Adding a fifth point with ``curve_vertex()`` will draw - the curve between the second, third, and fourth points. The ``curve_vertex()`` - method is an implementation of Catmull-Rom splines. + Specifies a `Py5Shape` object's vertex coordinates for curves. This method may + only be used between `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` and + only when there is no `MODE` parameter specified to `Py5Shape.begin_shape()`. + The first and last points in a series of `curve_vertex()` lines will be used to + guide the beginning and end of the curve. A minimum of four points is required + to draw a tiny curve between the second and third points. Adding a fifth point + with `curve_vertex()` will draw the curve between the second, third, and fourth + points. The `curve_vertex()` method is an implementation of Catmull-Rom splines. - Drawing 2D curves requires using the ``P2D`` renderer and drawing 3D curves - requires using the ``P3D`` renderer. When drawing directly with ``Py5Shape`` + Drawing 2D curves requires using the `P2D` renderer and drawing 3D curves + requires using the `P3D` renderer. When drawing directly with `Py5Shape` objects, curves do not work at all using the default renderer. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ pass def curve_vertex(self, *args): - """Specifies a ``Py5Shape`` object's vertex coordinates for curves. + """Specifies a `Py5Shape` object's vertex coordinates for curves. Underlying Processing method: PShape.curveVertex @@ -1489,22 +1490,21 @@ def curve_vertex(self, *args): Notes ----- - Specifies a ``Py5Shape`` object's vertex coordinates for curves. This method may - only be used between ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` and - only when there is no ``MODE`` parameter specified to - ``Py5Shape.begin_shape()``. The first and last points in a series of - ``curve_vertex()`` lines will be used to guide the beginning and end of the - curve. A minimum of four points is required to draw a tiny curve between the - second and third points. Adding a fifth point with ``curve_vertex()`` will draw - the curve between the second, third, and fourth points. The ``curve_vertex()`` - method is an implementation of Catmull-Rom splines. + Specifies a `Py5Shape` object's vertex coordinates for curves. This method may + only be used between `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` and + only when there is no `MODE` parameter specified to `Py5Shape.begin_shape()`. + The first and last points in a series of `curve_vertex()` lines will be used to + guide the beginning and end of the curve. A minimum of four points is required + to draw a tiny curve between the second and third points. Adding a fifth point + with `curve_vertex()` will draw the curve between the second, third, and fourth + points. The `curve_vertex()` method is an implementation of Catmull-Rom splines. - Drawing 2D curves requires using the ``P2D`` renderer and drawing 3D curves - requires using the ``P3D`` renderer. When drawing directly with ``Py5Shape`` + Drawing 2D curves requires using the `P2D` renderer and drawing 3D curves + requires using the `P3D` renderer. When drawing directly with `Py5Shape` objects, curves do not work at all using the default renderer. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ return self._instance.curveVertex(*args) @@ -1523,7 +1523,7 @@ def disable_style(self) -> None: @overload def emissive(self, gray: float, /) -> None: - """Sets the emissive color of a ``Py5Shape`` object's material. + """Sets the emissive color of a `Py5Shape` object's material. Underlying Processing method: PShape.emissive @@ -1557,20 +1557,19 @@ def emissive(self, gray: float, /) -> None: Notes ----- - Sets the emissive color of a ``Py5Shape`` object's material. Use in combination - with ``Py5Shape.ambient()``, ``Py5Shape.specular()``, and - ``Py5Shape.shininess()`` to set the material properties of a ``Py5Shape`` - object. + Sets the emissive color of a `Py5Shape` object's material. Use in combination + with `Py5Shape.ambient()`, `Py5Shape.specular()`, and `Py5Shape.shininess()` to + set the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The emissive color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The emissive color setting will be applied to vertices added after the call to this method. """ pass @overload def emissive(self, x: float, y: float, z: float, /) -> None: - """Sets the emissive color of a ``Py5Shape`` object's material. + """Sets the emissive color of a `Py5Shape` object's material. Underlying Processing method: PShape.emissive @@ -1604,20 +1603,19 @@ def emissive(self, x: float, y: float, z: float, /) -> None: Notes ----- - Sets the emissive color of a ``Py5Shape`` object's material. Use in combination - with ``Py5Shape.ambient()``, ``Py5Shape.specular()``, and - ``Py5Shape.shininess()`` to set the material properties of a ``Py5Shape`` - object. + Sets the emissive color of a `Py5Shape` object's material. Use in combination + with `Py5Shape.ambient()`, `Py5Shape.specular()`, and `Py5Shape.shininess()` to + set the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The emissive color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The emissive color setting will be applied to vertices added after the call to this method. """ pass @overload def emissive(self, rgb: int, /) -> None: - """Sets the emissive color of a ``Py5Shape`` object's material. + """Sets the emissive color of a `Py5Shape` object's material. Underlying Processing method: PShape.emissive @@ -1651,20 +1649,19 @@ def emissive(self, rgb: int, /) -> None: Notes ----- - Sets the emissive color of a ``Py5Shape`` object's material. Use in combination - with ``Py5Shape.ambient()``, ``Py5Shape.specular()``, and - ``Py5Shape.shininess()`` to set the material properties of a ``Py5Shape`` - object. + Sets the emissive color of a `Py5Shape` object's material. Use in combination + with `Py5Shape.ambient()`, `Py5Shape.specular()`, and `Py5Shape.shininess()` to + set the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The emissive color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The emissive color setting will be applied to vertices added after the call to this method. """ pass @_convert_hex_color() def emissive(self, *args): - """Sets the emissive color of a ``Py5Shape`` object's material. + """Sets the emissive color of a `Py5Shape` object's material. Underlying Processing method: PShape.emissive @@ -1698,13 +1695,12 @@ def emissive(self, *args): Notes ----- - Sets the emissive color of a ``Py5Shape`` object's material. Use in combination - with ``Py5Shape.ambient()``, ``Py5Shape.specular()``, and - ``Py5Shape.shininess()`` to set the material properties of a ``Py5Shape`` - object. + Sets the emissive color of a `Py5Shape` object's material. Use in combination + with `Py5Shape.ambient()`, `Py5Shape.specular()`, and `Py5Shape.shininess()` to + set the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The emissive color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The emissive color setting will be applied to vertices added after the call to this method. """ return self._instance.emissive(*args) @@ -1723,35 +1719,34 @@ def enable_style(self) -> None: return self._instance.enableStyle() def end_contour(self) -> None: - """Use the ``Py5Shape.begin_contour()`` and ``end_contour()`` methods to create - negative shapes within a ``Py5Shape`` object such as the center of the letter - 'O'. + """Use the `Py5Shape.begin_contour()` and `end_contour()` methods to create + negative shapes within a `Py5Shape` object such as the center of the letter 'O'. Underlying Processing method: PShape.endContour Notes ----- - Use the ``Py5Shape.begin_contour()`` and ``end_contour()`` methods to create - negative shapes within a ``Py5Shape`` object such as the center of the letter - 'O'. The ``Py5Shape.begin_contour()`` method begins recording vertices for the - shape and ``end_contour()`` stops recording. The vertices that define a negative - shape must "wind" in the opposite direction from the exterior shape. First draw + Use the `Py5Shape.begin_contour()` and `end_contour()` methods to create + negative shapes within a `Py5Shape` object such as the center of the letter 'O'. + The `Py5Shape.begin_contour()` method begins recording vertices for the shape + and `end_contour()` stops recording. The vertices that define a negative shape + must "wind" in the opposite direction from the exterior shape. First draw vertices for the exterior shape in clockwise order, then for internal shapes, draw vertices counterclockwise. - These methods can only be used within a ``Py5Shape.begin_shape()`` & - ``Py5Shape.end_shape()`` pair and transformations such as - ``Py5Shape.translate()``, ``Py5Shape.rotate()``, and ``Py5Shape.scale()`` do not - work within a ``Py5Shape.begin_contour()`` & ``end_contour()`` pair. It is also - not possible to use other shapes, such as ``ellipse()`` or ``rect()`` within. + These methods can only be used within a `Py5Shape.begin_shape()` & + `Py5Shape.end_shape()` pair and transformations such as `Py5Shape.translate()`, + `Py5Shape.rotate()`, and `Py5Shape.scale()` do not work within a + `Py5Shape.begin_contour()` & `end_contour()` pair. It is also not possible to + use other shapes, such as `ellipse()` or `rect()` within. """ return self._instance.endContour() @overload def end_shape(self) -> None: - """This method is used to complete a custom shape created with the - ``create_shape()`` function. + """This method is used to complete a custom shape created with the `create_shape()` + function. Underlying Processing method: PShape.endShape @@ -1772,15 +1767,15 @@ def end_shape(self) -> None: Notes ----- - This method is used to complete a custom shape created with the - ``create_shape()`` function. It's always and only used with ``create_shape()``. + This method is used to complete a custom shape created with the `create_shape()` + function. It's always and only used with `create_shape()`. """ pass @overload def end_shape(self, mode: int, /) -> None: - """This method is used to complete a custom shape created with the - ``create_shape()`` function. + """This method is used to complete a custom shape created with the `create_shape()` + function. Underlying Processing method: PShape.endShape @@ -1801,14 +1796,14 @@ def end_shape(self, mode: int, /) -> None: Notes ----- - This method is used to complete a custom shape created with the - ``create_shape()`` function. It's always and only used with ``create_shape()``. + This method is used to complete a custom shape created with the `create_shape()` + function. It's always and only used with `create_shape()`. """ pass def end_shape(self, *args): - """This method is used to complete a custom shape created with the - ``create_shape()`` function. + """This method is used to complete a custom shape created with the `create_shape()` + function. Underlying Processing method: PShape.endShape @@ -1829,14 +1824,14 @@ def end_shape(self, *args): Notes ----- - This method is used to complete a custom shape created with the - ``create_shape()`` function. It's always and only used with ``create_shape()``. + This method is used to complete a custom shape created with the `create_shape()` + function. It's always and only used with `create_shape()`. """ return self._instance.endShape(*args) @overload def fill(self, gray: float, /) -> None: - """Sets the color used to fill the ``Py5Shape`` object. + """Sets the color used to fill the `Py5Shape` object. Underlying Processing method: PShape.fill @@ -1879,42 +1874,41 @@ def fill(self, gray: float, /) -> None: Notes ----- - Sets the color used to fill the ``Py5Shape`` object. For example, if you run - ``fill(204, 102, 0)``, the shape will be filled with orange. This color is - either specified in terms of the ``RGB`` or ``HSB`` color depending on the - current ``color_mode()``. The default color space is ``RGB``, with each value in - the range from 0 to 255. + Sets the color used to fill the `Py5Shape` object. For example, if you run + `fill(204, 102, 0)`, the shape will be filled with orange. This color is either + specified in terms of the `RGB` or `HSB` color depending on the current + `color_mode()`. The default color space is `RGB`, with each value in the range + from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of a ``Py5Shape`` object's image or a texture, use - ``Py5Shape.tint()``. + To change the color of a `Py5Shape` object's image or a texture, use + `Py5Shape.tint()`. """ pass @overload def fill(self, gray: float, alpha: float, /) -> None: - """Sets the color used to fill the ``Py5Shape`` object. + """Sets the color used to fill the `Py5Shape` object. Underlying Processing method: PShape.fill @@ -1957,42 +1951,41 @@ def fill(self, gray: float, alpha: float, /) -> None: Notes ----- - Sets the color used to fill the ``Py5Shape`` object. For example, if you run - ``fill(204, 102, 0)``, the shape will be filled with orange. This color is - either specified in terms of the ``RGB`` or ``HSB`` color depending on the - current ``color_mode()``. The default color space is ``RGB``, with each value in - the range from 0 to 255. + Sets the color used to fill the `Py5Shape` object. For example, if you run + `fill(204, 102, 0)`, the shape will be filled with orange. This color is either + specified in terms of the `RGB` or `HSB` color depending on the current + `color_mode()`. The default color space is `RGB`, with each value in the range + from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of a ``Py5Shape`` object's image or a texture, use - ``Py5Shape.tint()``. + To change the color of a `Py5Shape` object's image or a texture, use + `Py5Shape.tint()`. """ pass @overload def fill(self, x: float, y: float, z: float, /) -> None: - """Sets the color used to fill the ``Py5Shape`` object. + """Sets the color used to fill the `Py5Shape` object. Underlying Processing method: PShape.fill @@ -2035,42 +2028,41 @@ def fill(self, x: float, y: float, z: float, /) -> None: Notes ----- - Sets the color used to fill the ``Py5Shape`` object. For example, if you run - ``fill(204, 102, 0)``, the shape will be filled with orange. This color is - either specified in terms of the ``RGB`` or ``HSB`` color depending on the - current ``color_mode()``. The default color space is ``RGB``, with each value in - the range from 0 to 255. + Sets the color used to fill the `Py5Shape` object. For example, if you run + `fill(204, 102, 0)`, the shape will be filled with orange. This color is either + specified in terms of the `RGB` or `HSB` color depending on the current + `color_mode()`. The default color space is `RGB`, with each value in the range + from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of a ``Py5Shape`` object's image or a texture, use - ``Py5Shape.tint()``. + To change the color of a `Py5Shape` object's image or a texture, use + `Py5Shape.tint()`. """ pass @overload def fill(self, x: float, y: float, z: float, a: float, /) -> None: - """Sets the color used to fill the ``Py5Shape`` object. + """Sets the color used to fill the `Py5Shape` object. Underlying Processing method: PShape.fill @@ -2113,42 +2105,41 @@ def fill(self, x: float, y: float, z: float, a: float, /) -> None: Notes ----- - Sets the color used to fill the ``Py5Shape`` object. For example, if you run - ``fill(204, 102, 0)``, the shape will be filled with orange. This color is - either specified in terms of the ``RGB`` or ``HSB`` color depending on the - current ``color_mode()``. The default color space is ``RGB``, with each value in - the range from 0 to 255. + Sets the color used to fill the `Py5Shape` object. For example, if you run + `fill(204, 102, 0)`, the shape will be filled with orange. This color is either + specified in terms of the `RGB` or `HSB` color depending on the current + `color_mode()`. The default color space is `RGB`, with each value in the range + from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of a ``Py5Shape`` object's image or a texture, use - ``Py5Shape.tint()``. + To change the color of a `Py5Shape` object's image or a texture, use + `Py5Shape.tint()`. """ pass @overload def fill(self, rgb: int, /) -> None: - """Sets the color used to fill the ``Py5Shape`` object. + """Sets the color used to fill the `Py5Shape` object. Underlying Processing method: PShape.fill @@ -2191,42 +2182,41 @@ def fill(self, rgb: int, /) -> None: Notes ----- - Sets the color used to fill the ``Py5Shape`` object. For example, if you run - ``fill(204, 102, 0)``, the shape will be filled with orange. This color is - either specified in terms of the ``RGB`` or ``HSB`` color depending on the - current ``color_mode()``. The default color space is ``RGB``, with each value in - the range from 0 to 255. + Sets the color used to fill the `Py5Shape` object. For example, if you run + `fill(204, 102, 0)`, the shape will be filled with orange. This color is either + specified in terms of the `RGB` or `HSB` color depending on the current + `color_mode()`. The default color space is `RGB`, with each value in the range + from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of a ``Py5Shape`` object's image or a texture, use - ``Py5Shape.tint()``. + To change the color of a `Py5Shape` object's image or a texture, use + `Py5Shape.tint()`. """ pass @overload def fill(self, rgb: int, alpha: float, /) -> None: - """Sets the color used to fill the ``Py5Shape`` object. + """Sets the color used to fill the `Py5Shape` object. Underlying Processing method: PShape.fill @@ -2269,42 +2259,41 @@ def fill(self, rgb: int, alpha: float, /) -> None: Notes ----- - Sets the color used to fill the ``Py5Shape`` object. For example, if you run - ``fill(204, 102, 0)``, the shape will be filled with orange. This color is - either specified in terms of the ``RGB`` or ``HSB`` color depending on the - current ``color_mode()``. The default color space is ``RGB``, with each value in - the range from 0 to 255. + Sets the color used to fill the `Py5Shape` object. For example, if you run + `fill(204, 102, 0)`, the shape will be filled with orange. This color is either + specified in terms of the `RGB` or `HSB` color depending on the current + `color_mode()`. The default color space is `RGB`, with each value in the range + from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of a ``Py5Shape`` object's image or a texture, use - ``Py5Shape.tint()``. + To change the color of a `Py5Shape` object's image or a texture, use + `Py5Shape.tint()`. """ pass @_convert_hex_color() def fill(self, *args): - """Sets the color used to fill the ``Py5Shape`` object. + """Sets the color used to fill the `Py5Shape` object. Underlying Processing method: PShape.fill @@ -2347,43 +2336,42 @@ def fill(self, *args): Notes ----- - Sets the color used to fill the ``Py5Shape`` object. For example, if you run - ``fill(204, 102, 0)``, the shape will be filled with orange. This color is - either specified in terms of the ``RGB`` or ``HSB`` color depending on the - current ``color_mode()``. The default color space is ``RGB``, with each value in - the range from 0 to 255. + Sets the color used to fill the `Py5Shape` object. For example, if you run + `fill(204, 102, 0)`, the shape will be filled with orange. This color is either + specified in terms of the `RGB` or `HSB` color depending on the current + `color_mode()`. The default color space is `RGB`, with each value in the range + from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of a ``Py5Shape`` object's image or a texture, use - ``Py5Shape.tint()``. + To change the color of a `Py5Shape` object's image or a texture, use + `Py5Shape.tint()`. """ return self._instance.fill(*args) @_return_py5shape def find_child(self, target: str, /) -> Py5Shape: - """Find a target ``Py5Shape`` object from anywhere within a ``Py5Shape`` object - that is defined as a ``GROUP``. + """Find a target `Py5Shape` object from anywhere within a `Py5Shape` object that is + defined as a `GROUP`. Underlying Processing method: PShape.findChild @@ -2396,15 +2384,15 @@ def find_child(self, target: str, /) -> Py5Shape: Notes ----- - Find a target ``Py5Shape`` object from anywhere within a ``Py5Shape`` object - that is defined as a ``GROUP``. This is similar to ``Py5Shape.get_child()`` in - that it locates a child ``Py5Shape`` object, except that it can start the search - from another child shape instead of the parent. + Find a target `Py5Shape` object from anywhere within a `Py5Shape` object that is + defined as a `GROUP`. This is similar to `Py5Shape.get_child()` in that it + locates a child `Py5Shape` object, except that it can start the search from + another child shape instead of the parent. """ return self._instance.findChild(target) def get_ambient(self, index: int, /) -> int: - """Get the ambient reflectance setting for one of a ``Py5Shape`` object's vertices. + """Get the ambient reflectance setting for one of a `Py5Shape` object's vertices. Underlying Processing method: PShape.getAmbient @@ -2417,19 +2405,19 @@ def get_ambient(self, index: int, /) -> int: Notes ----- - Get the ambient reflectance setting for one of a ``Py5Shape`` object's vertices. + Get the ambient reflectance setting for one of a `Py5Shape` object's vertices. This setting is combined with the ambient light component of the environment. - Use ``Py5Shape.set_ambient()`` to change the setting. + Use `Py5Shape.set_ambient()` to change the setting. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getAmbient(index) @overload def get_child(self, index: int, /) -> Py5Shape: - """Extracts a child ``Py5Shape`` object from a parent ``Py5Shape`` object that is - defined as a ``GROUP``. + """Extracts a child `Py5Shape` object from a parent `Py5Shape` object that is + defined as a `GROUP`. Underlying Processing method: PShape.getChild @@ -2453,17 +2441,17 @@ def get_child(self, index: int, /) -> Py5Shape: Notes ----- - Extracts a child ``Py5Shape`` object from a parent ``Py5Shape`` object that is - defined as a ``GROUP``. Specify the name of the shape with the ``target`` - parameter, or use the index with the ``index`` parameter. The shape is returned - as a ``Py5Shape`` object, or ``None`` is returned if there is an error. + Extracts a child `Py5Shape` object from a parent `Py5Shape` object that is + defined as a `GROUP`. Specify the name of the shape with the `target` parameter, + or use the index with the `index` parameter. The shape is returned as a + `Py5Shape` object, or `None` is returned if there is an error. """ pass @overload def get_child(self, target: str, /) -> Py5Shape: - """Extracts a child ``Py5Shape`` object from a parent ``Py5Shape`` object that is - defined as a ``GROUP``. + """Extracts a child `Py5Shape` object from a parent `Py5Shape` object that is + defined as a `GROUP`. Underlying Processing method: PShape.getChild @@ -2487,17 +2475,17 @@ def get_child(self, target: str, /) -> Py5Shape: Notes ----- - Extracts a child ``Py5Shape`` object from a parent ``Py5Shape`` object that is - defined as a ``GROUP``. Specify the name of the shape with the ``target`` - parameter, or use the index with the ``index`` parameter. The shape is returned - as a ``Py5Shape`` object, or ``None`` is returned if there is an error. + Extracts a child `Py5Shape` object from a parent `Py5Shape` object that is + defined as a `GROUP`. Specify the name of the shape with the `target` parameter, + or use the index with the `index` parameter. The shape is returned as a + `Py5Shape` object, or `None` is returned if there is an error. """ pass @_return_py5shape def get_child(self, *args): - """Extracts a child ``Py5Shape`` object from a parent ``Py5Shape`` object that is - defined as a ``GROUP``. + """Extracts a child `Py5Shape` object from a parent `Py5Shape` object that is + defined as a `GROUP`. Underlying Processing method: PShape.getChild @@ -2521,28 +2509,28 @@ def get_child(self, *args): Notes ----- - Extracts a child ``Py5Shape`` object from a parent ``Py5Shape`` object that is - defined as a ``GROUP``. Specify the name of the shape with the ``target`` - parameter, or use the index with the ``index`` parameter. The shape is returned - as a ``Py5Shape`` object, or ``None`` is returned if there is an error. + Extracts a child `Py5Shape` object from a parent `Py5Shape` object that is + defined as a `GROUP`. Specify the name of the shape with the `target` parameter, + or use the index with the `index` parameter. The shape is returned as a + `Py5Shape` object, or `None` is returned if there is an error. """ return self._instance.getChild(*args) def get_child_count(self) -> int: - """Returns the number of children within the ``Py5Shape`` object. + """Returns the number of children within the `Py5Shape` object. Underlying Processing method: PShape.getChildCount Notes ----- - Returns the number of children within the ``Py5Shape`` object. + Returns the number of children within the `Py5Shape` object. """ return self._instance.getChildCount() def get_child_index(self, who: Py5Shape, /) -> int: - """Get a child ``Py5Shape`` object's index from a parent ``Py5Shape`` object that - is defined as a ``GROUP``. + """Get a child `Py5Shape` object's index from a parent `Py5Shape` object that is + defined as a `GROUP`. Underlying Processing method: PShape.getChildIndex @@ -2555,45 +2543,45 @@ def get_child_index(self, who: Py5Shape, /) -> int: Notes ----- - Get a child ``Py5Shape`` object's index from a parent ``Py5Shape`` object that - is defined as a ``GROUP``. Inside Processing, a group ``Py5Shape`` object is an - ordered list of child shapes. This method will retrieve the index for a - particular child in that ordered list. That index value is useful when using - other methods such as ``Py5Shape.get_child()`` or ``Py5Shape.remove_child()``. + Get a child `Py5Shape` object's index from a parent `Py5Shape` object that is + defined as a `GROUP`. Inside Processing, a group `Py5Shape` object is an ordered + list of child shapes. This method will retrieve the index for a particular child + in that ordered list. That index value is useful when using other methods such + as `Py5Shape.get_child()` or `Py5Shape.remove_child()`. """ return self._instance.getChildIndex(who) @_return_list_py5shapes def get_children(self) -> list[Py5Shape]: - """Get the children of a ``Py5Shape`` object as a list of ``Py5Shape`` objects. + """Get the children of a `Py5Shape` object as a list of `Py5Shape` objects. Underlying Processing method: PShape.getChildren Notes ----- - Get the children of a ``Py5Shape`` object as a list of ``Py5Shape`` objects. - When Processing loads shape objects, it may create a hierarchy of ``Py5Shape`` - objects, depending on the organization of the source data file. This method will - retrieve the list of Py5Shapes that are the child objects to a given object. + Get the children of a `Py5Shape` object as a list of `Py5Shape` objects. When + Processing loads shape objects, it may create a hierarchy of `Py5Shape` objects, + depending on the organization of the source data file. This method will retrieve + the list of Py5Shapes that are the child objects to a given object. """ return self._instance.getChildren() def get_depth(self) -> float: - """Get the ``Py5Shape`` object's depth. + """Get the `Py5Shape` object's depth. Underlying Processing method: PShape.getDepth Notes ----- - Get the ``Py5Shape`` object's depth. This method only makes sense when using the - ``P3D`` renderer. It will return 0 when using default renderer. + Get the `Py5Shape` object's depth. This method only makes sense when using the + `P3D` renderer. It will return 0 when using default renderer. """ return self._instance.getDepth() def get_emissive(self, index: int, /) -> int: - """Get the emissive color setting for one of a ``Py5Shape`` object's vertices. + """Get the emissive color setting for one of a `Py5Shape` object's vertices. Underlying Processing method: PShape.getEmissive @@ -2606,11 +2594,11 @@ def get_emissive(self, index: int, /) -> int: Notes ----- - Get the emissive color setting for one of a ``Py5Shape`` object's vertices. Use - ``Py5Shape.set_emissive()`` to change the setting. + Get the emissive color setting for one of a `Py5Shape` object's vertices. Use + `Py5Shape.set_emissive()` to change the setting. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getEmissive(index) @@ -2627,7 +2615,7 @@ def get_family(self) -> int: return self._instance.getFamily() def get_fill(self, index: int, /) -> int: - """Gets the fill color used for a ``Py5Shape`` object. + """Gets the fill color used for a `Py5Shape` object. Underlying Processing method: PShape.getFill @@ -2640,30 +2628,30 @@ def get_fill(self, index: int, /) -> int: Notes ----- - Gets the fill color used for a ``Py5Shape`` object. This method can get the fill + Gets the fill color used for a `Py5Shape` object. This method can get the fill assigned to each vertex, but most likely the value will be the same for all vertices. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getFill(index) def get_height(self) -> float: - """Get the ``Py5Shape`` object's height. + """Get the `Py5Shape` object's height. Underlying Processing method: PShape.getHeight Notes ----- - Get the ``Py5Shape`` object's height. When using the ``P2D`` or ``P3D`` - renderers, the returned value should be the height of the drawn shape. When - using the default renderer, this will be the height of the drawing area, which - will not necessarily be the same as the height of the drawn shape. Consider that - the shape's vertices might have negative values or the shape may be offset from - the shape's origin. To get the shape's actual height, calculate the range of the - vertices obtained with ``Py5Shape.get_vertex_y()``. + Get the `Py5Shape` object's height. When using the `P2D` or `P3D` renderers, the + returned value should be the height of the drawn shape. When using the default + renderer, this will be the height of the drawing area, which will not + necessarily be the same as the height of the drawn shape. Consider that the + shape's vertices might have negative values or the shape may be offset from the + shape's origin. To get the shape's actual height, calculate the range of the + vertices obtained with `Py5Shape.get_vertex_y()`. """ return self._instance.getHeight() @@ -2688,14 +2676,14 @@ def get_name(self) -> str: Notes ----- - Get the name assigned to a Py5Shape object. Will return ``None`` if the object - has no name. + Get the name assigned to a Py5Shape object. Will return `None` if the object has + no name. """ return self._instance.getName() @overload def get_normal(self, index: int, /) -> Py5Vector: - """Get the normal vector for one of a ``Py5Shape`` object's vertices. + """Get the normal vector for one of a `Py5Shape` object's vertices. Underlying Processing method: PShape.getNormal @@ -2719,20 +2707,20 @@ def get_normal(self, index: int, /) -> Py5Vector: Notes ----- - Get the normal vector for one of a ``Py5Shape`` object's vertices. A normal - vector is used for drawing three dimensional shapes and surfaces, and specifies - a vector perpendicular to a shape's surface which, in turn, determines how + Get the normal vector for one of a `Py5Shape` object's vertices. A normal vector + is used for drawing three dimensional shapes and surfaces, and specifies a + vector perpendicular to a shape's surface which, in turn, determines how lighting affects it. Py5 attempts to automatically assign normals to shapes, and this method can be used to inspect that vector. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ pass @overload def get_normal(self, index: int, vec: Py5Vector, /) -> Py5Vector: - """Get the normal vector for one of a ``Py5Shape`` object's vertices. + """Get the normal vector for one of a `Py5Shape` object's vertices. Underlying Processing method: PShape.getNormal @@ -2756,20 +2744,20 @@ def get_normal(self, index: int, vec: Py5Vector, /) -> Py5Vector: Notes ----- - Get the normal vector for one of a ``Py5Shape`` object's vertices. A normal - vector is used for drawing three dimensional shapes and surfaces, and specifies - a vector perpendicular to a shape's surface which, in turn, determines how + Get the normal vector for one of a `Py5Shape` object's vertices. A normal vector + is used for drawing three dimensional shapes and surfaces, and specifies a + vector perpendicular to a shape's surface which, in turn, determines how lighting affects it. Py5 attempts to automatically assign normals to shapes, and this method can be used to inspect that vector. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ pass @_get_pvector_wrapper def get_normal(self, *args): - """Get the normal vector for one of a ``Py5Shape`` object's vertices. + """Get the normal vector for one of a `Py5Shape` object's vertices. Underlying Processing method: PShape.getNormal @@ -2793,19 +2781,19 @@ def get_normal(self, *args): Notes ----- - Get the normal vector for one of a ``Py5Shape`` object's vertices. A normal - vector is used for drawing three dimensional shapes and surfaces, and specifies - a vector perpendicular to a shape's surface which, in turn, determines how + Get the normal vector for one of a `Py5Shape` object's vertices. A normal vector + is used for drawing three dimensional shapes and surfaces, and specifies a + vector perpendicular to a shape's surface which, in turn, determines how lighting affects it. Py5 attempts to automatically assign normals to shapes, and this method can be used to inspect that vector. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getNormal(*args) def get_normal_x(self, index: int, /) -> float: - """Get the normal vector's x value for one of a ``Py5Shape`` object's vertices. + """Get the normal vector's x value for one of a `Py5Shape` object's vertices. Underlying Processing method: PShape.getNormalX @@ -2818,19 +2806,19 @@ def get_normal_x(self, index: int, /) -> float: Notes ----- - Get the normal vector's x value for one of a ``Py5Shape`` object's vertices. A + Get the normal vector's x value for one of a `Py5Shape` object's vertices. A normal vector is used for drawing three dimensional shapes and surfaces, and specifies a vector perpendicular to a shape's surface which, in turn, determines how lighting affects it. Py5 attempts to automatically assign normals to shapes, and this method can be used to inspect that vector. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getNormalX(index) def get_normal_y(self, index: int, /) -> float: - """Get the normal vector's y value for one of a ``Py5Shape`` object's vertices. + """Get the normal vector's y value for one of a `Py5Shape` object's vertices. Underlying Processing method: PShape.getNormalY @@ -2843,19 +2831,19 @@ def get_normal_y(self, index: int, /) -> float: Notes ----- - Get the normal vector's y value for one of a ``Py5Shape`` object's vertices. A + Get the normal vector's y value for one of a `Py5Shape` object's vertices. A normal vector is used for drawing three dimensional shapes and surfaces, and specifies a vector perpendicular to a shape's surface which, in turn, determines how lighting affects it. Py5 attempts to automatically assign normals to shapes, and this method can be used to inspect that vector. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getNormalY(index) def get_normal_z(self, index: int, /) -> float: - """Get the normal vector's z value for one of a ``Py5Shape`` object's vertices. + """Get the normal vector's z value for one of a `Py5Shape` object's vertices. Underlying Processing method: PShape.getNormalZ @@ -2868,34 +2856,34 @@ def get_normal_z(self, index: int, /) -> float: Notes ----- - Get the normal vector's z value for one of a ``Py5Shape`` object's vertices. A + Get the normal vector's z value for one of a `Py5Shape` object's vertices. A normal vector is used for drawing three dimensional shapes and surfaces, and specifies a vector perpendicular to a shape's surface which, in turn, determines how lighting affects it. Py5 attempts to automatically assign normals to shapes, and this method can be used to inspect that vector. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getNormalZ(index) @_return_py5shape def get_parent(self) -> Py5Shape: - """Locate a child ``Py5Shape`` object's parent ``GROUP`` ``Py5Shape`` object. + """Locate a child `Py5Shape` object's parent `GROUP` `Py5Shape` object. Underlying Processing method: PShape.getParent Notes ----- - Locate a child ``Py5Shape`` object's parent ``GROUP`` ``Py5Shape`` object. This - will return ``None`` if the shape has no parent, such as when the shape is the - parent object or the shape is not a part of a group. + Locate a child `Py5Shape` object's parent `GROUP` `Py5Shape` object. This will + return `None` if the shape has no parent, such as when the shape is the parent + object or the shape is not a part of a group. """ return self._instance.getParent() def get_shininess(self, index: int, /) -> float: - """Get the shininess setting for one of a ``Py5Shape`` object's vertices. + """Get the shininess setting for one of a `Py5Shape` object's vertices. Underlying Processing method: PShape.getShininess @@ -2908,16 +2896,16 @@ def get_shininess(self, index: int, /) -> float: Notes ----- - Get the shininess setting for one of a ``Py5Shape`` object's vertices. Use - ``Py5Shape.set_shininess()`` to change the setting. + Get the shininess setting for one of a `Py5Shape` object's vertices. Use + `Py5Shape.set_shininess()` to change the setting. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getShininess(index) def get_specular(self, index: int, /) -> int: - """Get the specular color setting for one of a ``Py5Shape`` object's vertices. + """Get the specular color setting for one of a `Py5Shape` object's vertices. Underlying Processing method: PShape.getSpecular @@ -2930,16 +2918,16 @@ def get_specular(self, index: int, /) -> int: Notes ----- - Get the specular color setting for one of a ``Py5Shape`` object's vertices. Use - ``Py5Shape.set_specular()`` to change the setting. + Get the specular color setting for one of a `Py5Shape` object's vertices. Use + `Py5Shape.set_specular()` to change the setting. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getSpecular(index) def get_stroke(self, index: int, /) -> int: - """Gets the stroke color used for lines and points in a ``Py5Shape`` object. + """Gets the stroke color used for lines and points in a `Py5Shape` object. Underlying Processing method: PShape.getStroke @@ -2952,17 +2940,17 @@ def get_stroke(self, index: int, /) -> int: Notes ----- - Gets the stroke color used for lines and points in a ``Py5Shape`` object. This + Gets the stroke color used for lines and points in a `Py5Shape` object. This method can get the stroke assigned to each vertex, but most likely the value will be the same for all vertices. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getStroke(index) def get_stroke_weight(self, index: int, /) -> float: - """Gets the width of the stroke used for lines and points in a ``Py5Shape`` object. + """Gets the width of the stroke used for lines and points in a `Py5Shape` object. Underlying Processing method: PShape.getStrokeWeight @@ -2975,13 +2963,13 @@ def get_stroke_weight(self, index: int, /) -> float: Notes ----- - Gets the width of the stroke used for lines and points in a ``Py5Shape`` object. + Gets the width of the stroke used for lines and points in a `Py5Shape` object. All widths are set in units of pixels. This method can get the stroke weight assigned to each vertex, but most likely the value will be the same for all vertices. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.getStrokeWeight(index) @@ -3001,7 +2989,7 @@ def get_texture_u(self, index: int, /) -> float: Get the horizontal texture mapping coordinate for a particular vertex. Returned values will always range from 0 to 1, regardless of what the Sketch's - ``texture_mode()`` setting is. + `texture_mode()` setting is. """ return self._instance.getTextureU(index) @@ -3021,12 +3009,12 @@ def get_texture_v(self, index: int, /) -> float: Get the vertical texture mapping coordinate for a particular vertex. Returned values will always range from 0 to 1, regardless of what the Sketch's - ``texture_mode()`` setting is. + `texture_mode()` setting is. """ return self._instance.getTextureV(index) def get_tint(self, index: int, /) -> int: - """Get the texture tint color assigned to one vertex in a ``Py5Shape`` object. + """Get the texture tint color assigned to one vertex in a `Py5Shape` object. Underlying Processing method: PShape.getTint @@ -3039,15 +3027,15 @@ def get_tint(self, index: int, /) -> int: Notes ----- - Get the texture tint color assigned to one vertex in a ``Py5Shape`` object. If - the vertex has no assigned tint, the returned color value will be white. + Get the texture tint color assigned to one vertex in a `Py5Shape` object. If the + vertex has no assigned tint, the returned color value will be white. """ return self._instance.getTint(index) @overload def get_vertex(self, index: int, /) -> Py5Vector: - """The ``get_vertex()`` method returns a Py5Vector with the coordinates of the - vertex point located at the position defined by the ``index`` parameter. + """The `get_vertex()` method returns a Py5Vector with the coordinates of the vertex + point located at the position defined by the `index` parameter. Underlying Processing method: PShape.getVertex @@ -3071,18 +3059,17 @@ def get_vertex(self, index: int, /) -> Py5Vector: Notes ----- - The ``get_vertex()`` method returns a Py5Vector with the coordinates of the - vertex point located at the position defined by the ``index`` parameter. This - method works when shapes are created as shown in the example, but won't work - properly when a shape is defined explicitly (e.g. ``create_shape(RECT, 20, 20, - 80, 80)``. + The `get_vertex()` method returns a Py5Vector with the coordinates of the vertex + point located at the position defined by the `index` parameter. This method + works when shapes are created as shown in the example, but won't work properly + when a shape is defined explicitly (e.g. `create_shape(RECT, 20, 20, 80, 80)`. """ pass @overload def get_vertex(self, index: int, vec: Py5Vector, /) -> Py5Vector: - """The ``get_vertex()`` method returns a Py5Vector with the coordinates of the - vertex point located at the position defined by the ``index`` parameter. + """The `get_vertex()` method returns a Py5Vector with the coordinates of the vertex + point located at the position defined by the `index` parameter. Underlying Processing method: PShape.getVertex @@ -3106,18 +3093,17 @@ def get_vertex(self, index: int, vec: Py5Vector, /) -> Py5Vector: Notes ----- - The ``get_vertex()`` method returns a Py5Vector with the coordinates of the - vertex point located at the position defined by the ``index`` parameter. This - method works when shapes are created as shown in the example, but won't work - properly when a shape is defined explicitly (e.g. ``create_shape(RECT, 20, 20, - 80, 80)``. + The `get_vertex()` method returns a Py5Vector with the coordinates of the vertex + point located at the position defined by the `index` parameter. This method + works when shapes are created as shown in the example, but won't work properly + when a shape is defined explicitly (e.g. `create_shape(RECT, 20, 20, 80, 80)`. """ pass @_get_pvector_wrapper def get_vertex(self, *args): - """The ``get_vertex()`` method returns a Py5Vector with the coordinates of the - vertex point located at the position defined by the ``index`` parameter. + """The `get_vertex()` method returns a Py5Vector with the coordinates of the vertex + point located at the position defined by the `index` parameter. Underlying Processing method: PShape.getVertex @@ -3141,11 +3127,10 @@ def get_vertex(self, *args): Notes ----- - The ``get_vertex()`` method returns a Py5Vector with the coordinates of the - vertex point located at the position defined by the ``index`` parameter. This - method works when shapes are created as shown in the example, but won't work - properly when a shape is defined explicitly (e.g. ``create_shape(RECT, 20, 20, - 80, 80)``. + The `get_vertex()` method returns a Py5Vector with the coordinates of the vertex + point located at the position defined by the `index` parameter. This method + works when shapes are created as shown in the example, but won't work properly + when a shape is defined explicitly (e.g. `create_shape(RECT, 20, 20, 80, 80)`. """ return self._instance.getVertex(*args) @@ -3165,71 +3150,71 @@ def get_vertex_code(self, index: int, /) -> int: Get the vertex code for a particular vertex code index. The vertex codes can be used to inspect a shape's geometry to determine what kind of vertices it has. - Each can be one of ``BREAK``, ``VERTEX``, ``BEZIER_VERTEX``, - ``QUADRATIC_VERTEX`` or ``CURVE_VERTEX``. + Each can be one of `BREAK`, `VERTEX`, `BEZIER_VERTEX`, `QUADRATIC_VERTEX` or + `CURVE_VERTEX`. The vertex codes will not necessarily align with the vertices because number of vertex codes may be larger than the number of vertices. This will be the case - for shapes that use contours, and therefore contain ``BREAK`` codes. + for shapes that use contours, and therefore contain `BREAK` codes. """ return self._instance.getVertexCode(index) def get_vertex_code_count(self) -> int: - """Get the number of vertex codes within a ``Py5Shape`` object. + """Get the number of vertex codes within a `Py5Shape` object. Underlying Processing method: PShape.getVertexCodeCount Notes ----- - Get the number of vertex codes within a ``Py5Shape`` object. The vertex codes - can be used to inspect a shape's geometry to determine what kind of vertices it - has. Each can be one of ``BREAK``, ``VERTEX``, ``BEZIER_VERTEX``, - ``QUADRATIC_VERTEX`` or ``CURVE_VERTEX``. + Get the number of vertex codes within a `Py5Shape` object. The vertex codes can + be used to inspect a shape's geometry to determine what kind of vertices it has. + Each can be one of `BREAK`, `VERTEX`, `BEZIER_VERTEX`, `QUADRATIC_VERTEX` or + `CURVE_VERTEX`. The vertex codes will not necessarily align with the vertices because number of vertex codes may be larger than the number of vertices. This will be the case - for shapes that use contours, and therefore contain ``BREAK`` codes. + for shapes that use contours, and therefore contain `BREAK` codes. """ return self._instance.getVertexCodeCount() @_return_numpy_array def get_vertex_codes(self) -> npt.NDArray[np.integer]: - """Get the vertex codes for a ``Py5Shape`` object. + """Get the vertex codes for a `Py5Shape` object. Underlying Processing method: PShape.getVertexCodes Notes ----- - Get the vertex codes for a ``Py5Shape`` object. The vertex codes can be used to + Get the vertex codes for a `Py5Shape` object. The vertex codes can be used to inspect a shape's geometry to determine what kind of vertices it has. Each can - be one of ``BREAK``, ``VERTEX``, ``BEZIER_VERTEX``, ``QUADRATIC_VERTEX`` or - ``CURVE_VERTEX``. + be one of `BREAK`, `VERTEX`, `BEZIER_VERTEX`, `QUADRATIC_VERTEX` or + `CURVE_VERTEX`. The vertex codes will not necessarily align with the vertices because number of vertex codes may be larger than the number of vertices. This will be the case - for shapes that use contours, and therefore contain ``BREAK`` codes. + for shapes that use contours, and therefore contain `BREAK` codes. """ return self._instance.getVertexCodes() def get_vertex_count(self) -> int: - """The ``get_vertex_count()`` method returns the number of vertices that make up a - ``Py5Shape``. + """The `get_vertex_count()` method returns the number of vertices that make up a + `Py5Shape`. Underlying Processing method: PShape.getVertexCount Notes ----- - The ``get_vertex_count()`` method returns the number of vertices that make up a - ``Py5Shape``. In the example, the value 4 is returned by the - ``get_vertex_count()`` method because 4 vertices are defined in ``setup()``. + The `get_vertex_count()` method returns the number of vertices that make up a + `Py5Shape`. In the example, the value 4 is returned by the `get_vertex_count()` + method because 4 vertices are defined in `setup()`. """ return self._instance.getVertexCount() def get_vertex_x(self, index: int, /) -> float: - """Get the value of the x coordinate for the vertex ``index``. + """Get the value of the x coordinate for the vertex `index`. Underlying Processing method: PShape.getVertexX @@ -3242,12 +3227,12 @@ def get_vertex_x(self, index: int, /) -> float: Notes ----- - Get the value of the x coordinate for the vertex ``index``. + Get the value of the x coordinate for the vertex `index`. """ return self._instance.getVertexX(index) def get_vertex_y(self, index: int, /) -> float: - """Get the value of the y coordinate for the vertex ``index``. + """Get the value of the y coordinate for the vertex `index`. Underlying Processing method: PShape.getVertexY @@ -3260,12 +3245,12 @@ def get_vertex_y(self, index: int, /) -> float: Notes ----- - Get the value of the y coordinate for the vertex ``index``. + Get the value of the y coordinate for the vertex `index`. """ return self._instance.getVertexY(index) def get_vertex_z(self, index: int, /) -> float: - """Get the value of the z coordinate for the vertex ``index``. + """Get the value of the z coordinate for the vertex `index`. Underlying Processing method: PShape.getVertexZ @@ -3278,25 +3263,25 @@ def get_vertex_z(self, index: int, /) -> float: Notes ----- - Get the value of the z coordinate for the vertex ``index``. + Get the value of the z coordinate for the vertex `index`. """ return self._instance.getVertexZ(index) def get_width(self) -> float: - """Get the ``Py5Shape`` object's width. + """Get the `Py5Shape` object's width. Underlying Processing method: PShape.getWidth Notes ----- - Get the ``Py5Shape`` object's width. When using the ``P2D`` or ``P3D`` - renderers, the returned value should be the width of the drawn shape. When using - the default renderer, this will be the width of the drawing area, which will not - necessarily be the same as the width of the drawn shape. Consider that the - shape's vertices might have negative values or the shape may be offset from the - shape's origin. To get the shape's actual width, calculate the range of the - vertices obtained with ``Py5Shape.get_vertex_x()``. + Get the `Py5Shape` object's width. When using the `P2D` or `P3D` renderers, the + returned value should be the width of the drawn shape. When using the default + renderer, this will be the width of the drawing area, which will not necessarily + be the same as the width of the drawn shape. Consider that the shape's vertices + might have negative values or the shape may be offset from the shape's origin. + To get the shape's actual width, calculate the range of the vertices obtained + with `Py5Shape.get_vertex_x()`. """ return self._instance.getWidth() @@ -3310,8 +3295,8 @@ def is2d(self) -> bool: Boolean value reflecting if the shape is or is not a 2D shape. - If the shape is created in a Sketch using the ``P3D`` renderer, this will be - ``False``, even if it only uses 2D coordinates. + If the shape is created in a Sketch using the `P3D` renderer, this will be + `False`, even if it only uses 2D coordinates. """ return self._instance.is2D() @@ -3325,13 +3310,13 @@ def is3d(self) -> bool: Boolean value reflecting if the shape is or is not a 3D shape. - If the shape is created in a Sketch using the ``P3D`` renderer, this will be - ``True``, even if it only uses 2D coordinates. + If the shape is created in a Sketch using the `P3D` renderer, this will be + `True`, even if it only uses 2D coordinates. """ return self._instance.is3D() def is_visible(self) -> bool: - """Returns a boolean value ``True`` if the image is set to be visible, ``False`` if + """Returns a boolean value `True` if the image is set to be visible, `False` if not. Underlying Processing method: PShape.isVisible @@ -3339,8 +3324,8 @@ def is_visible(self) -> bool: Notes ----- - Returns a boolean value ``True`` if the image is set to be visible, ``False`` if - not. This value can be modified with the ``Py5Shape.set_visible()`` method. + Returns a boolean value `True` if the image is set to be visible, `False` if + not. This value can be modified with the `Py5Shape.set_visible()` method. The default visibility of a shape is usually controlled by whatever program created the SVG file. For instance, this parameter is controlled by showing or @@ -3349,35 +3334,35 @@ def is_visible(self) -> bool: return self._instance.isVisible() def no_fill(self) -> None: - """Disables the ``Py5Shape`` object's filling geometry. + """Disables the `Py5Shape` object's filling geometry. Underlying Processing method: PShape.noFill Notes ----- - Disables the ``Py5Shape`` object's filling geometry. If both - ``Py5Shape.no_stroke()`` and ``no_fill()`` are called, nothing will be drawn to - the screen. + Disables the `Py5Shape` object's filling geometry. If both + `Py5Shape.no_stroke()` and `no_fill()` are called, nothing will be drawn to the + screen. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ return self._instance.noFill() def no_stroke(self) -> None: - """Disables the ``Py5Shape`` object's stroke (outline). + """Disables the `Py5Shape` object's stroke (outline). Underlying Processing method: PShape.noStroke Notes ----- - Disables the ``Py5Shape`` object's stroke (outline). If both ``no_stroke()`` and - ``Py5Shape.no_fill()`` are called, nothing will be drawn to the screen. + Disables the `Py5Shape` object's stroke (outline). If both `no_stroke()` and + `Py5Shape.no_fill()` are called, nothing will be drawn to the screen. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ return self._instance.noStroke() @@ -3389,16 +3374,16 @@ def no_tint(self) -> None: Notes ----- - Stop applying a color tint to a shape's texture map. Use ``Py5Shape.tint()`` to + Stop applying a color tint to a shape's texture map. Use `Py5Shape.tint()` to start applying a color tint. - Both ``Py5Shape.tint()`` and ``no_tint()`` can be used to control the coloring - of textures in 3D. + Both `Py5Shape.tint()` and `no_tint()` can be used to control the coloring of + textures in 3D. """ return self._instance.noTint() def normal(self, nx: float, ny: float, nz: float, /) -> None: - """Sets the current normal vector for a ``Py5Shape`` object's vertices. + """Sets the current normal vector for a `Py5Shape` object's vertices. Underlying Processing method: PShape.normal @@ -3417,14 +3402,14 @@ def normal(self, nx: float, ny: float, nz: float, /) -> None: Notes ----- - Sets the current normal vector for a ``Py5Shape`` object's vertices. Used for - drawing three dimensional shapes and surfaces, ``normal()`` specifies a vector + Sets the current normal vector for a `Py5Shape` object's vertices. Used for + drawing three dimensional shapes and surfaces, `normal()` specifies a vector perpendicular to a shape's surface which, in turn, determines how lighting affects it. Py5 attempts to automatically assign normals to shapes, but since that's imperfect, this is a better option when you want more control. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The normal setting will be applied to vertices + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The normal setting will be applied to vertices added after the call to this method. """ return self._instance.normal(nx, ny, nz) @@ -3432,8 +3417,7 @@ def normal(self, nx: float, ny: float, nz: float, /) -> None: @overload def quadratic_vertex(self, cx: float, cy: float, x3: float, y3: float, /) -> None: - """Specifies a ``Py5Shape`` object's vertex coordinates for quadratic Bezier - curves. + """Specifies a `Py5Shape` object's vertex coordinates for quadratic Bezier curves. Underlying Processing method: PShape.quadraticVertex @@ -3469,27 +3453,25 @@ def quadratic_vertex(self, cx: float, cy: float, Notes ----- - Specifies a ``Py5Shape`` object's vertex coordinates for quadratic Bezier - curves. Each call to ``quadratic_vertex()`` defines the position of one control - point and one anchor point of a Bezier curve, adding a new segment to a line or - shape. The first time ``quadratic_vertex()`` is used within a - ``Py5Shape.begin_shape()`` call, it must be prefaced with a call to - ``Py5Shape.vertex()`` to set the first anchor point. This method must be used - between ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` and only when - there is no ``MODE`` parameter specified to ``Py5Shape.begin_shape()``. + Specifies a `Py5Shape` object's vertex coordinates for quadratic Bezier curves. + Each call to `quadratic_vertex()` defines the position of one control point and + one anchor point of a Bezier curve, adding a new segment to a line or shape. The + first time `quadratic_vertex()` is used within a `Py5Shape.begin_shape()` call, + it must be prefaced with a call to `Py5Shape.vertex()` to set the first anchor + point. This method must be used between `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` and only when there is no `MODE` parameter specified to + `Py5Shape.begin_shape()`. - Drawing 2D bezier curves requires using the ``P2D`` renderer and drawing 3D - bezier curves requires using the ``P3D`` renderer. When drawing directly with - ``Py5Shape`` objects, bezier curves do not work at all using the default - renderer. + Drawing 2D bezier curves requires using the `P2D` renderer and drawing 3D bezier + curves requires using the `P3D` renderer. When drawing directly with `Py5Shape` + objects, bezier curves do not work at all using the default renderer. """ pass @overload def quadratic_vertex(self, cx: float, cy: float, cz: float, x3: float, y3: float, z3: float, /) -> None: - """Specifies a ``Py5Shape`` object's vertex coordinates for quadratic Bezier - curves. + """Specifies a `Py5Shape` object's vertex coordinates for quadratic Bezier curves. Underlying Processing method: PShape.quadraticVertex @@ -3525,25 +3507,23 @@ def quadratic_vertex(self, cx: float, cy: float, cz: float, Notes ----- - Specifies a ``Py5Shape`` object's vertex coordinates for quadratic Bezier - curves. Each call to ``quadratic_vertex()`` defines the position of one control - point and one anchor point of a Bezier curve, adding a new segment to a line or - shape. The first time ``quadratic_vertex()`` is used within a - ``Py5Shape.begin_shape()`` call, it must be prefaced with a call to - ``Py5Shape.vertex()`` to set the first anchor point. This method must be used - between ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` and only when - there is no ``MODE`` parameter specified to ``Py5Shape.begin_shape()``. + Specifies a `Py5Shape` object's vertex coordinates for quadratic Bezier curves. + Each call to `quadratic_vertex()` defines the position of one control point and + one anchor point of a Bezier curve, adding a new segment to a line or shape. The + first time `quadratic_vertex()` is used within a `Py5Shape.begin_shape()` call, + it must be prefaced with a call to `Py5Shape.vertex()` to set the first anchor + point. This method must be used between `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` and only when there is no `MODE` parameter specified to + `Py5Shape.begin_shape()`. - Drawing 2D bezier curves requires using the ``P2D`` renderer and drawing 3D - bezier curves requires using the ``P3D`` renderer. When drawing directly with - ``Py5Shape`` objects, bezier curves do not work at all using the default - renderer. + Drawing 2D bezier curves requires using the `P2D` renderer and drawing 3D bezier + curves requires using the `P3D` renderer. When drawing directly with `Py5Shape` + objects, bezier curves do not work at all using the default renderer. """ pass def quadratic_vertex(self, *args): - """Specifies a ``Py5Shape`` object's vertex coordinates for quadratic Bezier - curves. + """Specifies a `Py5Shape` object's vertex coordinates for quadratic Bezier curves. Underlying Processing method: PShape.quadraticVertex @@ -3579,25 +3559,24 @@ def quadratic_vertex(self, *args): Notes ----- - Specifies a ``Py5Shape`` object's vertex coordinates for quadratic Bezier - curves. Each call to ``quadratic_vertex()`` defines the position of one control - point and one anchor point of a Bezier curve, adding a new segment to a line or - shape. The first time ``quadratic_vertex()`` is used within a - ``Py5Shape.begin_shape()`` call, it must be prefaced with a call to - ``Py5Shape.vertex()`` to set the first anchor point. This method must be used - between ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` and only when - there is no ``MODE`` parameter specified to ``Py5Shape.begin_shape()``. + Specifies a `Py5Shape` object's vertex coordinates for quadratic Bezier curves. + Each call to `quadratic_vertex()` defines the position of one control point and + one anchor point of a Bezier curve, adding a new segment to a line or shape. The + first time `quadratic_vertex()` is used within a `Py5Shape.begin_shape()` call, + it must be prefaced with a call to `Py5Shape.vertex()` to set the first anchor + point. This method must be used between `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` and only when there is no `MODE` parameter specified to + `Py5Shape.begin_shape()`. - Drawing 2D bezier curves requires using the ``P2D`` renderer and drawing 3D - bezier curves requires using the ``P3D`` renderer. When drawing directly with - ``Py5Shape`` objects, bezier curves do not work at all using the default - renderer. + Drawing 2D bezier curves requires using the `P2D` renderer and drawing 3D bezier + curves requires using the `P3D` renderer. When drawing directly with `Py5Shape` + objects, bezier curves do not work at all using the default renderer. """ return self._instance.quadraticVertex(*args) def remove_child(self, idx: int, /) -> None: - """Removes a child ``Py5Shape`` object from a parent ``Py5Shape`` object that is - defined as a ``GROUP``. + """Removes a child `Py5Shape` object from a parent `Py5Shape` object that is + defined as a `GROUP`. Underlying Processing method: PShape.removeChild @@ -3610,8 +3589,8 @@ def remove_child(self, idx: int, /) -> None: Notes ----- - Removes a child ``Py5Shape`` object from a parent ``Py5Shape`` object that is - defined as a ``GROUP``. + Removes a child `Py5Shape` object from a parent `Py5Shape` object that is + defined as a `GROUP`. """ return self._instance.removeChild(idx) @@ -3624,13 +3603,13 @@ def reset_matrix(self) -> None: ----- Replaces the current matrix of a shape with the identity matrix. The equivalent - function in OpenGL is ``gl_load_identity()``. + function in OpenGL is `gl_load_identity()`. """ return self._instance.resetMatrix() @overload def rotate(self, angle: float, /) -> None: - """Rotates the shape the amount specified by the ``angle`` parameter. + """Rotates the shape the amount specified by the `angle` parameter. Underlying Processing method: PShape.rotate @@ -3660,22 +3639,22 @@ def rotate(self, angle: float, /) -> None: Notes ----- - Rotates the shape the amount specified by the ``angle`` parameter. Angles should - be specified in radians (values from 0 to ``TWO_PI``) or converted from degrees - to radians with the ``radians()`` method. + Rotates the shape the amount specified by the `angle` parameter. Angles should + be specified in radians (values from 0 to `TWO_PI`) or converted from degrees to + radians with the `radians()` method. Shapes are always rotated around the upper-left corner of their bounding box. Positive numbers rotate objects in a clockwise direction. Transformations apply to everything that happens after and subsequent calls to the method accumulates - the effect. For example, calling ``rotate(HALF_PI)`` and then - ``rotate(HALF_PI)`` is the same as ``rotate(PI)``. This transformation is - applied directly to the shape, it's not refreshed each time ``draw()`` is run. + the effect. For example, calling `rotate(HALF_PI)` and then `rotate(HALF_PI)` is + the same as `rotate(PI)`. This transformation is applied directly to the shape, + it's not refreshed each time `draw()` is run. """ pass @overload def rotate(self, angle: float, v0: float, v1: float, v2: float, /) -> None: - """Rotates the shape the amount specified by the ``angle`` parameter. + """Rotates the shape the amount specified by the `angle` parameter. Underlying Processing method: PShape.rotate @@ -3705,21 +3684,21 @@ def rotate(self, angle: float, v0: float, v1: float, v2: float, /) -> None: Notes ----- - Rotates the shape the amount specified by the ``angle`` parameter. Angles should - be specified in radians (values from 0 to ``TWO_PI``) or converted from degrees - to radians with the ``radians()`` method. + Rotates the shape the amount specified by the `angle` parameter. Angles should + be specified in radians (values from 0 to `TWO_PI`) or converted from degrees to + radians with the `radians()` method. Shapes are always rotated around the upper-left corner of their bounding box. Positive numbers rotate objects in a clockwise direction. Transformations apply to everything that happens after and subsequent calls to the method accumulates - the effect. For example, calling ``rotate(HALF_PI)`` and then - ``rotate(HALF_PI)`` is the same as ``rotate(PI)``. This transformation is - applied directly to the shape, it's not refreshed each time ``draw()`` is run. + the effect. For example, calling `rotate(HALF_PI)` and then `rotate(HALF_PI)` is + the same as `rotate(PI)`. This transformation is applied directly to the shape, + it's not refreshed each time `draw()` is run. """ pass def rotate(self, *args): - """Rotates the shape the amount specified by the ``angle`` parameter. + """Rotates the shape the amount specified by the `angle` parameter. Underlying Processing method: PShape.rotate @@ -3749,21 +3728,21 @@ def rotate(self, *args): Notes ----- - Rotates the shape the amount specified by the ``angle`` parameter. Angles should - be specified in radians (values from 0 to ``TWO_PI``) or converted from degrees - to radians with the ``radians()`` method. + Rotates the shape the amount specified by the `angle` parameter. Angles should + be specified in radians (values from 0 to `TWO_PI`) or converted from degrees to + radians with the `radians()` method. Shapes are always rotated around the upper-left corner of their bounding box. Positive numbers rotate objects in a clockwise direction. Transformations apply to everything that happens after and subsequent calls to the method accumulates - the effect. For example, calling ``rotate(HALF_PI)`` and then - ``rotate(HALF_PI)`` is the same as ``rotate(PI)``. This transformation is - applied directly to the shape, it's not refreshed each time ``draw()`` is run. + the effect. For example, calling `rotate(HALF_PI)` and then `rotate(HALF_PI)` is + the same as `rotate(PI)`. This transformation is applied directly to the shape, + it's not refreshed each time `draw()` is run. """ return self._instance.rotate(*args) def rotate_x(self, angle: float, /) -> None: - """Rotates the shape around the x-axis the amount specified by the ``angle`` + """Rotates the shape around the x-axis the amount specified by the `angle` parameter. Underlying Processing method: PShape.rotateX @@ -3777,24 +3756,23 @@ def rotate_x(self, angle: float, /) -> None: Notes ----- - Rotates the shape around the x-axis the amount specified by the ``angle`` - parameter. Angles should be specified in radians (values from 0 to ``TWO_PI``) - or converted from degrees to radians with the ``radians()`` method. + Rotates the shape around the x-axis the amount specified by the `angle` + parameter. Angles should be specified in radians (values from 0 to `TWO_PI`) or + converted from degrees to radians with the `radians()` method. Shapes are always rotated around the upper-left corner of their bounding box. Positive numbers rotate objects in a clockwise direction. Subsequent calls to - the method accumulates the effect. For example, calling ``rotate_x(HALF_PI)`` - and then ``rotate_x(HALF_PI)`` is the same as ``rotate_x(PI)``. This - transformation is applied directly to the shape, it's not refreshed each time - ``draw()`` is run. + the method accumulates the effect. For example, calling `rotate_x(HALF_PI)` and + then `rotate_x(HALF_PI)` is the same as `rotate_x(PI)`. This transformation is + applied directly to the shape, it's not refreshed each time `draw()` is run. - This method requires a 3D renderer. You need to use ``P3D`` as a third parameter - for the ``size()`` function as shown in the example. + This method requires a 3D renderer. You need to use `P3D` as a third parameter + for the `size()` function as shown in the example. """ return self._instance.rotateX(angle) def rotate_y(self, angle: float, /) -> None: - """Rotates the shape around the y-axis the amount specified by the ``angle`` + """Rotates the shape around the y-axis the amount specified by the `angle` parameter. Underlying Processing method: PShape.rotateY @@ -3808,24 +3786,23 @@ def rotate_y(self, angle: float, /) -> None: Notes ----- - Rotates the shape around the y-axis the amount specified by the ``angle`` - parameter. Angles should be specified in radians (values from 0 to ``TWO_PI``) - or converted from degrees to radians with the ``radians()`` method. + Rotates the shape around the y-axis the amount specified by the `angle` + parameter. Angles should be specified in radians (values from 0 to `TWO_PI`) or + converted from degrees to radians with the `radians()` method. Shapes are always rotated around the upper-left corner of their bounding box. Positive numbers rotate objects in a clockwise direction. Subsequent calls to - the method accumulates the effect. For example, calling ``rotate_y(HALF_PI)`` - and then ``rotate_y(HALF_PI)`` is the same as ``rotate_y(PI)``. This - transformation is applied directly to the shape, it's not refreshed each time - ``draw()`` is run. + the method accumulates the effect. For example, calling `rotate_y(HALF_PI)` and + then `rotate_y(HALF_PI)` is the same as `rotate_y(PI)`. This transformation is + applied directly to the shape, it's not refreshed each time `draw()` is run. - This method requires a 3D renderer. You need to use ``P3D`` as a third parameter - for the ``size()`` function as shown in the example. + This method requires a 3D renderer. You need to use `P3D` as a third parameter + for the `size()` function as shown in the example. """ return self._instance.rotateY(angle) def rotate_z(self, angle: float, /) -> None: - """Rotates the shape around the z-axis the amount specified by the ``angle`` + """Rotates the shape around the z-axis the amount specified by the `angle` parameter. Underlying Processing method: PShape.rotateZ @@ -3839,19 +3816,18 @@ def rotate_z(self, angle: float, /) -> None: Notes ----- - Rotates the shape around the z-axis the amount specified by the ``angle`` - parameter. Angles should be specified in radians (values from 0 to ``TWO_PI``) - or converted from degrees to radians with the ``radians()`` method. + Rotates the shape around the z-axis the amount specified by the `angle` + parameter. Angles should be specified in radians (values from 0 to `TWO_PI`) or + converted from degrees to radians with the `radians()` method. Shapes are always rotated around the upper-left corner of their bounding box. Positive numbers rotate objects in a clockwise direction. Subsequent calls to - the method accumulates the effect. For example, calling ``rotate_z(HALF_PI)`` - and then ``rotate_z(HALF_PI)`` is the same as ``rotate_z(PI)``. This - transformation is applied directly to the shape, it's not refreshed each time - ``draw()`` is run. + the method accumulates the effect. For example, calling `rotate_z(HALF_PI)` and + then `rotate_z(HALF_PI)` is the same as `rotate_z(PI)`. This transformation is + applied directly to the shape, it's not refreshed each time `draw()` is run. - This method requires a 3D renderer. You need to use ``P3D`` as a third parameter - for the ``size()`` function as shown in the example. + This method requires a 3D renderer. You need to use `P3D` as a third parameter + for the `size()` function as shown in the example. """ return self._instance.rotateZ(angle) @@ -3892,13 +3868,13 @@ def scale(self, s: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Shapes always scale from the relative origin of their bounding box. Scale values are specified as decimal percentages. For example, the method call - ``scale(2.0)`` increases the dimension of a shape by 200%. Subsequent calls to - the method multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. This transformation is applied - directly to the shape; it's not refreshed each time ``draw()`` is run. + `scale(2.0)` increases the dimension of a shape by 200%. Subsequent calls to the + method multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. This transformation is applied + directly to the shape; it's not refreshed each time `draw()` is run. - Using this method with the ``z`` parameter requires using the ``P3D`` parameter - in combination with size. + Using this method with the `z` parameter requires using the `P3D` parameter in + combination with size. """ pass @@ -3939,13 +3915,13 @@ def scale(self, x: float, y: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Shapes always scale from the relative origin of their bounding box. Scale values are specified as decimal percentages. For example, the method call - ``scale(2.0)`` increases the dimension of a shape by 200%. Subsequent calls to - the method multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. This transformation is applied - directly to the shape; it's not refreshed each time ``draw()`` is run. + `scale(2.0)` increases the dimension of a shape by 200%. Subsequent calls to the + method multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. This transformation is applied + directly to the shape; it's not refreshed each time `draw()` is run. - Using this method with the ``z`` parameter requires using the ``P3D`` parameter - in combination with size. + Using this method with the `z` parameter requires using the `P3D` parameter in + combination with size. """ pass @@ -3986,13 +3962,13 @@ def scale(self, x: float, y: float, z: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Shapes always scale from the relative origin of their bounding box. Scale values are specified as decimal percentages. For example, the method call - ``scale(2.0)`` increases the dimension of a shape by 200%. Subsequent calls to - the method multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. This transformation is applied - directly to the shape; it's not refreshed each time ``draw()`` is run. + `scale(2.0)` increases the dimension of a shape by 200%. Subsequent calls to the + method multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. This transformation is applied + directly to the shape; it's not refreshed each time `draw()` is run. - Using this method with the ``z`` parameter requires using the ``P3D`` parameter - in combination with size. + Using this method with the `z` parameter requires using the `P3D` parameter in + combination with size. """ pass @@ -4032,19 +4008,19 @@ def scale(self, *args): Increases or decreases the size of a shape by expanding and contracting vertices. Shapes always scale from the relative origin of their bounding box. Scale values are specified as decimal percentages. For example, the method call - ``scale(2.0)`` increases the dimension of a shape by 200%. Subsequent calls to - the method multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. This transformation is applied - directly to the shape; it's not refreshed each time ``draw()`` is run. + `scale(2.0)` increases the dimension of a shape by 200%. Subsequent calls to the + method multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. This transformation is applied + directly to the shape; it's not refreshed each time `draw()` is run. - Using this method with the ``z`` parameter requires using the ``P3D`` parameter - in combination with size. + Using this method with the `z` parameter requires using the `P3D` parameter in + combination with size. """ return self._instance.scale(*args) @overload def set_ambient(self, ambient: int, /) -> None: - """Sets a ``Py5Shape`` object's ambient reflectance. + """Sets a `Py5Shape` object's ambient reflectance. Underlying Processing method: PShape.setAmbient @@ -4068,26 +4044,26 @@ def set_ambient(self, ambient: int, /) -> None: Notes ----- - Sets a ``Py5Shape`` object's ambient reflectance. This is combined with the + Sets a `Py5Shape` object's ambient reflectance. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color mode, - calling ``set_ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with - ``Py5Shape.set_emissive()``, ``Py5Shape.set_specular()``, and - ``Py5Shape.set_shininess()`` to set the material properties of a ``Py5Shape`` + calling `set_ambient(255, 127, 0)`, would cause all the red light to reflect and + half of the green light to reflect. Use in combination with + `Py5Shape.set_emissive()`, `Py5Shape.set_specular()`, and + `Py5Shape.set_shininess()` to set the material properties of a `Py5Shape` object. - The ``ambient`` parameter can be applied to the entire ``Py5Shape`` object or to - a single vertex. + The `ambient` parameter can be applied to the entire `Py5Shape` object or to a + single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ pass @overload def set_ambient(self, index: int, ambient: int, /) -> None: - """Sets a ``Py5Shape`` object's ambient reflectance. + """Sets a `Py5Shape` object's ambient reflectance. Underlying Processing method: PShape.setAmbient @@ -4111,26 +4087,26 @@ def set_ambient(self, index: int, ambient: int, /) -> None: Notes ----- - Sets a ``Py5Shape`` object's ambient reflectance. This is combined with the + Sets a `Py5Shape` object's ambient reflectance. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color mode, - calling ``set_ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with - ``Py5Shape.set_emissive()``, ``Py5Shape.set_specular()``, and - ``Py5Shape.set_shininess()`` to set the material properties of a ``Py5Shape`` + calling `set_ambient(255, 127, 0)`, would cause all the red light to reflect and + half of the green light to reflect. Use in combination with + `Py5Shape.set_emissive()`, `Py5Shape.set_specular()`, and + `Py5Shape.set_shininess()` to set the material properties of a `Py5Shape` object. - The ``ambient`` parameter can be applied to the entire ``Py5Shape`` object or to - a single vertex. + The `ambient` parameter can be applied to the entire `Py5Shape` object or to a + single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ pass @_convert_hex_color2 def set_ambient(self, *args): - """Sets a ``Py5Shape`` object's ambient reflectance. + """Sets a `Py5Shape` object's ambient reflectance. Underlying Processing method: PShape.setAmbient @@ -4154,26 +4130,26 @@ def set_ambient(self, *args): Notes ----- - Sets a ``Py5Shape`` object's ambient reflectance. This is combined with the + Sets a `Py5Shape` object's ambient reflectance. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color mode, - calling ``set_ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with - ``Py5Shape.set_emissive()``, ``Py5Shape.set_specular()``, and - ``Py5Shape.set_shininess()`` to set the material properties of a ``Py5Shape`` + calling `set_ambient(255, 127, 0)`, would cause all the red light to reflect and + half of the green light to reflect. Use in combination with + `Py5Shape.set_emissive()`, `Py5Shape.set_specular()`, and + `Py5Shape.set_shininess()` to set the material properties of a `Py5Shape` object. - The ``ambient`` parameter can be applied to the entire ``Py5Shape`` object or to - a single vertex. + The `ambient` parameter can be applied to the entire `Py5Shape` object or to a + single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.setAmbient(*args) @overload def set_emissive(self, emissive: int, /) -> None: - """Sets a ``Py5Shape`` object's emissive color. + """Sets a `Py5Shape` object's emissive color. Underlying Processing method: PShape.setEmissive @@ -4197,20 +4173,20 @@ def set_emissive(self, emissive: int, /) -> None: Notes ----- - Sets a ``Py5Shape`` object's emissive color. This is part of the material - properties of a ``Py5Shape`` object. + Sets a `Py5Shape` object's emissive color. This is part of the material + properties of a `Py5Shape` object. - The ``emissive`` parameter can be applied to the entire ``Py5Shape`` object or - to a single vertex. + The `emissive` parameter can be applied to the entire `Py5Shape` object or to a + single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ pass @overload def set_emissive(self, index: int, emissive: int, /) -> None: - """Sets a ``Py5Shape`` object's emissive color. + """Sets a `Py5Shape` object's emissive color. Underlying Processing method: PShape.setEmissive @@ -4234,20 +4210,20 @@ def set_emissive(self, index: int, emissive: int, /) -> None: Notes ----- - Sets a ``Py5Shape`` object's emissive color. This is part of the material - properties of a ``Py5Shape`` object. + Sets a `Py5Shape` object's emissive color. This is part of the material + properties of a `Py5Shape` object. - The ``emissive`` parameter can be applied to the entire ``Py5Shape`` object or - to a single vertex. + The `emissive` parameter can be applied to the entire `Py5Shape` object or to a + single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ pass @_convert_hex_color2 def set_emissive(self, *args): - """Sets a ``Py5Shape`` object's emissive color. + """Sets a `Py5Shape` object's emissive color. Underlying Processing method: PShape.setEmissive @@ -4271,20 +4247,20 @@ def set_emissive(self, *args): Notes ----- - Sets a ``Py5Shape`` object's emissive color. This is part of the material - properties of a ``Py5Shape`` object. + Sets a `Py5Shape` object's emissive color. This is part of the material + properties of a `Py5Shape` object. - The ``emissive`` parameter can be applied to the entire ``Py5Shape`` object or - to a single vertex. + The `emissive` parameter can be applied to the entire `Py5Shape` object or to a + single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.setEmissive(*args) @overload def set_fill(self, fill: bool, /) -> None: - """The ``set_fill()`` method defines the fill color of a ``Py5Shape``. + """The `set_fill()` method defines the fill color of a `Py5Shape`. Underlying Processing method: PShape.setFill @@ -4312,20 +4288,20 @@ def set_fill(self, fill: bool, /) -> None: Notes ----- - The ``set_fill()`` method defines the fill color of a ``Py5Shape``. This method - is used after shapes are created or when a shape is defined explicitly (e.g. - ``create_shape(RECT, 20, 20, 60, 60)``) as shown in the example. When a shape is - created with ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``, its - attributes may be changed with ``Py5Shape.fill()`` and ``Py5Shape.stroke()`` - between the calls to ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``. - However, after the shape is created, only the ``set_fill()`` method can define a - new fill value for the ``Py5Shape``. + The `set_fill()` method defines the fill color of a `Py5Shape`. This method is + used after shapes are created or when a shape is defined explicitly (e.g. + `create_shape(RECT, 20, 20, 60, 60)`) as shown in the example. When a shape is + created with `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`, its attributes + may be changed with `Py5Shape.fill()` and `Py5Shape.stroke()` between the calls + to `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`. However, after the shape + is created, only the `set_fill()` method can define a new fill value for the + `Py5Shape`. """ pass @overload def set_fill(self, fill: int, /) -> None: - """The ``set_fill()`` method defines the fill color of a ``Py5Shape``. + """The `set_fill()` method defines the fill color of a `Py5Shape`. Underlying Processing method: PShape.setFill @@ -4353,20 +4329,20 @@ def set_fill(self, fill: int, /) -> None: Notes ----- - The ``set_fill()`` method defines the fill color of a ``Py5Shape``. This method - is used after shapes are created or when a shape is defined explicitly (e.g. - ``create_shape(RECT, 20, 20, 60, 60)``) as shown in the example. When a shape is - created with ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``, its - attributes may be changed with ``Py5Shape.fill()`` and ``Py5Shape.stroke()`` - between the calls to ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``. - However, after the shape is created, only the ``set_fill()`` method can define a - new fill value for the ``Py5Shape``. + The `set_fill()` method defines the fill color of a `Py5Shape`. This method is + used after shapes are created or when a shape is defined explicitly (e.g. + `create_shape(RECT, 20, 20, 60, 60)`) as shown in the example. When a shape is + created with `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`, its attributes + may be changed with `Py5Shape.fill()` and `Py5Shape.stroke()` between the calls + to `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`. However, after the shape + is created, only the `set_fill()` method can define a new fill value for the + `Py5Shape`. """ pass @overload def set_fill(self, index: int, fill: int, /) -> None: - """The ``set_fill()`` method defines the fill color of a ``Py5Shape``. + """The `set_fill()` method defines the fill color of a `Py5Shape`. Underlying Processing method: PShape.setFill @@ -4394,21 +4370,21 @@ def set_fill(self, index: int, fill: int, /) -> None: Notes ----- - The ``set_fill()`` method defines the fill color of a ``Py5Shape``. This method - is used after shapes are created or when a shape is defined explicitly (e.g. - ``create_shape(RECT, 20, 20, 60, 60)``) as shown in the example. When a shape is - created with ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``, its - attributes may be changed with ``Py5Shape.fill()`` and ``Py5Shape.stroke()`` - between the calls to ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``. - However, after the shape is created, only the ``set_fill()`` method can define a - new fill value for the ``Py5Shape``. + The `set_fill()` method defines the fill color of a `Py5Shape`. This method is + used after shapes are created or when a shape is defined explicitly (e.g. + `create_shape(RECT, 20, 20, 60, 60)`) as shown in the example. When a shape is + created with `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`, its attributes + may be changed with `Py5Shape.fill()` and `Py5Shape.stroke()` between the calls + to `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`. However, after the shape + is created, only the `set_fill()` method can define a new fill value for the + `Py5Shape`. """ pass @_py5shape_type_fixer @_convert_hex_color2 def set_fill(self, *args): - """The ``set_fill()`` method defines the fill color of a ``Py5Shape``. + """The `set_fill()` method defines the fill color of a `Py5Shape`. Underlying Processing method: PShape.setFill @@ -4436,19 +4412,19 @@ def set_fill(self, *args): Notes ----- - The ``set_fill()`` method defines the fill color of a ``Py5Shape``. This method - is used after shapes are created or when a shape is defined explicitly (e.g. - ``create_shape(RECT, 20, 20, 60, 60)``) as shown in the example. When a shape is - created with ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``, its - attributes may be changed with ``Py5Shape.fill()`` and ``Py5Shape.stroke()`` - between the calls to ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``. - However, after the shape is created, only the ``set_fill()`` method can define a - new fill value for the ``Py5Shape``. + The `set_fill()` method defines the fill color of a `Py5Shape`. This method is + used after shapes are created or when a shape is defined explicitly (e.g. + `create_shape(RECT, 20, 20, 60, 60)`) as shown in the example. When a shape is + created with `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`, its attributes + may be changed with `Py5Shape.fill()` and `Py5Shape.stroke()` between the calls + to `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`. However, after the shape + is created, only the `set_fill()` method can define a new fill value for the + `Py5Shape`. """ return self._instance.setFill(*args) def set_name(self, name: str, /) -> None: - """Assign a name to a ``Py5Shape`` object. + """Assign a name to a `Py5Shape` object. Underlying Processing method: PShape.setName @@ -4461,8 +4437,8 @@ def set_name(self, name: str, /) -> None: Notes ----- - Assign a name to a ``Py5Shape`` object. This can be used to later find the shape - in a ``GROUP`` shape. + Assign a name to a `Py5Shape` object. This can be used to later find the shape + in a `GROUP` shape. """ return self._instance.setName(name) @@ -4485,18 +4461,18 @@ def set_path(self, vcount: int, ----- Set many vertex points at the same time, using a numpy array. This will be - faster and more efficient than repeatedly calling ``Py5Shape.set_vertex()`` in a + faster and more efficient than repeatedly calling `Py5Shape.set_vertex()` in a loop. Setting the vertex codes is not supported, so the vertices will be regular vertices and not bezier, quadratic or curve vertices. - The ``vcount`` parameter cannot be larger than the first dimension of the - ``verts`` array. + The `vcount` parameter cannot be larger than the first dimension of the `verts` + array. """ return self._instance.setPath(vcount, verts) @overload def set_shininess(self, shine: float, /) -> None: - """Sets the amount of gloss a ``Py5Shape`` object's surface has. + """Sets the amount of gloss a `Py5Shape` object's surface has. Underlying Processing method: PShape.setShininess @@ -4520,20 +4496,20 @@ def set_shininess(self, shine: float, /) -> None: Notes ----- - Sets the amount of gloss a ``Py5Shape`` object's surface has. This is part of - the material properties of a ``Py5Shape`` object. + Sets the amount of gloss a `Py5Shape` object's surface has. This is part of the + material properties of a `Py5Shape` object. - The ``shine`` parameter can be applied to the entire ``Py5Shape`` object or to a + The `shine` parameter can be applied to the entire `Py5Shape` object or to a single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ pass @overload def set_shininess(self, index: int, shine: float, /) -> None: - """Sets the amount of gloss a ``Py5Shape`` object's surface has. + """Sets the amount of gloss a `Py5Shape` object's surface has. Underlying Processing method: PShape.setShininess @@ -4557,19 +4533,19 @@ def set_shininess(self, index: int, shine: float, /) -> None: Notes ----- - Sets the amount of gloss a ``Py5Shape`` object's surface has. This is part of - the material properties of a ``Py5Shape`` object. + Sets the amount of gloss a `Py5Shape` object's surface has. This is part of the + material properties of a `Py5Shape` object. - The ``shine`` parameter can be applied to the entire ``Py5Shape`` object or to a + The `shine` parameter can be applied to the entire `Py5Shape` object or to a single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ pass def set_shininess(self, *args): - """Sets the amount of gloss a ``Py5Shape`` object's surface has. + """Sets the amount of gloss a `Py5Shape` object's surface has. Underlying Processing method: PShape.setShininess @@ -4593,21 +4569,21 @@ def set_shininess(self, *args): Notes ----- - Sets the amount of gloss a ``Py5Shape`` object's surface has. This is part of - the material properties of a ``Py5Shape`` object. + Sets the amount of gloss a `Py5Shape` object's surface has. This is part of the + material properties of a `Py5Shape` object. - The ``shine`` parameter can be applied to the entire ``Py5Shape`` object or to a + The `shine` parameter can be applied to the entire `Py5Shape` object or to a single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.setShininess(*args) @overload def set_specular(self, specular: int, /) -> None: - """Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. + """Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Underlying Processing method: PShape.setSpecular @@ -4631,22 +4607,21 @@ def set_specular(self, specular: int, /) -> None: Notes ----- - Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. This is part of the material properties of a ``Py5Shape`` - object. + Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. This is part of the material properties of a `Py5Shape` object. - The ``specular`` parameter can be applied to the entire ``Py5Shape`` object or - to a single vertex. + The `specular` parameter can be applied to the entire `Py5Shape` object or to a + single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ pass @overload def set_specular(self, index: int, specular: int, /) -> None: - """Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. + """Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Underlying Processing method: PShape.setSpecular @@ -4670,22 +4645,21 @@ def set_specular(self, index: int, specular: int, /) -> None: Notes ----- - Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. This is part of the material properties of a ``Py5Shape`` - object. + Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. This is part of the material properties of a `Py5Shape` object. - The ``specular`` parameter can be applied to the entire ``Py5Shape`` object or - to a single vertex. + The `specular` parameter can be applied to the entire `Py5Shape` object or to a + single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ pass @_convert_hex_color2 def set_specular(self, *args): - """Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. + """Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Underlying Processing method: PShape.setSpecular @@ -4709,21 +4683,20 @@ def set_specular(self, *args): Notes ----- - Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. This is part of the material properties of a ``Py5Shape`` - object. + Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. This is part of the material properties of a `Py5Shape` object. - The ``specular`` parameter can be applied to the entire ``Py5Shape`` object or - to a single vertex. + The `specular` parameter can be applied to the entire `Py5Shape` object or to a + single vertex. - This method can only be used for a complete ``Py5Shape`` object, and never - within a ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` pair. + This method can only be used for a complete `Py5Shape` object, and never within + a `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` pair. """ return self._instance.setSpecular(*args) @overload def set_stroke(self, stroke: bool, /) -> None: - """The ``set_stroke()`` method defines the outline color of a ``Py5Shape``. + """The `set_stroke()` method defines the outline color of a `Py5Shape`. Underlying Processing method: PShape.setStroke @@ -4751,20 +4724,20 @@ def set_stroke(self, stroke: bool, /) -> None: Notes ----- - The ``set_stroke()`` method defines the outline color of a ``Py5Shape``. This - method is used after shapes are created or when a shape is defined explicitly - (e.g. ``create_shape(RECT, 20, 20, 60, 60)``) as shown in the example. When a - shape is created with ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``, - its attributes may be changed with ``Py5Shape.fill()`` and ``Py5Shape.stroke()`` - within ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``. However, after - the shape is created, only the ``set_stroke()`` method can define a new stroke - value for the ``Py5Shape``. + The `set_stroke()` method defines the outline color of a `Py5Shape`. This method + is used after shapes are created or when a shape is defined explicitly (e.g. + `create_shape(RECT, 20, 20, 60, 60)`) as shown in the example. When a shape is + created with `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`, its attributes + may be changed with `Py5Shape.fill()` and `Py5Shape.stroke()` within + `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`. However, after the shape is + created, only the `set_stroke()` method can define a new stroke value for the + `Py5Shape`. """ pass @overload def set_stroke(self, stroke: int, /) -> None: - """The ``set_stroke()`` method defines the outline color of a ``Py5Shape``. + """The `set_stroke()` method defines the outline color of a `Py5Shape`. Underlying Processing method: PShape.setStroke @@ -4792,20 +4765,20 @@ def set_stroke(self, stroke: int, /) -> None: Notes ----- - The ``set_stroke()`` method defines the outline color of a ``Py5Shape``. This - method is used after shapes are created or when a shape is defined explicitly - (e.g. ``create_shape(RECT, 20, 20, 60, 60)``) as shown in the example. When a - shape is created with ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``, - its attributes may be changed with ``Py5Shape.fill()`` and ``Py5Shape.stroke()`` - within ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``. However, after - the shape is created, only the ``set_stroke()`` method can define a new stroke - value for the ``Py5Shape``. + The `set_stroke()` method defines the outline color of a `Py5Shape`. This method + is used after shapes are created or when a shape is defined explicitly (e.g. + `create_shape(RECT, 20, 20, 60, 60)`) as shown in the example. When a shape is + created with `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`, its attributes + may be changed with `Py5Shape.fill()` and `Py5Shape.stroke()` within + `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`. However, after the shape is + created, only the `set_stroke()` method can define a new stroke value for the + `Py5Shape`. """ pass @overload def set_stroke(self, index: int, stroke: int, /) -> None: - """The ``set_stroke()`` method defines the outline color of a ``Py5Shape``. + """The `set_stroke()` method defines the outline color of a `Py5Shape`. Underlying Processing method: PShape.setStroke @@ -4833,21 +4806,21 @@ def set_stroke(self, index: int, stroke: int, /) -> None: Notes ----- - The ``set_stroke()`` method defines the outline color of a ``Py5Shape``. This - method is used after shapes are created or when a shape is defined explicitly - (e.g. ``create_shape(RECT, 20, 20, 60, 60)``) as shown in the example. When a - shape is created with ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``, - its attributes may be changed with ``Py5Shape.fill()`` and ``Py5Shape.stroke()`` - within ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``. However, after - the shape is created, only the ``set_stroke()`` method can define a new stroke - value for the ``Py5Shape``. + The `set_stroke()` method defines the outline color of a `Py5Shape`. This method + is used after shapes are created or when a shape is defined explicitly (e.g. + `create_shape(RECT, 20, 20, 60, 60)`) as shown in the example. When a shape is + created with `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`, its attributes + may be changed with `Py5Shape.fill()` and `Py5Shape.stroke()` within + `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`. However, after the shape is + created, only the `set_stroke()` method can define a new stroke value for the + `Py5Shape`. """ pass @_py5shape_type_fixer @_convert_hex_color2 def set_stroke(self, *args): - """The ``set_stroke()`` method defines the outline color of a ``Py5Shape``. + """The `set_stroke()` method defines the outline color of a `Py5Shape`. Underlying Processing method: PShape.setStroke @@ -4875,19 +4848,19 @@ def set_stroke(self, *args): Notes ----- - The ``set_stroke()`` method defines the outline color of a ``Py5Shape``. This - method is used after shapes are created or when a shape is defined explicitly - (e.g. ``create_shape(RECT, 20, 20, 60, 60)``) as shown in the example. When a - shape is created with ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``, - its attributes may be changed with ``Py5Shape.fill()`` and ``Py5Shape.stroke()`` - within ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()``. However, after - the shape is created, only the ``set_stroke()`` method can define a new stroke - value for the ``Py5Shape``. + The `set_stroke()` method defines the outline color of a `Py5Shape`. This method + is used after shapes are created or when a shape is defined explicitly (e.g. + `create_shape(RECT, 20, 20, 60, 60)`) as shown in the example. When a shape is + created with `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`, its attributes + may be changed with `Py5Shape.fill()` and `Py5Shape.stroke()` within + `Py5Shape.begin_shape()` and `Py5Shape.end_shape()`. However, after the shape is + created, only the `set_stroke()` method can define a new stroke value for the + `Py5Shape`. """ return self._instance.setStroke(*args) def set_stroke_cap(self, cap: int, /) -> None: - """Sets the style for rendering line endings in a ``Py5Shape`` object. + """Sets the style for rendering line endings in a `Py5Shape` object. Underlying Processing method: PShape.setStrokeCap @@ -4900,19 +4873,18 @@ def set_stroke_cap(self, cap: int, /) -> None: Notes ----- - Sets the style for rendering line endings in a ``Py5Shape`` object. These ends - are either squared, extended, or rounded, each of which specified with the - corresponding parameters: ``SQUARE``, ``PROJECT``, and ``ROUND``. The default - cap is ``ROUND``. + Sets the style for rendering line endings in a `Py5Shape` object. These ends are + either squared, extended, or rounded, each of which specified with the + corresponding parameters: `SQUARE`, `PROJECT`, and `ROUND`. The default cap is + `ROUND`. - This method differs from ``Py5Shape.stroke_cap()`` in that it is only to be used - outside the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` methods. + This method differs from `Py5Shape.stroke_cap()` in that it is only to be used + outside the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. """ return self._instance.setStrokeCap(cap) def set_stroke_join(self, join: int, /) -> None: - """Sets the style of the joints which connect line segments in a ``Py5Shape`` - object. + """Sets the style of the joints which connect line segments in a `Py5Shape` object. Underlying Processing method: PShape.setStrokeJoin @@ -4925,20 +4897,19 @@ def set_stroke_join(self, join: int, /) -> None: Notes ----- - Sets the style of the joints which connect line segments in a ``Py5Shape`` - object. These joints are either mitered, beveled, or rounded and specified with - the corresponding parameters ``MITER``, ``BEVEL``, and ``ROUND``. The default - joint is ``MITER``. + Sets the style of the joints which connect line segments in a `Py5Shape` object. + These joints are either mitered, beveled, or rounded and specified with the + corresponding parameters `MITER`, `BEVEL`, and `ROUND`. The default joint is + `MITER`. - This method differs from ``Py5Shape.stroke_join()`` in that it is only to be - used outside the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` - methods. + This method differs from `Py5Shape.stroke_join()` in that it is only to be used + outside the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. """ return self._instance.setStrokeJoin(join) @overload def set_stroke_weight(self, weight: float, /) -> None: - """Sets the width of the stroke used for lines and points in a ``Py5Shape`` object. + """Sets the width of the stroke used for lines and points in a `Py5Shape` object. Underlying Processing method: PShape.setStrokeWeight @@ -4962,19 +4933,18 @@ def set_stroke_weight(self, weight: float, /) -> None: Notes ----- - Sets the width of the stroke used for lines and points in a ``Py5Shape`` object. + Sets the width of the stroke used for lines and points in a `Py5Shape` object. All widths are set in units of pixels. Attempting to set this for individual vertices may not work, depending on the renderer used and other factors. - This method differs from ``Py5Shape.stroke_weight()`` in that it is only to be - used outside the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` - methods. + This method differs from `Py5Shape.stroke_weight()` in that it is only to be + used outside the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. """ pass @overload def set_stroke_weight(self, index: int, weight: float, /) -> None: - """Sets the width of the stroke used for lines and points in a ``Py5Shape`` object. + """Sets the width of the stroke used for lines and points in a `Py5Shape` object. Underlying Processing method: PShape.setStrokeWeight @@ -4998,18 +4968,17 @@ def set_stroke_weight(self, index: int, weight: float, /) -> None: Notes ----- - Sets the width of the stroke used for lines and points in a ``Py5Shape`` object. + Sets the width of the stroke used for lines and points in a `Py5Shape` object. All widths are set in units of pixels. Attempting to set this for individual vertices may not work, depending on the renderer used and other factors. - This method differs from ``Py5Shape.stroke_weight()`` in that it is only to be - used outside the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` - methods. + This method differs from `Py5Shape.stroke_weight()` in that it is only to be + used outside the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. """ pass def set_stroke_weight(self, *args): - """Sets the width of the stroke used for lines and points in a ``Py5Shape`` object. + """Sets the width of the stroke used for lines and points in a `Py5Shape` object. Underlying Processing method: PShape.setStrokeWeight @@ -5033,18 +5002,17 @@ def set_stroke_weight(self, *args): Notes ----- - Sets the width of the stroke used for lines and points in a ``Py5Shape`` object. + Sets the width of the stroke used for lines and points in a `Py5Shape` object. All widths are set in units of pixels. Attempting to set this for individual vertices may not work, depending on the renderer used and other factors. - This method differs from ``Py5Shape.stroke_weight()`` in that it is only to be - used outside the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` - methods. + This method differs from `Py5Shape.stroke_weight()` in that it is only to be + used outside the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. """ return self._instance.setStrokeWeight(*args) def set_texture(self, tex: Py5Image, /) -> None: - """Set a ``Py5Shape`` object's texture. + """Set a `Py5Shape` object's texture. Underlying Processing method: PShape.setTexture @@ -5057,21 +5025,20 @@ def set_texture(self, tex: Py5Image, /) -> None: Notes ----- - Set a ``Py5Shape`` object's texture. This method differs from - ``Py5Shape.texture()`` in that it is only to be used outside the - ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` methods. This method - only works with the ``P2D`` and ``P3D`` renderers. This method can be used in - conjunction with ``Py5Shape.set_texture_mode()`` and - ``Py5Shape.set_texture_uv()``. + Set a `Py5Shape` object's texture. This method differs from `Py5Shape.texture()` + in that it is only to be used outside the `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` methods. This method only works with the `P2D` and `P3D` + renderers. This method can be used in conjunction with + `Py5Shape.set_texture_mode()` and `Py5Shape.set_texture_uv()`. When textures are in use, the fill color is ignored. Instead, use - ``Py5Shape.tint()`` to specify the color of the texture as it is applied to the + `Py5Shape.tint()` to specify the color of the texture as it is applied to the shape. """ return self._instance.setTexture(tex) def set_texture_mode(self, mode: int, /) -> None: - """Sets a ``Py5Shape`` object's coordinate space for texture mapping. + """Sets a `Py5Shape` object's coordinate space for texture mapping. Underlying Processing method: PShape.setTextureMode @@ -5084,24 +5051,24 @@ def set_texture_mode(self, mode: int, /) -> None: Notes ----- - Sets a ``Py5Shape`` object's coordinate space for texture mapping. This method - differs from ``Py5Shape.texture_mode()`` in that it is only to be used outside - the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` methods. Use of this - method should be followed by calls to ``Py5Shape.set_texture_uv()`` to set the - mapping coordinates using the new mode. + Sets a `Py5Shape` object's coordinate space for texture mapping. This method + differs from `Py5Shape.texture_mode()` in that it is only to be used outside the + `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. Use of this method + should be followed by calls to `Py5Shape.set_texture_uv()` to set the mapping + coordinates using the new mode. - The default mode is ``IMAGE``, which refers to the actual pixel coordinates of - the image. ``NORMAL`` refers to a normalized space of values ranging from 0 to - 1. This function only works with the ``P2D`` and ``P3D`` renderers. + The default mode is `IMAGE`, which refers to the actual pixel coordinates of the + image. `NORMAL` refers to a normalized space of values ranging from 0 to 1. This + function only works with the `P2D` and `P3D` renderers. - With ``IMAGE``, if an image is 100 x 200 pixels, mapping the image onto the - entire size of a quad would require the points (0,0) (100,0) (100,200) (0,200). - The same mapping in ``NORMAL`` is (0,0) (1,0) (1,1) (0,1). + With `IMAGE`, if an image is 100 x 200 pixels, mapping the image onto the entire + size of a quad would require the points (0,0) (100,0) (100,200) (0,200). The + same mapping in `NORMAL` is (0,0) (1,0) (1,1) (0,1). """ return self._instance.setTextureMode(mode) def set_texture_uv(self, index: int, u: float, v: float, /) -> None: - """Set the uv texture mapping coordinates for a given vertex in a ``Py5Shape`` + """Set the uv texture mapping coordinates for a given vertex in a `Py5Shape` object. Underlying Processing method: PShape.setTextureUV @@ -5121,14 +5088,14 @@ def set_texture_uv(self, index: int, u: float, v: float, /) -> None: Notes ----- - Set the uv texture mapping coordinates for a given vertex in a ``Py5Shape`` - object. This method can only be used outside the ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` methods. + Set the uv texture mapping coordinates for a given vertex in a `Py5Shape` + object. This method can only be used outside the `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` methods. - The ``u`` and ``v`` coordinates define the mapping of a ``Py5Shape`` object's - texture to the form. By default, the coordinates used for ``u`` and ``v`` are - specified in relation to the image's size in pixels, but this relation can be - changed with the ``Py5Shape`` object's ``Py5Shape.set_texture_mode()`` method. + The `u` and `v` coordinates define the mapping of a `Py5Shape` object's texture + to the form. By default, the coordinates used for `u` and `v` are specified in + relation to the image's size in pixels, but this relation can be changed with + the `Py5Shape` object's `Py5Shape.set_texture_mode()` method. """ return self._instance.setTextureUV(index, u, v) @@ -5168,13 +5135,13 @@ def set_tint(self, tint: bool, /) -> None: Apply a color tint to a shape's texture map. This can be done for either the entire shape or one vertex. - This method differs from ``Py5Shape.tint()`` in that it is only to be used - outside the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` methods. - This method only works with the ``P2D`` and ``P3D`` renderers. + This method differs from `Py5Shape.tint()` in that it is only to be used outside + the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. This method + only works with the `P2D` and `P3D` renderers. - Calling this method with the boolean parameter ``False`` will delete the - assigned tint. A later call with the boolean parameter ``True`` will not restore - it; you must reassign the tint color, as shown in the second example. + Calling this method with the boolean parameter `False` will delete the assigned + tint. A later call with the boolean parameter `True` will not restore it; you + must reassign the tint color, as shown in the second example. """ pass @@ -5214,13 +5181,13 @@ def set_tint(self, fill: int, /) -> None: Apply a color tint to a shape's texture map. This can be done for either the entire shape or one vertex. - This method differs from ``Py5Shape.tint()`` in that it is only to be used - outside the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` methods. - This method only works with the ``P2D`` and ``P3D`` renderers. + This method differs from `Py5Shape.tint()` in that it is only to be used outside + the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. This method + only works with the `P2D` and `P3D` renderers. - Calling this method with the boolean parameter ``False`` will delete the - assigned tint. A later call with the boolean parameter ``True`` will not restore - it; you must reassign the tint color, as shown in the second example. + Calling this method with the boolean parameter `False` will delete the assigned + tint. A later call with the boolean parameter `True` will not restore it; you + must reassign the tint color, as shown in the second example. """ pass @@ -5260,13 +5227,13 @@ def set_tint(self, index: int, tint: int, /) -> None: Apply a color tint to a shape's texture map. This can be done for either the entire shape or one vertex. - This method differs from ``Py5Shape.tint()`` in that it is only to be used - outside the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` methods. - This method only works with the ``P2D`` and ``P3D`` renderers. + This method differs from `Py5Shape.tint()` in that it is only to be used outside + the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. This method + only works with the `P2D` and `P3D` renderers. - Calling this method with the boolean parameter ``False`` will delete the - assigned tint. A later call with the boolean parameter ``True`` will not restore - it; you must reassign the tint color, as shown in the second example. + Calling this method with the boolean parameter `False` will delete the assigned + tint. A later call with the boolean parameter `True` will not restore it; you + must reassign the tint color, as shown in the second example. """ pass @@ -5307,20 +5274,20 @@ def set_tint(self, *args): Apply a color tint to a shape's texture map. This can be done for either the entire shape or one vertex. - This method differs from ``Py5Shape.tint()`` in that it is only to be used - outside the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` methods. - This method only works with the ``P2D`` and ``P3D`` renderers. + This method differs from `Py5Shape.tint()` in that it is only to be used outside + the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. This method + only works with the `P2D` and `P3D` renderers. - Calling this method with the boolean parameter ``False`` will delete the - assigned tint. A later call with the boolean parameter ``True`` will not restore - it; you must reassign the tint color, as shown in the second example. + Calling this method with the boolean parameter `False` will delete the assigned + tint. A later call with the boolean parameter `True` will not restore it; you + must reassign the tint color, as shown in the second example. """ return self._instance.setTint(*args) @overload def set_vertex(self, index: int, x: float, y: float, /) -> None: - """The ``set_vertex()`` method defines the coordinates of the vertex point located - at the position defined by the ``index`` parameter. + """The `set_vertex()` method defines the coordinates of the vertex point located at + the position defined by the `index` parameter. Underlying Processing method: PShape.setVertex @@ -5354,17 +5321,17 @@ def set_vertex(self, index: int, x: float, y: float, /) -> None: Notes ----- - The ``set_vertex()`` method defines the coordinates of the vertex point located - at the position defined by the ``index`` parameter. This method works when - shapes are created as shown in the example, but won't work properly when a shape - is defined explicitly (e.g. ``create_shape(RECT, 20, 20, 80, 80)``. + The `set_vertex()` method defines the coordinates of the vertex point located at + the position defined by the `index` parameter. This method works when shapes are + created as shown in the example, but won't work properly when a shape is defined + explicitly (e.g. `create_shape(RECT, 20, 20, 80, 80)`. """ pass @overload def set_vertex(self, index: int, x: float, y: float, z: float, /) -> None: - """The ``set_vertex()`` method defines the coordinates of the vertex point located - at the position defined by the ``index`` parameter. + """The `set_vertex()` method defines the coordinates of the vertex point located at + the position defined by the `index` parameter. Underlying Processing method: PShape.setVertex @@ -5398,17 +5365,17 @@ def set_vertex(self, index: int, x: float, y: float, z: float, /) -> None: Notes ----- - The ``set_vertex()`` method defines the coordinates of the vertex point located - at the position defined by the ``index`` parameter. This method works when - shapes are created as shown in the example, but won't work properly when a shape - is defined explicitly (e.g. ``create_shape(RECT, 20, 20, 80, 80)``. + The `set_vertex()` method defines the coordinates of the vertex point located at + the position defined by the `index` parameter. This method works when shapes are + created as shown in the example, but won't work properly when a shape is defined + explicitly (e.g. `create_shape(RECT, 20, 20, 80, 80)`. """ pass @overload def set_vertex(self, index: int, vec: Py5Vector, /) -> None: - """The ``set_vertex()`` method defines the coordinates of the vertex point located - at the position defined by the ``index`` parameter. + """The `set_vertex()` method defines the coordinates of the vertex point located at + the position defined by the `index` parameter. Underlying Processing method: PShape.setVertex @@ -5442,16 +5409,16 @@ def set_vertex(self, index: int, vec: Py5Vector, /) -> None: Notes ----- - The ``set_vertex()`` method defines the coordinates of the vertex point located - at the position defined by the ``index`` parameter. This method works when - shapes are created as shown in the example, but won't work properly when a shape - is defined explicitly (e.g. ``create_shape(RECT, 20, 20, 80, 80)``. + The `set_vertex()` method defines the coordinates of the vertex point located at + the position defined by the `index` parameter. This method works when shapes are + created as shown in the example, but won't work properly when a shape is defined + explicitly (e.g. `create_shape(RECT, 20, 20, 80, 80)`. """ pass def set_vertex(self, *args): - """The ``set_vertex()`` method defines the coordinates of the vertex point located - at the position defined by the ``index`` parameter. + """The `set_vertex()` method defines the coordinates of the vertex point located at + the position defined by the `index` parameter. Underlying Processing method: PShape.setVertex @@ -5485,10 +5452,10 @@ def set_vertex(self, *args): Notes ----- - The ``set_vertex()`` method defines the coordinates of the vertex point located - at the position defined by the ``index`` parameter. This method works when - shapes are created as shown in the example, but won't work properly when a shape - is defined explicitly (e.g. ``create_shape(RECT, 20, 20, 80, 80)``. + The `set_vertex()` method defines the coordinates of the vertex point located at + the position defined by the `index` parameter. This method works when shapes are + created as shown in the example, but won't work properly when a shape is defined + explicitly (e.g. `create_shape(RECT, 20, 20, 80, 80)`. """ return self._instance.setVertex(*args) @@ -5501,13 +5468,13 @@ def set_visible(self, visible: bool, /) -> None: ---------- visible: bool - ``False`` makes the shape invisible and ``True`` makes it visible + False makes the shape invisible and True makes it visible Notes ----- Sets the shape to be visible or invisible. This is determined by the value of - the ``visible`` parameter. + the `visible` parameter. The default visibility of a shape is usually controlled by whatever program created the SVG file. For instance, this parameter is controlled by showing or @@ -5516,7 +5483,7 @@ def set_visible(self, visible: bool, /) -> None: return self._instance.setVisible(visible) def shininess(self, shine: float, /) -> None: - """Sets the amount of gloss in the surface of a ``Py5Shape`` object. + """Sets the amount of gloss in the surface of a `Py5Shape` object. Underlying Processing method: PShape.shininess @@ -5529,20 +5496,20 @@ def shininess(self, shine: float, /) -> None: Notes ----- - Sets the amount of gloss in the surface of a ``Py5Shape`` object. Use in - combination with ``Py5Shape.ambient()``, ``Py5Shape.specular()``, and - ``Py5Shape.emissive()`` to set the material properties of a ``Py5Shape`` object. + Sets the amount of gloss in the surface of a `Py5Shape` object. Use in + combination with `Py5Shape.ambient()`, `Py5Shape.specular()`, and + `Py5Shape.emissive()` to set the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The shininess color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The shininess color setting will be applied to vertices added after the call to this method. """ return self._instance.shininess(shine) @overload def specular(self, gray: float, /) -> None: - """Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. + """Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Underlying Processing method: PShape.specular @@ -5576,23 +5543,22 @@ def specular(self, gray: float, /) -> None: Notes ----- - Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. Specular refers to light which bounces off a surface in a + Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a diffuse - light). Use in combination with ``Py5Shape.emissive()``, ``Py5Shape.ambient()``, - and ``Py5Shape.shininess()`` to set the material properties of a ``Py5Shape`` - object. + light). Use in combination with `Py5Shape.emissive()`, `Py5Shape.ambient()`, and + `Py5Shape.shininess()` to set the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The specular color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The specular color setting will be applied to vertices added after the call to this method. """ pass @overload def specular(self, x: float, y: float, z: float, /) -> None: - """Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. + """Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Underlying Processing method: PShape.specular @@ -5626,23 +5592,22 @@ def specular(self, x: float, y: float, z: float, /) -> None: Notes ----- - Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. Specular refers to light which bounces off a surface in a + Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a diffuse - light). Use in combination with ``Py5Shape.emissive()``, ``Py5Shape.ambient()``, - and ``Py5Shape.shininess()`` to set the material properties of a ``Py5Shape`` - object. + light). Use in combination with `Py5Shape.emissive()`, `Py5Shape.ambient()`, and + `Py5Shape.shininess()` to set the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The specular color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The specular color setting will be applied to vertices added after the call to this method. """ pass @overload def specular(self, rgb: int, /) -> None: - """Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. + """Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Underlying Processing method: PShape.specular @@ -5676,23 +5641,22 @@ def specular(self, rgb: int, /) -> None: Notes ----- - Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. Specular refers to light which bounces off a surface in a + Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a diffuse - light). Use in combination with ``Py5Shape.emissive()``, ``Py5Shape.ambient()``, - and ``Py5Shape.shininess()`` to set the material properties of a ``Py5Shape`` - object. + light). Use in combination with `Py5Shape.emissive()`, `Py5Shape.ambient()`, and + `Py5Shape.shininess()` to set the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The specular color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The specular color setting will be applied to vertices added after the call to this method. """ pass @_convert_hex_color() def specular(self, *args): - """Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. + """Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Underlying Processing method: PShape.specular @@ -5726,22 +5690,21 @@ def specular(self, *args): Notes ----- - Sets the specular color of a ``Py5Shape`` object's material, which sets the - color of highlight. Specular refers to light which bounces off a surface in a + Sets the specular color of a `Py5Shape` object's material, which sets the color + of highlight. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a diffuse - light). Use in combination with ``Py5Shape.emissive()``, ``Py5Shape.ambient()``, - and ``Py5Shape.shininess()`` to set the material properties of a ``Py5Shape`` - object. + light). Use in combination with `Py5Shape.emissive()`, `Py5Shape.ambient()`, and + `Py5Shape.shininess()` to set the material properties of a `Py5Shape` object. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. The specular color setting will be applied to + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. The specular color setting will be applied to vertices added after the call to this method. """ return self._instance.specular(*args) @overload def stroke(self, gray: float, /) -> None: - """Sets the color used to draw the ``Py5Shape`` object's lines. + """Sets the color used to draw the `Py5Shape` object's lines. Underlying Processing method: PShape.stroke @@ -5781,42 +5744,41 @@ def stroke(self, gray: float, /) -> None: Notes ----- - Sets the color used to draw the ``Py5Shape`` object's lines. This color is - either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + Sets the color used to draw the `Py5Shape` object's lines. This color is either + specified in terms of the RGB or HSB color depending on the current + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @overload def stroke(self, gray: float, alpha: float, /) -> None: - """Sets the color used to draw the ``Py5Shape`` object's lines. + """Sets the color used to draw the `Py5Shape` object's lines. Underlying Processing method: PShape.stroke @@ -5856,42 +5818,41 @@ def stroke(self, gray: float, alpha: float, /) -> None: Notes ----- - Sets the color used to draw the ``Py5Shape`` object's lines. This color is - either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + Sets the color used to draw the `Py5Shape` object's lines. This color is either + specified in terms of the RGB or HSB color depending on the current + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @overload def stroke(self, x: float, y: float, z: float, /) -> None: - """Sets the color used to draw the ``Py5Shape`` object's lines. + """Sets the color used to draw the `Py5Shape` object's lines. Underlying Processing method: PShape.stroke @@ -5931,42 +5892,41 @@ def stroke(self, x: float, y: float, z: float, /) -> None: Notes ----- - Sets the color used to draw the ``Py5Shape`` object's lines. This color is - either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + Sets the color used to draw the `Py5Shape` object's lines. This color is either + specified in terms of the RGB or HSB color depending on the current + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @overload def stroke(self, x: float, y: float, z: float, alpha: float, /) -> None: - """Sets the color used to draw the ``Py5Shape`` object's lines. + """Sets the color used to draw the `Py5Shape` object's lines. Underlying Processing method: PShape.stroke @@ -6006,42 +5966,41 @@ def stroke(self, x: float, y: float, z: float, alpha: float, /) -> None: Notes ----- - Sets the color used to draw the ``Py5Shape`` object's lines. This color is - either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + Sets the color used to draw the `Py5Shape` object's lines. This color is either + specified in terms of the RGB or HSB color depending on the current + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @overload def stroke(self, rgb: int, /) -> None: - """Sets the color used to draw the ``Py5Shape`` object's lines. + """Sets the color used to draw the `Py5Shape` object's lines. Underlying Processing method: PShape.stroke @@ -6081,42 +6040,41 @@ def stroke(self, rgb: int, /) -> None: Notes ----- - Sets the color used to draw the ``Py5Shape`` object's lines. This color is - either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + Sets the color used to draw the `Py5Shape` object's lines. This color is either + specified in terms of the RGB or HSB color depending on the current + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @overload def stroke(self, rgb: int, alpha: float, /) -> None: - """Sets the color used to draw the ``Py5Shape`` object's lines. + """Sets the color used to draw the `Py5Shape` object's lines. Underlying Processing method: PShape.stroke @@ -6156,42 +6114,41 @@ def stroke(self, rgb: int, alpha: float, /) -> None: Notes ----- - Sets the color used to draw the ``Py5Shape`` object's lines. This color is - either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + Sets the color used to draw the `Py5Shape` object's lines. This color is either + specified in terms of the RGB or HSB color depending on the current + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @_convert_hex_color() def stroke(self, *args): - """Sets the color used to draw the ``Py5Shape`` object's lines. + """Sets the color used to draw the `Py5Shape` object's lines. Underlying Processing method: PShape.stroke @@ -6231,41 +6188,40 @@ def stroke(self, *args): Notes ----- - Sets the color used to draw the ``Py5Shape`` object's lines. This color is - either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + Sets the color used to draw the `Py5Shape` object's lines. This color is either + specified in terms of the RGB or HSB color depending on the current + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ return self._instance.stroke(*args) def stroke_cap(self, cap: int, /) -> None: - """Sets the style for rendering line endings in a ``Py5Shape`` object. + """Sets the style for rendering line endings in a `Py5Shape` object. Underlying Processing method: PShape.strokeCap @@ -6278,19 +6234,18 @@ def stroke_cap(self, cap: int, /) -> None: Notes ----- - Sets the style for rendering line endings in a ``Py5Shape`` object. These ends - are either squared, extended, or rounded, each of which specified with the - corresponding parameters: ``SQUARE``, ``PROJECT``, and ``ROUND``. The default - cap is ``ROUND``. + Sets the style for rendering line endings in a `Py5Shape` object. These ends are + either squared, extended, or rounded, each of which specified with the + corresponding parameters: `SQUARE`, `PROJECT`, and `ROUND`. The default cap is + `ROUND`. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ return self._instance.strokeCap(cap) def stroke_join(self, join: int, /) -> None: - """Sets the style of the joints which connect line segments in a ``Py5Shape`` - object. + """Sets the style of the joints which connect line segments in a `Py5Shape` object. Underlying Processing method: PShape.strokeJoin @@ -6303,18 +6258,18 @@ def stroke_join(self, join: int, /) -> None: Notes ----- - Sets the style of the joints which connect line segments in a ``Py5Shape`` - object. These joints are either mitered, beveled, or rounded and specified with - the corresponding parameters ``MITER``, ``BEVEL``, and ``ROUND``. The default - joint is ``MITER``. + Sets the style of the joints which connect line segments in a `Py5Shape` object. + These joints are either mitered, beveled, or rounded and specified with the + corresponding parameters `MITER`, `BEVEL`, and `ROUND`. The default joint is + `MITER`. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ return self._instance.strokeJoin(join) def stroke_weight(self, weight: float, /) -> None: - """Sets the width of the stroke used for lines and points in a ``Py5Shape`` object. + """Sets the width of the stroke used for lines and points in a `Py5Shape` object. Underlying Processing method: PShape.strokeWeight @@ -6327,16 +6282,16 @@ def stroke_weight(self, weight: float, /) -> None: Notes ----- - Sets the width of the stroke used for lines and points in a ``Py5Shape`` object. + Sets the width of the stroke used for lines and points in a `Py5Shape` object. All widths are set in units of pixels. - This method can only be used within a ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` pair. + This method can only be used within a `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` pair. """ return self._instance.strokeWeight(weight) def texture(self, tex: Py5Image, /) -> None: - """Sets a texture to be applied to a ``Py5Shape`` object's vertex points. + """Sets a texture to be applied to a `Py5Shape` object's vertex points. Underlying Processing method: PShape.texture @@ -6349,19 +6304,19 @@ def texture(self, tex: Py5Image, /) -> None: Notes ----- - Sets a texture to be applied to a ``Py5Shape`` object's vertex points. The - ``texture()`` function must be called between ``Py5Shape.begin_shape()`` and - ``Py5Shape.end_shape()`` and before any calls to ``Py5Shape.vertex()``. This - method only works with the ``P2D`` and ``P3D`` renderers. + Sets a texture to be applied to a `Py5Shape` object's vertex points. The + `texture()` function must be called between `Py5Shape.begin_shape()` and + `Py5Shape.end_shape()` and before any calls to `Py5Shape.vertex()`. This method + only works with the `P2D` and `P3D` renderers. When textures are in use, the fill color is ignored. Instead, use - ``Py5Shape.tint()`` to specify the color of the texture as it is applied to the + `Py5Shape.tint()` to specify the color of the texture as it is applied to the shape. """ return self._instance.texture(tex) def texture_mode(self, mode: int, /) -> None: - """Sets a ``Py5Shape`` object's coordinate space for texture mapping. + """Sets a `Py5Shape` object's coordinate space for texture mapping. Underlying Processing method: PShape.textureMode @@ -6374,17 +6329,17 @@ def texture_mode(self, mode: int, /) -> None: Notes ----- - Sets a ``Py5Shape`` object's coordinate space for texture mapping. The default - mode is ``IMAGE``, which refers to the actual pixel coordinates of the image. - ``NORMAL`` refers to a normalized space of values ranging from 0 to 1. This - function only works with the ``P2D`` and ``P3D`` renderers. + Sets a `Py5Shape` object's coordinate space for texture mapping. The default + mode is `IMAGE`, which refers to the actual pixel coordinates of the image. + `NORMAL` refers to a normalized space of values ranging from 0 to 1. This + function only works with the `P2D` and `P3D` renderers. If this method is not used, it will inherit the current texture mode setting from the Sketch when the shape is created. - With ``IMAGE``, if an image is 100 x 200 pixels, mapping the image onto the - entire size of a quad would require the points (0,0) (100,0) (100,200) (0,200). - The same mapping in ``NORMAL`` is (0,0) (1,0) (1,1) (0,1). + With `IMAGE`, if an image is 100 x 200 pixels, mapping the image onto the entire + size of a quad would require the points (0,0) (100,0) (100,200) (0,200). The + same mapping in `NORMAL` is (0,0) (1,0) (1,1) (0,1). """ return self._instance.textureMode(mode) @@ -6431,35 +6386,34 @@ def tint(self, gray: float, /) -> None: ----- Apply a color tint to a shape's texture map. The tint will be applied only to - vertices after the call to ``tint()``. Use ``Py5Shape.no_tint()`` to deactivate - the tint. + vertices after the call to `tint()`. Use `Py5Shape.no_tint()` to deactivate the + tint. Images can be tinted to specified colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use - white as the tint color and specify an alpha value. For instance, ``tint(255, - 128)`` will make an image 50% transparent (assuming the default alpha range of - 0-255, which can be changed with ``color_mode()``). + white as the tint color and specify an alpha value. For instance, `tint(255, + 128)` will make an image 50% transparent (assuming the default alpha range of + 0-255, which can be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -6506,35 +6460,34 @@ def tint(self, gray: float, alpha: float, /) -> None: ----- Apply a color tint to a shape's texture map. The tint will be applied only to - vertices after the call to ``tint()``. Use ``Py5Shape.no_tint()`` to deactivate - the tint. + vertices after the call to `tint()`. Use `Py5Shape.no_tint()` to deactivate the + tint. Images can be tinted to specified colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use - white as the tint color and specify an alpha value. For instance, ``tint(255, - 128)`` will make an image 50% transparent (assuming the default alpha range of - 0-255, which can be changed with ``color_mode()``). + white as the tint color and specify an alpha value. For instance, `tint(255, + 128)` will make an image 50% transparent (assuming the default alpha range of + 0-255, which can be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -6581,35 +6534,34 @@ def tint(self, x: float, y: float, z: float, /) -> None: ----- Apply a color tint to a shape's texture map. The tint will be applied only to - vertices after the call to ``tint()``. Use ``Py5Shape.no_tint()`` to deactivate - the tint. + vertices after the call to `tint()`. Use `Py5Shape.no_tint()` to deactivate the + tint. Images can be tinted to specified colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use - white as the tint color and specify an alpha value. For instance, ``tint(255, - 128)`` will make an image 50% transparent (assuming the default alpha range of - 0-255, which can be changed with ``color_mode()``). + white as the tint color and specify an alpha value. For instance, `tint(255, + 128)` will make an image 50% transparent (assuming the default alpha range of + 0-255, which can be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -6656,35 +6608,34 @@ def tint(self, x: float, y: float, z: float, alpha: float, /) -> None: ----- Apply a color tint to a shape's texture map. The tint will be applied only to - vertices after the call to ``tint()``. Use ``Py5Shape.no_tint()`` to deactivate - the tint. + vertices after the call to `tint()`. Use `Py5Shape.no_tint()` to deactivate the + tint. Images can be tinted to specified colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use - white as the tint color and specify an alpha value. For instance, ``tint(255, - 128)`` will make an image 50% transparent (assuming the default alpha range of - 0-255, which can be changed with ``color_mode()``). + white as the tint color and specify an alpha value. For instance, `tint(255, + 128)` will make an image 50% transparent (assuming the default alpha range of + 0-255, which can be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -6731,35 +6682,34 @@ def tint(self, rgb: int, /) -> None: ----- Apply a color tint to a shape's texture map. The tint will be applied only to - vertices after the call to ``tint()``. Use ``Py5Shape.no_tint()`` to deactivate - the tint. + vertices after the call to `tint()`. Use `Py5Shape.no_tint()` to deactivate the + tint. Images can be tinted to specified colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use - white as the tint color and specify an alpha value. For instance, ``tint(255, - 128)`` will make an image 50% transparent (assuming the default alpha range of - 0-255, which can be changed with ``color_mode()``). + white as the tint color and specify an alpha value. For instance, `tint(255, + 128)` will make an image 50% transparent (assuming the default alpha range of + 0-255, which can be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -6806,35 +6756,34 @@ def tint(self, rgb: int, alpha: float, /) -> None: ----- Apply a color tint to a shape's texture map. The tint will be applied only to - vertices after the call to ``tint()``. Use ``Py5Shape.no_tint()`` to deactivate - the tint. + vertices after the call to `tint()`. Use `Py5Shape.no_tint()` to deactivate the + tint. Images can be tinted to specified colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use - white as the tint color and specify an alpha value. For instance, ``tint(255, - 128)`` will make an image 50% transparent (assuming the default alpha range of - 0-255, which can be changed with ``color_mode()``). + white as the tint color and specify an alpha value. For instance, `tint(255, + 128)` will make an image 50% transparent (assuming the default alpha range of + 0-255, which can be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -6881,35 +6830,34 @@ def tint(self, *args): ----- Apply a color tint to a shape's texture map. The tint will be applied only to - vertices after the call to ``tint()``. Use ``Py5Shape.no_tint()`` to deactivate - the tint. + vertices after the call to `tint()`. Use `Py5Shape.no_tint()` to deactivate the + tint. Images can be tinted to specified colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use - white as the tint color and specify an alpha value. For instance, ``tint(255, - 128)`` will make an image 50% transparent (assuming the default alpha range of - 0-255, which can be changed with ``color_mode()``). + white as the tint color and specify an alpha value. For instance, `tint(255, + 128)` will make an image 50% transparent (assuming the default alpha range of + 0-255, which can be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ return self._instance.tint(*args) @@ -6942,16 +6890,16 @@ def translate(self, x: float, y: float, /) -> None: Notes ----- - Specifies an amount to displace the shape. The ``x`` parameter specifies - left/right translation, the ``y`` parameter specifies up/down translation, and - the ``z`` parameter specifies translations toward/away from the screen. - Subsequent calls to the method accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. This transformation is applied directly to the shape, it's - not refreshed each time ``draw()`` is run. + Specifies an amount to displace the shape. The `x` parameter specifies + left/right translation, the `y` parameter specifies up/down translation, and the + `z` parameter specifies translations toward/away from the screen. Subsequent + calls to the method accumulates the effect. For example, calling `translate(50, + 0)` and then `translate(20, 0)` is the same as `translate(70, 0)`. This + transformation is applied directly to the shape, it's not refreshed each time + `draw()` is run. - Using this method with the ``z`` parameter requires using the ``P3D`` parameter - in combination with size. + Using this method with the `z` parameter requires using the `P3D` parameter in + combination with size. """ pass @@ -6984,16 +6932,16 @@ def translate(self, x: float, y: float, z: float, /) -> None: Notes ----- - Specifies an amount to displace the shape. The ``x`` parameter specifies - left/right translation, the ``y`` parameter specifies up/down translation, and - the ``z`` parameter specifies translations toward/away from the screen. - Subsequent calls to the method accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. This transformation is applied directly to the shape, it's - not refreshed each time ``draw()`` is run. + Specifies an amount to displace the shape. The `x` parameter specifies + left/right translation, the `y` parameter specifies up/down translation, and the + `z` parameter specifies translations toward/away from the screen. Subsequent + calls to the method accumulates the effect. For example, calling `translate(50, + 0)` and then `translate(20, 0)` is the same as `translate(70, 0)`. This + transformation is applied directly to the shape, it's not refreshed each time + `draw()` is run. - Using this method with the ``z`` parameter requires using the ``P3D`` parameter - in combination with size. + Using this method with the `z` parameter requires using the `P3D` parameter in + combination with size. """ pass @@ -7025,22 +6973,22 @@ def translate(self, *args): Notes ----- - Specifies an amount to displace the shape. The ``x`` parameter specifies - left/right translation, the ``y`` parameter specifies up/down translation, and - the ``z`` parameter specifies translations toward/away from the screen. - Subsequent calls to the method accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. This transformation is applied directly to the shape, it's - not refreshed each time ``draw()`` is run. + Specifies an amount to displace the shape. The `x` parameter specifies + left/right translation, the `y` parameter specifies up/down translation, and the + `z` parameter specifies translations toward/away from the screen. Subsequent + calls to the method accumulates the effect. For example, calling `translate(50, + 0)` and then `translate(20, 0)` is the same as `translate(70, 0)`. This + transformation is applied directly to the shape, it's not refreshed each time + `draw()` is run. - Using this method with the ``z`` parameter requires using the ``P3D`` parameter - in combination with size. + Using this method with the `z` parameter requires using the `P3D` parameter in + combination with size. """ return self._instance.translate(*args) @overload def vertex(self, x: float, y: float, /) -> None: - """Add a new vertex to a ``Py5Shape`` object. + """Add a new vertex to a `Py5Shape` object. Underlying Processing method: PShape.vertex @@ -7075,28 +7023,28 @@ def vertex(self, x: float, y: float, /) -> None: Notes ----- - Add a new vertex to a ``Py5Shape`` object. All shapes are constructed by - connecting a series of vertices. The ``vertex()`` method is used to specify the + Add a new vertex to a `Py5Shape` object. All shapes are constructed by + connecting a series of vertices. The `vertex()` method is used to specify the vertex coordinates for points, lines, triangles, quads, and polygons. It is used - exclusively within the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` + exclusively within the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. This method is also used to map a texture onto geometry. The - ``Py5Shape.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Shape`` object's ``Py5Shape.texture_mode()`` method or by calling the - Sketch's ``texture_mode()`` method before the shape is created. + `Py5Shape.texture()` function declares the texture to apply to the geometry and + the `u` and `v` coordinates define the mapping of this texture to the form. By + default, the coordinates used for `u` and `v` are specified in relation to the + image's size in pixels, but this relation can be changed with the `Py5Shape` + object's `Py5Shape.texture_mode()` method or by calling the Sketch's + `texture_mode()` method before the shape is created. """ pass @overload def vertex(self, x: float, y: float, z: float, /) -> None: - """Add a new vertex to a ``Py5Shape`` object. + """Add a new vertex to a `Py5Shape` object. Underlying Processing method: PShape.vertex @@ -7131,28 +7079,28 @@ def vertex(self, x: float, y: float, z: float, /) -> None: Notes ----- - Add a new vertex to a ``Py5Shape`` object. All shapes are constructed by - connecting a series of vertices. The ``vertex()`` method is used to specify the + Add a new vertex to a `Py5Shape` object. All shapes are constructed by + connecting a series of vertices. The `vertex()` method is used to specify the vertex coordinates for points, lines, triangles, quads, and polygons. It is used - exclusively within the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` + exclusively within the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. This method is also used to map a texture onto geometry. The - ``Py5Shape.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Shape`` object's ``Py5Shape.texture_mode()`` method or by calling the - Sketch's ``texture_mode()`` method before the shape is created. + `Py5Shape.texture()` function declares the texture to apply to the geometry and + the `u` and `v` coordinates define the mapping of this texture to the form. By + default, the coordinates used for `u` and `v` are specified in relation to the + image's size in pixels, but this relation can be changed with the `Py5Shape` + object's `Py5Shape.texture_mode()` method or by calling the Sketch's + `texture_mode()` method before the shape is created. """ pass @overload def vertex(self, x: float, y: float, u: float, v: float, /) -> None: - """Add a new vertex to a ``Py5Shape`` object. + """Add a new vertex to a `Py5Shape` object. Underlying Processing method: PShape.vertex @@ -7187,29 +7135,29 @@ def vertex(self, x: float, y: float, u: float, v: float, /) -> None: Notes ----- - Add a new vertex to a ``Py5Shape`` object. All shapes are constructed by - connecting a series of vertices. The ``vertex()`` method is used to specify the + Add a new vertex to a `Py5Shape` object. All shapes are constructed by + connecting a series of vertices. The `vertex()` method is used to specify the vertex coordinates for points, lines, triangles, quads, and polygons. It is used - exclusively within the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` + exclusively within the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. This method is also used to map a texture onto geometry. The - ``Py5Shape.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Shape`` object's ``Py5Shape.texture_mode()`` method or by calling the - Sketch's ``texture_mode()`` method before the shape is created. + `Py5Shape.texture()` function declares the texture to apply to the geometry and + the `u` and `v` coordinates define the mapping of this texture to the form. By + default, the coordinates used for `u` and `v` are specified in relation to the + image's size in pixels, but this relation can be changed with the `Py5Shape` + object's `Py5Shape.texture_mode()` method or by calling the Sketch's + `texture_mode()` method before the shape is created. """ pass @overload def vertex(self, x: float, y: float, z: float, u: float, v: float, /) -> None: - """Add a new vertex to a ``Py5Shape`` object. + """Add a new vertex to a `Py5Shape` object. Underlying Processing method: PShape.vertex @@ -7244,27 +7192,27 @@ def vertex(self, x: float, y: float, z: float, Notes ----- - Add a new vertex to a ``Py5Shape`` object. All shapes are constructed by - connecting a series of vertices. The ``vertex()`` method is used to specify the + Add a new vertex to a `Py5Shape` object. All shapes are constructed by + connecting a series of vertices. The `vertex()` method is used to specify the vertex coordinates for points, lines, triangles, quads, and polygons. It is used - exclusively within the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` + exclusively within the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. This method is also used to map a texture onto geometry. The - ``Py5Shape.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Shape`` object's ``Py5Shape.texture_mode()`` method or by calling the - Sketch's ``texture_mode()`` method before the shape is created. + `Py5Shape.texture()` function declares the texture to apply to the geometry and + the `u` and `v` coordinates define the mapping of this texture to the form. By + default, the coordinates used for `u` and `v` are specified in relation to the + image's size in pixels, but this relation can be changed with the `Py5Shape` + object's `Py5Shape.texture_mode()` method or by calling the Sketch's + `texture_mode()` method before the shape is created. """ pass def vertex(self, *args): - """Add a new vertex to a ``Py5Shape`` object. + """Add a new vertex to a `Py5Shape` object. Underlying Processing method: PShape.vertex @@ -7299,21 +7247,21 @@ def vertex(self, *args): Notes ----- - Add a new vertex to a ``Py5Shape`` object. All shapes are constructed by - connecting a series of vertices. The ``vertex()`` method is used to specify the + Add a new vertex to a `Py5Shape` object. All shapes are constructed by + connecting a series of vertices. The `vertex()` method is used to specify the vertex coordinates for points, lines, triangles, quads, and polygons. It is used - exclusively within the ``Py5Shape.begin_shape()`` and ``Py5Shape.end_shape()`` + exclusively within the `Py5Shape.begin_shape()` and `Py5Shape.end_shape()` methods. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. This method is also used to map a texture onto geometry. The - ``Py5Shape.texture()`` function declares the texture to apply to the geometry - and the ``u`` and ``v`` coordinates define the mapping of this texture to the - form. By default, the coordinates used for ``u`` and ``v`` are specified in - relation to the image's size in pixels, but this relation can be changed with - the ``Py5Shape`` object's ``Py5Shape.texture_mode()`` method or by calling the - Sketch's ``texture_mode()`` method before the shape is created. + `Py5Shape.texture()` function declares the texture to apply to the geometry and + the `u` and `v` coordinates define the mapping of this texture to the form. By + default, the coordinates used for `u` and `v` are specified in relation to the + image's size in pixels, but this relation can be changed with the `Py5Shape` + object's `Py5Shape.texture_mode()` method or by calling the Sketch's + `texture_mode()` method before the shape is created. """ return self._instance.vertex(*args) diff --git a/py5/sketch.py b/py5/sketch.py index 1edf808..d047a58 100644 --- a/py5/sketch.py +++ b/py5/sketch.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -26,7 +26,9 @@ import warnings from io import BytesIO from pathlib import Path +import inspect import functools +import types import uuid from typing import overload, Any, Callable, Union # noqa @@ -51,14 +53,17 @@ from .graphics import Py5Graphics, _return_py5graphics # noqa from .keyevent import Py5KeyEvent, _convert_jchar_to_chr, _convert_jint_to_int # noqa from .mouseevent import Py5MouseEvent # noqa +from .utilities import Py5Utilities from .decorators import _text_fix_str, _convert_hex_color, _context_wrapper # noqa from .pmath import _get_matrix_wrapper # noqa from . import image_conversion from .image_conversion import NumpyImageArray, _convertable +from . import spelling from . import reference _Sketch = jpype.JClass('py5.core.Sketch') +_SketchBase = jpype.JClass('py5.core.SketchBase') try: @@ -77,15 +82,28 @@ _PY5_LAST_WINDOW_Y = None -def _auto_convert_to_py5image(f): +def _auto_convert_to_py5image(argnum): + def _decorator(f): + @functools.wraps(f) + def decorated(self_, *args): + if len(args) > argnum: + args = list(args) + img = args[argnum] + if isinstance(img, NumpyImageArray): + args[argnum] = self_.create_image_from_numpy( + img.array, img.bands) + elif not isinstance(img, (Py5Image, Py5Graphics)) and _convertable(img): + args[argnum] = self_.convert_image(img) + return f(self_, *args) + return decorated + return _decorator + + +def _generator_to_list(f): @functools.wraps(f) def decorated(self_, *args): - args_index = args[0] - if isinstance(args_index, NumpyImageArray): - args = self_.create_image_from_numpy( - args_index.array, args_index.bands), *args[1:] - elif not isinstance(args_index, (Py5Image, Py5Graphics)) and _convertable(args_index): - args = self_.convert_image(args_index), *args[1:] + if isinstance(args[0], types.GeneratorType): + args = list(args[0]), *args[1:] return f(self_, *args) return decorated @@ -120,32 +138,32 @@ class Sketch( ----- Core py5 class for leveraging py5's functionality. This is analogous to the - PApplet class in Processing. Launch the Sketch with the ``run_sketch()`` method. - - The core functions to be implemented by the py5 coder are ``settings``, - ``setup``, and ``draw``. The first two will be run once at Sketch initialization - and the third will be run in an animation thread, once per frame. The following - event functions are also supported: - - * ``exiting`` - * ``key_pressed`` - * ``key_released`` - * ``key_typed`` - * ``mouse_clicked`` - * ``mouse_dragged`` - * ``mouse_entered`` - * ``mouse_exited`` - * ``mouse_moved`` - * ``mouse_pressed`` - * ``mouse_released`` - * ``mouse_wheel`` - * ``movie_event`` - * ``post_draw`` - * ``pre_draw`` + PApplet class in Processing. Launch the Sketch with the `run_sketch()` method. + + The core functions to be implemented by the py5 coder are `settings`, `setup`, + and `draw`. The first two will be run once at Sketch initialization and the + third will be run in an animation thread, once per frame. The following event + functions are also supported: + + * `exiting` + * `key_pressed` + * `key_released` + * `key_typed` + * `mouse_clicked` + * `mouse_dragged` + * `mouse_entered` + * `mouse_exited` + * `mouse_moved` + * `mouse_pressed` + * `mouse_released` + * `mouse_wheel` + * `movie_event` + * `post_draw` + * `pre_draw` When coding in class mode, all of the above functions should be class methods. When coding in module mode or imported mode, the above functions should be - stand-alone functions available in the local namespace in which ``run_sketch()`` + stand-alone functions available in the local namespace in which `run_sketch()` was called. """ _py5_object_cache = set() @@ -154,8 +172,10 @@ class Sketch( def __new__(cls, *args, **kwargs): _instance = kwargs.get('_instance') + # remove dead or malformed Sketch instances from the object cache cls._py5_object_cache = set( - s for s in cls._py5_object_cache if not s.is_dead) + s for s in cls._py5_object_cache if hasattr( + s, '_instance') and not s.is_dead) if _instance: for s in cls._py5_object_cache: if _instance == s._instance: @@ -170,7 +190,7 @@ def __new__(cls, *args, **kwargs): def __init__(self, *args, **kwargs): _instance = kwargs.get('_instance') - _jclassname = kwargs.get('_jclassname') + jclassname = kwargs.get('jclassname') if _instance: if _instance == getattr(self, '_instance', None): @@ -180,11 +200,11 @@ def __init__(self, *args, **kwargs): raise RuntimeError( 'Unexpected Situation: Passed py5.core.Sketch instance does not match existing py5.core.Sketch instance. What is going on?') - Sketch._cls = JClass(_jclassname) if _jclassname else _Sketch + Sketch._cls = JClass(jclassname) if jclassname else _Sketch instance = Sketch._cls() - if not isinstance(instance, _Sketch): + if not isinstance(instance, _SketchBase): raise RuntimeError( - 'Java instance must inherit from py5.core.Sketch') + 'Java instance must inherit from py5.core.SketchBase') super().__init__(instance=instance) self._methods_to_profile = [] @@ -196,21 +216,25 @@ def __init__(self, *args, **kwargs): self._py5_bridge = None self._environ = None iconPath = Path(__file__).parent.parent / \ - 'py5_tools/kernel/resources/logo-64x64.png' - if iconPath.exists(): + 'py5_tools/resources/logo-64x64.png' + if iconPath.exists() and hasattr(self._instance, 'setPy5IconPath'): self._instance.setPy5IconPath(str(iconPath)) elif hasattr(sys, '_MEIPASS'): warnings.warn( "py5 logo image cannot be found. You are running this Sketch with pyinstaller and the image is missing from the packaging. I'm going to nag you about this until you fix it.", stacklevel=3) Sketch._cls.setJOGLProperties(str(Path(__file__).parent)) + self.utils = Py5Utilities(self) - # attempt to instantiate Py5Utilities - self.utils = None - try: - self.utils = jpype.JClass('py5utils.Py5Utilities')(self._instance) - except Exception: - pass + def __str__(self): + return f"Sketch(width=" + str(self._get_width()) + ", height=" + str( + self._get_height()) + ", renderer=" + str(self._instance.getRendererName()) + ")" + + def __repr__(self): + return self.__str__() + + def __getattr__(self, name): + raise AttributeError(spelling.error_msg('Sketch', name, self)) def run_sketch(self, block: bool = None, *, py5_options: list = None, sketch_args: list = None, @@ -223,6 +247,9 @@ def run_sketch(self, block: bool = None, *, block: bool = None method returns immediately (False) or blocks until Sketch exits (True) + jclassname: str = None + canonical name of class to instantiate when using py5 in processing mode + py5_options: list[str] = None command line arguments to pass to Processing as arguments @@ -235,56 +262,58 @@ def run_sketch(self, block: bool = None, *, Notes ----- - Run the Sketch. Code in the ``settings()``, ``setup()``, and ``draw()`` - functions will be used to actualize your Sketch. - - Use the ``block`` parameter to specify if the call to ``run_sketch()`` should - return immediately (asynchronous Sketch execution) or block until the Sketch - exits. If the ``block`` parameter is not specified, py5 will first attempt to - determine if the Sketch is running in a Jupyter Notebook or an IPython shell. If - it is, ``block`` will default to ``False``, and ``True`` otherwise. + Run the Sketch. Code in the `settings()`, `setup()`, and `draw()` functions will + be used to actualize your Sketch. - Blocking is not supported on OSX. This is because of the (current) limitations - of py5 on OSX. If the ``block`` parameter is set to ``True``, a warning message - will appear and it will be changed to ``False``. + Use the `block` parameter to specify if the call to `run_sketch()` should return + immediately (asynchronous Sketch execution) or block until the Sketch exits. If + the `block` parameter is not specified, py5 will first attempt to determine if + the Sketch is running in a Jupyter Notebook or an IPython shell. If it is, + `block` will default to `False`, and `True` otherwise. However, on OSX, these + default values are required, as py5 cannot work on OSX without them. - A list of strings passed to ``py5_options`` will be passed to the Processing + A list of strings passed to `py5_options` will be passed to the Processing PApplet class as arguments to specify characteristics such as the window's - location on the screen. A list of strings passed to ``sketch_args`` will be - available to a running Sketch using ``pargs``. See the third example for an + location on the screen. A list of strings passed to `sketch_args` will be + available to a running Sketch using `pargs`. See the third example for an example of how this can be used. - When calling ``run_sketch()`` in module mode, py5 will by default search for - functions such as ``setup()``, ``draw()``, etc. in the caller's stack frame and - use those in the Sketch. If for some reason that is not what you want or does - not work because you are hacking py5 to do something unusual, you can use the - ``sketch_functions`` parameter to pass a dictionary of the desired callable - functions. The ``sketch_functions`` parameter is not available when coding py5 - in class mode. Don't forget you can always replace the ``draw()`` function in a - running Sketch using ``hot_reload_draw()``. + When calling `run_sketch()` in module mode, py5 will by default search for + functions such as `setup()`, `draw()`, etc. in the caller's stack frame and use + those in the Sketch. If for some reason that is not what you want or does not + work because you are hacking py5 to do something unusual, you can use the + `sketch_functions` parameter to pass a dictionary of the desired callable + functions. The `sketch_functions` parameter is not available when coding py5 in + class mode. Don't forget you can always replace the `draw()` function in a + running Sketch using `hot_reload_draw()`. When programming in module mode and imported mode, py5 will inspect the - ``setup()`` function and will attempt to split it into synthetic ``settings()`` - and ``setup()`` functions if both were not created by the user and the real - ``setup()`` function contains calls to ``size()``, ``full_screen()``, - ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to those functions - must be at the very beginning of ``setup()``, before any other Python code - (except for comments). This feature allows the user to omit the ``settings()`` - function, much like what can be done while programming in the Processing IDE. - This feature is not available when programming in class mode. - - When running a Sketch asynchronously through Jupyter Notebook, any ``print`` + `setup()` function and will attempt to split it into synthetic `settings()` and + `setup()` functions if both were not created by the user and the real `setup()` + function contains calls to `size()`, `full_screen()`, `smooth()`, `no_smooth()`, + or `pixel_density()`. Calls to those functions must be at the very beginning of + `setup()`, before any other Python code (except for comments). This feature + allows the user to omit the `settings()` function, much like what can be done + while programming in the Processing IDE. This feature is not available when + programming in class mode. + + When running a Sketch asynchronously through Jupyter Notebook, any `print` statements using Python's builtin function will always appear in the output of the currently active cell. This will rarely be desirable, as the active cell will keep changing as the user executes code elsewhere in the notebook. As an - alternative, use py5's ``println()`` method, which will place all text in the - output of the cell that made the ``run_sketch()`` call. This will continue to be + alternative, use py5's `println()` method, which will place all text in the + output of the cell that made the `run_sketch()` call. This will continue to be true if the user moves on to execute code in other Notebook cells. Use - ``set_println_stream()`` to customize this behavior. All py5 error messages and - stack traces are routed through the ``println()`` method. Be aware that some - error messages and warnings generated inside the Processing Jars cannot be - controlled in the same way, and may appear in the output of the active cell or - mixed in with the Jupyter Kernel logs.""" + `set_println_stream()` to customize this behavior. All py5 error messages and + stack traces are routed through the `println()` method. Be aware that some error + messages and warnings generated inside the Processing Jars cannot be controlled + in the same way, and may appear in the output of the active cell or mixed in + with the Jupyter Kernel logs. + + The `jclassname` parameter should only be used when programming in Processing + Mode. This value must be the canonical name of your Processing Sketch class + (i.e. `"org.test.MySketch"`). The class must inherit from `py5.core.SketchBase`. + Read py5's online documentation to learn more about Processing Mode.""" if not hasattr(self, '_instance'): raise RuntimeError( ('py5 internal problem: did you create a class with an `__init__()` ' @@ -317,7 +346,10 @@ def _run_sketch(self, self._py5_bridge.profile_functions(self._methods_to_profile) self._py5_bridge.add_pre_hooks(self._pre_hooks_to_add) self._py5_bridge.add_post_hooks(self._post_hooks_to_add) - self._instance.buildPy5Bridge(self._py5_bridge) + self._instance.buildPy5Bridge( + self._py5_bridge, + self._environ.in_ipython_session, + self._environ.in_jupyter_zmq_shell) if not py5_options: py5_options = [] @@ -336,7 +368,7 @@ def _run_sketch(self, try: if _osx_alt_run_method and platform.system() == 'Darwin': - from PyObjCTools import AppHelper + from PyObjCTools import AppHelper # type: ignore def run(): Sketch._cls.runSketch(args, self._instance) @@ -399,7 +431,8 @@ def run(): def _shutdown(self): global _PY5_LAST_WINDOW_X global _PY5_LAST_WINDOW_Y - if self._instance.lastWindowX is not None and self._instance.lastWindowY is not None: + if (hasattr(self._instance, 'lastWindowX') and hasattr(self._instance, 'lastWindowY') + and self._instance.lastWindowX is not None and self._instance.lastWindowY is not None): _PY5_LAST_WINDOW_X = int(self._instance.lastWindowX) _PY5_LAST_WINDOW_Y = int(self._instance.lastWindowY) super()._shutdown() @@ -469,12 +502,12 @@ def sketch_path(self) -> Path: Notes ----- - The Sketch's current path. If the ``where`` parameter is used, the result will - be a subdirectory of the current path. + The Sketch's current path. If the `where` parameter is used, the result will be + a subdirectory of the current path. - Result will be relative to Python's current working directory (``os.getcwd()``) - unless it was specifically set to something else with the ``run_sketch()`` call - by including a ``--sketch-path`` argument in the ``py5_options`` parameters.""" + Result will be relative to Python's current working directory (`os.getcwd()`) + unless it was specifically set to something else with the `run_sketch()` call by + including a `--sketch-path` argument in the `py5_options` parameters.""" pass @overload @@ -500,12 +533,12 @@ def sketch_path(self, where: str, /) -> Path: Notes ----- - The Sketch's current path. If the ``where`` parameter is used, the result will - be a subdirectory of the current path. + The Sketch's current path. If the `where` parameter is used, the result will be + a subdirectory of the current path. - Result will be relative to Python's current working directory (``os.getcwd()``) - unless it was specifically set to something else with the ``run_sketch()`` call - by including a ``--sketch-path`` argument in the ``py5_options`` parameters.""" + Result will be relative to Python's current working directory (`os.getcwd()`) + unless it was specifically set to something else with the `run_sketch()` call by + including a `--sketch-path` argument in the `py5_options` parameters.""" pass def sketch_path(self, *args) -> Path: @@ -530,12 +563,12 @@ def sketch_path(self, *args) -> Path: Notes ----- - The Sketch's current path. If the ``where`` parameter is used, the result will - be a subdirectory of the current path. + The Sketch's current path. If the `where` parameter is used, the result will be + a subdirectory of the current path. - Result will be relative to Python's current working directory (``os.getcwd()``) - unless it was specifically set to something else with the ``run_sketch()`` call - by including a ``--sketch-path`` argument in the ``py5_options`` parameters.""" + Result will be relative to Python's current working directory (`os.getcwd()`) + unless it was specifically set to something else with the `run_sketch()` call by + including a `--sketch-path` argument in the `py5_options` parameters.""" if not self.is_running: msg = ( "Calling method sketch_path() when Sketch is not running. " + @@ -558,8 +591,8 @@ def _get_is_ready(self) -> bool: ----- Boolean value reflecting if the Sketch is in the ready state. This will be - ``True`` before ``run_sketch()`` is called. It will be ``False`` while the - Sketch is running and after it has exited.""" + `True` before `run_sketch()` is called. It will be `False` while the Sketch is + running and after it has exited.""" surface = self.get_surface() # if there is no surface yet, the sketch can be run. return surface._instance is None @@ -571,8 +604,8 @@ def _get_is_ready(self) -> bool: ----- Boolean value reflecting if the Sketch is in the ready state. This will be - ``True`` before ``run_sketch()`` is called. It will be ``False`` while the - Sketch is running and after it has exited.""") + `True` before `run_sketch()` is called. It will be `False` while the Sketch is + running and after it has exited.""") def _get_is_running(self) -> bool: """Boolean value reflecting if the Sketch is in the running state. @@ -581,8 +614,8 @@ def _get_is_running(self) -> bool: ----- Boolean value reflecting if the Sketch is in the running state. This will be - ``False`` before ``run_sketch()`` is called and ``True`` after. It will be - ``False`` again after the Sketch has exited.""" + `False` before `run_sketch()` is called and `True` after. It will be `False` + again after the Sketch has exited.""" surface = self.get_surface() if surface._instance is None: # Sketch has not been run yet @@ -597,8 +630,8 @@ def _get_is_running(self) -> bool: ----- Boolean value reflecting if the Sketch is in the running state. This will be - ``False`` before ``run_sketch()`` is called and ``True`` after. It will be - ``False`` again after the Sketch has exited.""") + `False` before `run_sketch()` is called and `True` after. It will be `False` + again after the Sketch has exited.""") def _get_is_dead(self) -> bool: """Boolean value reflecting if the Sketch has been run and has now stopped. @@ -607,13 +640,13 @@ def _get_is_dead(self) -> bool: ----- Boolean value reflecting if the Sketch has been run and has now stopped. This - will be ``True`` after calling ``exit_sketch()`` or if the Sketch throws an - error and stops. This will also be ``True`` after calling ``Py5Surface``'s - ``Py5Surface.stop_thread()`` method. Once a Sketch reaches the "dead" state, it + will be `True` after calling `exit_sketch()` or if the Sketch throws an error + and stops. This will also be `True` after calling `Py5Surface`'s + `Py5Surface.stop_thread()` method. Once a Sketch reaches the "dead" state, it cannot be rerun. - After an error or a call to ``Py5Surface.stop_thread()``, the Sketch window will - still be open. Call ``exit_sketch()`` to close the window.""" + After an error or a call to `Py5Surface.stop_thread()`, the Sketch window will + still be open. Call `exit_sketch()` to close the window.""" surface = self.get_surface() if surface._instance is None: # Sketch has not been run yet @@ -627,13 +660,13 @@ def _get_is_dead(self) -> bool: ----- Boolean value reflecting if the Sketch has been run and has now stopped. This - will be ``True`` after calling ``exit_sketch()`` or if the Sketch throws an - error and stops. This will also be ``True`` after calling ``Py5Surface``'s - ``Py5Surface.stop_thread()`` method. Once a Sketch reaches the "dead" state, it + will be `True` after calling `exit_sketch()` or if the Sketch throws an error + and stops. This will also be `True` after calling `Py5Surface`'s + `Py5Surface.stop_thread()` method. Once a Sketch reaches the "dead" state, it cannot be rerun. - After an error or a call to ``Py5Surface.stop_thread()``, the Sketch window will - still be open. Call ``exit_sketch()`` to close the window.""") + After an error or a call to `Py5Surface.stop_thread()`, the Sketch window will + still be open. Call `exit_sketch()` to close the window.""") def _get_is_dead_from_error(self) -> bool: """Boolean value reflecting if the Sketch has been run and has now stopped because @@ -643,8 +676,8 @@ def _get_is_dead_from_error(self) -> bool: ----- Boolean value reflecting if the Sketch has been run and has now stopped because - of an error. This will be ``True`` only when ``is_dead`` is ``True`` and the - Sketch stopped because an exception was thrown.""" + of an error. This will be `True` only when `is_dead` is `True` and the Sketch + stopped because an exception was thrown.""" return self.is_dead and not self._instance.getSuccess() is_dead_from_error: bool = property( fget=_get_is_dead_from_error, @@ -655,62 +688,60 @@ def _get_is_dead_from_error(self) -> bool: ----- Boolean value reflecting if the Sketch has been run and has now stopped because - of an error. This will be ``True`` only when ``is_dead`` is ``True`` and the - Sketch stopped because an exception was thrown.""") + of an error. This will be `True` only when `is_dead` is `True` and the Sketch + stopped because an exception was thrown.""") def _get_is_mouse_pressed(self) -> bool: - """The ``is_mouse_pressed`` variable stores whether or not a mouse button is + """The `is_mouse_pressed` variable stores whether or not a mouse button is currently being pressed. Notes ----- - The ``is_mouse_pressed`` variable stores whether or not a mouse button is - currently being pressed. The value is ``True`` when `any` mouse button is - pressed, and ``False`` if no button is pressed. The ``mouse_button`` variable - (see the related reference entry) can be used to determine which button has been - pressed.""" + The `is_mouse_pressed` variable stores whether or not a mouse button is + currently being pressed. The value is `True` when `any` mouse button is pressed, + and `False` if no button is pressed. The `mouse_button` variable (see the + related reference entry) can be used to determine which button has been pressed.""" return self._instance.isMousePressed() is_mouse_pressed: bool = property( fget=_get_is_mouse_pressed, - doc="""The ``is_mouse_pressed`` variable stores whether or not a mouse button is + doc="""The `is_mouse_pressed` variable stores whether or not a mouse button is currently being pressed. Notes ----- - The ``is_mouse_pressed`` variable stores whether or not a mouse button is - currently being pressed. The value is ``True`` when `any` mouse button is - pressed, and ``False`` if no button is pressed. The ``mouse_button`` variable - (see the related reference entry) can be used to determine which button has been - pressed.""") + The `is_mouse_pressed` variable stores whether or not a mouse button is + currently being pressed. The value is `True` when `any` mouse button is pressed, + and `False` if no button is pressed. The `mouse_button` variable (see the + related reference entry) can be used to determine which button has been pressed.""") def _get_is_key_pressed(self) -> bool: - """The ``is_key_pressed`` variable stores whether or not a keyboard button is + """The `is_key_pressed` variable stores whether or not a keyboard button is currently being pressed. Notes ----- - The ``is_key_pressed`` variable stores whether or not a keyboard button is + The `is_key_pressed` variable stores whether or not a keyboard button is currently being pressed. The value is true when `any` keyboard button is - pressed, and false if no button is pressed. The ``key`` variable and - ``key_code`` variables (see the related reference entries) can be used to - determine which button has been pressed.""" + pressed, and false if no button is pressed. The `key` variable and `key_code` + variables (see the related reference entries) can be used to determine which + button has been pressed.""" return self._instance.isKeyPressed() is_key_pressed: bool = property( fget=_get_is_key_pressed, - doc="""The ``is_key_pressed`` variable stores whether or not a keyboard button is + doc="""The `is_key_pressed` variable stores whether or not a keyboard button is currently being pressed. Notes ----- - The ``is_key_pressed`` variable stores whether or not a keyboard button is + The `is_key_pressed` variable stores whether or not a keyboard button is currently being pressed. The value is true when `any` keyboard button is - pressed, and false if no button is pressed. The ``key`` variable and - ``key_code`` variables (see the related reference entries) can be used to - determine which button has been pressed.""") + pressed, and false if no button is pressed. The `key` variable and `key_code` + variables (see the related reference entries) can be used to determine which + button has been pressed.""") def hot_reload_draw(self, draw: Callable) -> None: """Perform a hot reload of the Sketch's draw function. @@ -752,14 +783,14 @@ def profile_functions(self, function_names: list[str]) -> None: information can be used to target the performance tuning efforts for a slow Sketch. - This method can be called before or after ``run_sketch()``. You are welcome to + This method can be called before or after `run_sketch()`. You are welcome to profile multiple functions, but don't initiate profiling on the same function multiple times. To profile functions that do not belong to the Sketch, including - any functions called from ``launch_thread()`` and the like, use lineprofiler + any functions called from `launch_thread()` and the like, use lineprofiler directly and not through py5's performance tools. - To profile just the draw function, you can also use ``profile_draw()``. To see - the results, use ``print_line_profiler_stats()``.""" + To profile just the draw function, you can also use `profile_draw()`. To see the + results, use `print_line_profiler_stats()`.""" if self._py5_bridge is None: self._methods_to_profile.extend(function_names) else: @@ -777,28 +808,28 @@ def profile_draw(self) -> None: (Hits) and the total amount of time spent on each line (Time). This information can be used to target the performance tuning efforts for a slow Sketch. - This method can be called before or after ``run_sketch()``. You are welcome to + This method can be called before or after `run_sketch()`. You are welcome to profile multiple functions, but don't initiate profiling on the same function multiple times. To profile functions that do not belong to the Sketch, including - any functions called from ``launch_thread()`` and the like, use lineprofiler + any functions called from `launch_thread()` and the like, use lineprofiler directly and not through py5's performance tools. - To profile a other functions besides draw, use ``profile_functions()``. To see - the results, use ``print_line_profiler_stats()``.""" + To profile a other functions besides draw, use `profile_functions()`. To see the + results, use `print_line_profiler_stats()`.""" self.profile_functions(['draw']) def print_line_profiler_stats(self) -> None: - """Print the line profiler stats initiated with ``profile_draw()`` or - ``profile_functions()``. + """Print the line profiler stats initiated with `profile_draw()` or + `profile_functions()`. Notes ----- - Print the line profiler stats initiated with ``profile_draw()`` or - ``profile_functions()``. The collected stats will include the number of times - each line of code was executed (Hits) and the total amount of time spent on each - line (Time). This information can be used to target the performance tuning - efforts for a slow Sketch. + Print the line profiler stats initiated with `profile_draw()` or + `profile_functions()`. The collected stats will include the number of times each + line of code was executed (Hits) and the total amount of time spent on each line + (Time). This information can be used to target the performance tuning efforts + for a slow Sketch. This method can be called multiple times on a running Sketch.""" self._py5_bridge.dump_stats() @@ -856,17 +887,17 @@ def save_frame(self, to write the image, so it can save images in any format that that library supports. - Use the ``drop_alpha`` parameter to drop the alpha channel from the image. This - defaults to ``True``. Some image formats such as JPG do not support alpha + Use the `drop_alpha` parameter to drop the alpha channel from the image. This + defaults to `True`. Some image formats such as JPG do not support alpha channels, and Pillow will throw an error if you try to save an image with the alpha channel in that format. - The ``use_thread`` parameter will save the image in a separate Python thread. - This improves performance by returning before the image has actually been - written to the file. + The `use_thread` parameter will save the image in a separate Python thread. This + improves performance by returning before the image has actually been written to + the file. - This method is the same as ``save()`` except it will replace a sequence of ``#`` - symbols in the ``filename`` parameter with the frame number. This is useful when + This method is the same as `save()` except it will replace a sequence of `#` + symbols in the `filename` parameter with the frame number. This is useful when saving an image sequence for a running animation. The first frame number will be 1.""" if not isinstance(filename, BytesIO): @@ -900,15 +931,15 @@ def select_folder(self, prompt: str, callback: Callable, ----- Opens a file chooser dialog to select a folder. After the selection is made, the - selection will be passed to the ``callback`` function. If the dialog is closed - or canceled, ``None`` will be sent to the function, so that the program is not + selection will be passed to the `callback` function. If the dialog is closed or + canceled, `None` will be sent to the function, so that the program is not waiting for additional input. The callback is necessary because of how threading works. This method has some platform specific quirks. On OSX, this does not work when the Sketch is run through a Jupyter notebook. On Windows, Sketches using the - OpenGL renderers (``P2D`` or ``P3D``) will be minimized while the select dialog - box is open. This method only uses native dialog boxes on OSX.""" + OpenGL renderers (`P2D` or `P3D`) will be minimized while the select dialog box + is open. This method only uses native dialog boxes on OSX.""" if not isinstance( prompt, str) or not callable(callback) or ( @@ -949,15 +980,15 @@ def select_input( ----- Opens a file chooser dialog to select a folder. After the selection is made, the - selection will be passed to the ``callback`` function. If the dialog is closed - or canceled, ``None`` will be sent to the function, so that the program is not + selection will be passed to the `callback` function. If the dialog is closed or + canceled, `None` will be sent to the function, so that the program is not waiting for additional input. The callback is necessary because of how threading works. This method has some platform specific quirks. On OSX, this does not work when the Sketch is run through a Jupyter notebook. On Windows, Sketches using the - OpenGL renderers (``P2D`` or ``P3D``) will be minimized while the select dialog - box is open. This method only uses native dialog boxes on OSX.""" + OpenGL renderers (`P2D` or `P3D`) will be minimized while the select dialog box + is open. This method only uses native dialog boxes on OSX.""" if not isinstance( prompt, str) or not callable(callback) or ( @@ -998,15 +1029,15 @@ def select_output( ----- Opens a file chooser dialog to select a folder. After the selection is made, the - selection will be passed to the ``callback`` function. If the dialog is closed - or canceled, ``None`` will be sent to the function, so that the program is not + selection will be passed to the `callback` function. If the dialog is closed or + canceled, `None` will be sent to the function, so that the program is not waiting for additional input. The callback is necessary because of how threading works. This method has some platform specific quirks. On OSX, this does not work when the Sketch is run through a Jupyter notebook. On Windows, Sketches using the - OpenGL renderers (``P2D`` or ``P3D``) will be minimized while the select dialog - box is open. This method only uses native dialog boxes on OSX.""" + OpenGL renderers (`P2D` or `P3D`) will be minimized while the select dialog box + is open. This method only uses native dialog boxes on OSX.""" if not isinstance( prompt, str) or not callable(callback) or ( @@ -1029,9 +1060,20 @@ def _generic_select( prompt: str, callback: Callable, default_folder: str = None) -> None: + callback_sig = inspect.signature(callback) + if len(callback_sig.parameters) != 1 or list(callback_sig.parameters.values())[ + 0].kind == inspect.Parameter.KEYWORD_ONLY: + raise RuntimeError( + "The callback function must have one and only one positional argument") + key = "_PY5_SELECT_CALLBACK_" + str(uuid.uuid4()) + + def wrapped_callback_py5_no_prune(selection): + return callback( + selection if selection is None else Path(selection)) + py5_tools.config.register_processing_mode_key( - key, callback, callback_once=True) + key, wrapped_callback_py5_no_prune, callback_once=True) if platform.system() == 'Darwin': if self._environ.in_ipython_session: @@ -1072,20 +1114,20 @@ def create_image_from_numpy(self, ----- Convert a numpy array into a Py5Image object. The numpy array must have 3 - dimensions and the array's ``dtype`` must be ``np.uint8``. The size of - ``array``'s first and second dimensions will be the image's height and width, - respectively. The third dimension is for the array's color channels. + dimensions and the array's `dtype` must be `np.uint8`. The size of `array`'s + first and second dimensions will be the image's height and width, respectively. + The third dimension is for the array's color channels. - The ``bands`` parameter is used to interpret the ``array``'s color channel - dimension (the array's third dimension). It can be one of ``'L'`` (single- - channel grayscale), ``'ARGB'``, ``'RGB'``, or ``'RGBA'``. If there is no alpha - channel, ``array`` is assumed to have no transparency. If the ``bands`` - parameter is ``'L'``, ``array``'s third dimension is optional. + The `bands` parameter is used to interpret the `array`'s color channel dimension + (the array's third dimension). It can be one of `'L'` (single-channel + grayscale), `'ARGB'`, `'RGB'`, or `'RGBA'`. If there is no alpha channel, + `array` is assumed to have no transparency. If the `bands` parameter is `'L'`, + `array`'s third dimension is optional. The caller can optionally pass an existing Py5Image object to put the image data - into using the ``dst`` parameter. This can have performance benefits in code - that would otherwise continuously create new Py5Image objects. The array's width - and height must match that of the recycled Py5Image object.""" + into using the `dst` parameter. This can have performance benefits in code that + would otherwise continuously create new Py5Image objects. The array's width and + height must match that of the recycled Py5Image object.""" height, width = array.shape[:2] if dst: @@ -1118,23 +1160,21 @@ def convert_image(self, obj: Any, *, dst: Py5Image = None) -> Py5Image: Convert non-py5 image objects into Py5Image objects. This facilitates py5 compatability with other commonly used Python libraries. - This method is comparable to ``load_image()``, except instead of reading image + This method is comparable to `load_image()`, except instead of reading image files from disk, it reads image data from other Python objects. Passed image object types must be known to py5's image conversion tools. New object types and functions to effect conversions can be registered with - ``register_image_conversion()``. + `register_image_conversion()`. - The ``convert_image()`` method has builtin support for conversion of - ``PIL.Image`` objects. This will allow users to use image formats that - ``load_image()`` cannot read. To convert a numpy array into a Py5Image, use - ``create_image_from_numpy()``. + The `convert_image()` method has builtin support for conversion of `PIL.Image` + objects. This will allow users to use image formats that `load_image()` cannot + read. To convert a numpy array into a Py5Image, use `create_image_from_numpy()`. The caller can optionally pass an existing Py5Image object to put the converted - image into using the ``dst`` parameter. This can have performance benefits in - code that would otherwise continuously create new Py5Image objects. The - converted image width and height must match that of the recycled Py5Image - object.""" + image into using the `dst` parameter. This can have performance benefits in code + that would otherwise continuously create new Py5Image objects. The converted + image width and height must match that of the recycled Py5Image object.""" result = image_conversion._convert(obj) if isinstance(result, (Path, str)): return self.load_image(result, dst=dst) @@ -1150,7 +1190,7 @@ def load_image(self, Path], *, dst: Py5Image = None) -> Py5Image: - """Load an image into a variable of type ``Py5Image``. + """Load an image into a variable of type `Py5Image`. Parameters ---------- @@ -1164,24 +1204,24 @@ def load_image(self, Notes ----- - Load an image into a variable of type ``Py5Image``. Four types of images (GIF, + Load an image into a variable of type `Py5Image`. Four types of images (GIF, JPG, TGA, PNG) can be loaded. To load images in other formats, consider using - ``convert_image()``. + `convert_image()`. - The ``image_path`` parameter can be a file or a URL. When loading a file, the - path can be in the data directory, relative to the current working directory - (``sketch_path()``), or an absolute path. When loading from a URL, the - ``image_path`` parameter must start with ``http://`` or ``https://``. If the - image cannot be loaded, a Python ``RuntimeError`` will be thrown. + The `image_path` parameter can be a file or a URL. When loading a file, the path + can be in the data directory, relative to the current working directory + (`sketch_path()`), or an absolute path. When loading from a URL, the + `image_path` parameter must start with `http://` or `https://`. If the image + cannot be loaded, a Python `RuntimeError` will be thrown. - In most cases, load all images in ``setup()`` to preload them at the start of - the program. Loading images inside ``draw()`` will reduce the speed of a - program. In those situations, consider using ``request_image()`` instead. + In most cases, load all images in `setup()` to preload them at the start of the + program. Loading images inside `draw()` will reduce the speed of a program. In + those situations, consider using `request_image()` instead. - The ``dst`` parameter allows users to store the loaded image into an existing + The `dst` parameter allows users to store the loaded image into an existing Py5Image object instead of creating a new object. The size of the existing Py5Image object must match the size of the loaded image. Most users will not - find the ``dst`` parameter helpful. This feature is needed internally for + find the `dst` parameter helpful. This feature is needed internally for performance reasons.""" try: pimg = self._instance.loadImage(str(image_path)) @@ -1209,7 +1249,7 @@ def load_image(self, raise RuntimeError(msg) def request_image(self, image_path: Union[str, Path]) -> Py5Promise: - """Use a Py5Promise object to load an image into a variable of type ``Py5Image``. + """Use a Py5Promise object to load an image into a variable of type `Py5Image`. Parameters ---------- @@ -1220,17 +1260,17 @@ def request_image(self, image_path: Union[str, Path]) -> Py5Promise: Notes ----- - Use a Py5Promise object to load an image into a variable of type ``Py5Image``. + Use a Py5Promise object to load an image into a variable of type `Py5Image`. This method provides a convenient alternative to combining - ``launch_promise_thread()`` with ``load_image()`` to load image data. + `launch_promise_thread()` with `load_image()` to load image data. - Consider using ``request_image()`` to load image data from within a Sketch's - ``draw()`` function. Using ``load_image()`` in the ``draw()`` function would - slow down the Sketch animation. + Consider using `request_image()` to load image data from within a Sketch's + `draw()` function. Using `load_image()` in the `draw()` function would slow down + the Sketch animation. - The returned Py5Promise object has an ``is_ready`` property that will be - ``True`` when the ``result`` property contains the value function ``f`` - returned. Before then, the ``result`` property will be ``None``.""" + The returned Py5Promise object has an `is_ready` property that will be `True` + when the `result` property contains the value function `f` returned. Before + then, the `result` property will be `None`.""" return self.launch_promise_thread(self.load_image, args=(image_path,)) ADD = 2 @@ -1391,28 +1431,28 @@ def request_image(self, image_path: Union[str, Path]) -> Py5Promise: @_return_list_str def _get_pargs(self) -> list[str]: - """List of strings passed to the Sketch through the call to ``run_sketch()``. + """List of strings passed to the Sketch through the call to `run_sketch()`. Underlying Processing field: PApplet.args Notes ----- - List of strings passed to the Sketch through the call to ``run_sketch()``. Only + List of strings passed to the Sketch through the call to `run_sketch()`. Only passing strings is allowed, but you can convert string types to something else to make this more useful. """ return self._instance.args pargs: list[str] = property( fget=_get_pargs, - doc="""List of strings passed to the Sketch through the call to ``run_sketch()``. + doc="""List of strings passed to the Sketch through the call to `run_sketch()`. Underlying Processing field: PApplet.args Notes ----- - List of strings passed to the Sketch through the call to ``run_sketch()``. Only + List of strings passed to the Sketch through the call to `run_sketch()`. Only passing strings is allowed, but you can convert string types to something else to make this more useful.""") @@ -1426,7 +1466,7 @@ def _get_display_height(self) -> int: System variable that stores the height of the entire screen display. This can be used to run a full-screen program on any display size, but calling - ``full_screen()`` is usually a better choice. + `full_screen()` is usually a better choice. """ return self._instance.displayHeight display_height: int = property( @@ -1440,7 +1480,7 @@ def _get_display_height(self) -> int: System variable that stores the height of the entire screen display. This can be used to run a full-screen program on any display size, but calling - ``full_screen()`` is usually a better choice.""") + `full_screen()` is usually a better choice.""") def _get_display_width(self) -> int: """System variable that stores the width of the entire screen display. @@ -1452,7 +1492,7 @@ def _get_display_width(self) -> int: System variable that stores the width of the entire screen display. This can be used to run a full-screen program on any display size, but calling - ``full_screen()`` is usually a better choice. + `full_screen()` is usually a better choice. """ return self._instance.displayWidth display_width: int = property( @@ -1466,7 +1506,7 @@ def _get_display_width(self) -> int: System variable that stores the width of the entire screen display. This can be used to run a full-screen program on any display size, but calling - ``full_screen()`` is usually a better choice.""") + `full_screen()` is usually a better choice.""") def _get_finished(self) -> bool: """Boolean variable reflecting if the Sketch has stopped permanently. @@ -1500,8 +1540,8 @@ def _get_focused(self) -> bool: ----- Confirms if a py5 program is "focused," meaning that it is active and will - accept mouse or keyboard input. This variable is ``True`` if it is focused and - ``False`` if not. + accept mouse or keyboard input. This variable is `True` if it is focused and + `False` if not. """ return self._instance.focused focused: bool = property( @@ -1515,11 +1555,11 @@ def _get_focused(self) -> bool: ----- Confirms if a py5 program is "focused," meaning that it is active and will - accept mouse or keyboard input. This variable is ``True`` if it is focused and - ``False`` if not.""") + accept mouse or keyboard input. This variable is `True` if it is focused and + `False` if not.""") def _get_frame_count(self) -> int: - """The system variable ``frame_count`` contains the number of frames that have been + """The system variable `frame_count` contains the number of frames that have been displayed since the program started. Underlying Processing field: PApplet.frameCount @@ -1527,15 +1567,15 @@ def _get_frame_count(self) -> int: Notes ----- - The system variable ``frame_count`` contains the number of frames that have been - displayed since the program started. Inside ``setup()`` the value is 0. Inside - the first execution of ``draw()`` it is 1, and it will increase by 1 for every - execution of ``draw()`` after that. + The system variable `frame_count` contains the number of frames that have been + displayed since the program started. Inside `setup()` the value is 0. Inside the + first execution of `draw()` it is 1, and it will increase by 1 for every + execution of `draw()` after that. """ return self._instance.frameCount frame_count: int = property( fget=_get_frame_count, - doc="""The system variable ``frame_count`` contains the number of frames that have been + doc="""The system variable `frame_count` contains the number of frames that have been displayed since the program started. Underlying Processing field: PApplet.frameCount @@ -1543,35 +1583,35 @@ def _get_frame_count(self) -> int: Notes ----- - The system variable ``frame_count`` contains the number of frames that have been - displayed since the program started. Inside ``setup()`` the value is 0. Inside - the first execution of ``draw()`` it is 1, and it will increase by 1 for every - execution of ``draw()`` after that.""") + The system variable `frame_count` contains the number of frames that have been + displayed since the program started. Inside `setup()` the value is 0. Inside the + first execution of `draw()` it is 1, and it will increase by 1 for every + execution of `draw()` after that.""") @_return_py5graphics def _get_g(self) -> Py5Graphics: - """The ``Py5Graphics`` object used by the Sketch. + """The `Py5Graphics` object used by the Sketch. Underlying Processing field: Sketch.g Notes ----- - The ``Py5Graphics`` object used by the Sketch. Internally, all of Processing's + The `Py5Graphics` object used by the Sketch. Internally, all of Processing's drawing functionality comes from interaction with PGraphics objects, and this will provide direct access to the PGraphics object used by the Sketch. """ return self._instance.g g: Py5Graphics = property( fget=_get_g, - doc="""The ``Py5Graphics`` object used by the Sketch. + doc="""The `Py5Graphics` object used by the Sketch. Underlying Processing field: Sketch.g Notes ----- - The ``Py5Graphics`` object used by the Sketch. Internally, all of Processing's + The `Py5Graphics` object used by the Sketch. Internally, all of Processing's drawing functionality comes from interaction with PGraphics objects, and this will provide direct access to the PGraphics object used by the Sketch.""") @@ -1584,9 +1624,9 @@ def _get_height(self) -> int: ----- System variable that stores the height of the display window. This value is set - by the second parameter of the ``size()`` function. For example, the function - call ``size(320, 240)`` sets the ``height`` variable to the value 240. The value - of ``height`` defaults to 100 if ``size()`` is not used in a program. + by the second parameter of the `size()` function. For example, the function call + `size(320, 240)` sets the `height` variable to the value 240. The value of + `height` defaults to 100 if `size()` is not used in a program. """ return self._instance.height height: int = property( @@ -1599,9 +1639,9 @@ def _get_height(self) -> int: ----- System variable that stores the height of the display window. This value is set - by the second parameter of the ``size()`` function. For example, the function - call ``size(320, 240)`` sets the ``height`` variable to the value 240. The value - of ``height`` defaults to 100 if ``size()`` is not used in a program.""") + by the second parameter of the `size()` function. For example, the function call + `size(320, 240)` sets the `height` variable to the value 240. The value of + `height` defaults to 100 if `size()` is not used in a program.""") def _get_java_platform(self) -> int: """Version of Java currently being used by py5. @@ -1661,7 +1701,7 @@ def _get_java_version_name(self) -> str: @_convert_jchar_to_chr def _get_key(self) -> chr: - """The system variable ``key`` always contains the value of the most recent key on + """The system variable `key` always contains the value of the most recent key on the keyboard that was used (either pressed or released). Underlying Processing field: PApplet.key @@ -1669,25 +1709,25 @@ def _get_key(self) -> chr: Notes ----- - The system variable ``key`` always contains the value of the most recent key on + The system variable `key` always contains the value of the most recent key on the keyboard that was used (either pressed or released). - For non-ASCII keys, use the ``key_code`` variable. The keys included in the - ASCII specification (``BACKSPACE``, ``TAB``, ``ENTER``, ``RETURN``, ``ESC``, and - ``DELETE``) do not require checking to see if the key is coded, and you should - simply use the ``key`` variable instead of ``key_code``. If you're making cross- - platform projects, note that the ``ENTER`` key is commonly used on PCs and Unix - and the ``RETURN`` key is used instead on Macintosh. Check for both ``ENTER`` - and ``RETURN`` to make sure your program will work for all platforms. + For non-ASCII keys, use the `key_code` variable. The keys included in the ASCII + specification (`BACKSPACE`, `TAB`, `ENTER`, `RETURN`, `ESC`, and `DELETE`) do + not require checking to see if the key is coded, and you should simply use the + `key` variable instead of `key_code`. If you're making cross-platform projects, + note that the `ENTER` key is commonly used on PCs and Unix and the `RETURN` key + is used instead on Macintosh. Check for both `ENTER` and `RETURN` to make sure + your program will work for all platforms. - There are issues with how ``key_code`` behaves across different renderers and + There are issues with how `key_code` behaves across different renderers and operating systems. Watch out for unexpected behavior as you switch renderers and operating systems. """ return self._instance.key key: chr = property( fget=_get_key, - doc="""The system variable ``key`` always contains the value of the most recent key on + doc="""The system variable `key` always contains the value of the most recent key on the keyboard that was used (either pressed or released). Underlying Processing field: PApplet.key @@ -1695,211 +1735,207 @@ def _get_key(self) -> chr: Notes ----- - The system variable ``key`` always contains the value of the most recent key on + The system variable `key` always contains the value of the most recent key on the keyboard that was used (either pressed or released). - For non-ASCII keys, use the ``key_code`` variable. The keys included in the - ASCII specification (``BACKSPACE``, ``TAB``, ``ENTER``, ``RETURN``, ``ESC``, and - ``DELETE``) do not require checking to see if the key is coded, and you should - simply use the ``key`` variable instead of ``key_code``. If you're making cross- - platform projects, note that the ``ENTER`` key is commonly used on PCs and Unix - and the ``RETURN`` key is used instead on Macintosh. Check for both ``ENTER`` - and ``RETURN`` to make sure your program will work for all platforms. + For non-ASCII keys, use the `key_code` variable. The keys included in the ASCII + specification (`BACKSPACE`, `TAB`, `ENTER`, `RETURN`, `ESC`, and `DELETE`) do + not require checking to see if the key is coded, and you should simply use the + `key` variable instead of `key_code`. If you're making cross-platform projects, + note that the `ENTER` key is commonly used on PCs and Unix and the `RETURN` key + is used instead on Macintosh. Check for both `ENTER` and `RETURN` to make sure + your program will work for all platforms. - There are issues with how ``key_code`` behaves across different renderers and + There are issues with how `key_code` behaves across different renderers and operating systems. Watch out for unexpected behavior as you switch renderers and operating systems.""") @_convert_jint_to_int def _get_key_code(self) -> int: - """The variable ``key_code`` is used to detect special keys such as the arrow keys - (``UP``, ``DOWN``, ``LEFT``, and ``RIGHT``) as well as ``ALT``, ``CONTROL``, and - ``SHIFT``. + """The variable `key_code` is used to detect special keys such as the arrow keys + (`UP`, `DOWN`, `LEFT`, and `RIGHT`) as well as `ALT`, `CONTROL`, and `SHIFT`. Underlying Processing field: PApplet.keyCode Notes ----- - The variable ``key_code`` is used to detect special keys such as the arrow keys - (``UP``, ``DOWN``, ``LEFT``, and ``RIGHT``) as well as ``ALT``, ``CONTROL``, and - ``SHIFT``. + The variable `key_code` is used to detect special keys such as the arrow keys + (`UP`, `DOWN`, `LEFT`, and `RIGHT`) as well as `ALT`, `CONTROL`, and `SHIFT`. When checking for these keys, it can be useful to first check if the key is - coded. This is done with the conditional ``if (key == CODED)``, as shown in the + coded. This is done with the conditional `if (key == CODED)`, as shown in the example. - The keys included in the ASCII specification (``BACKSPACE``, ``TAB``, ``ENTER``, - ``RETURN``, ``ESC``, and ``DELETE``) do not require checking to see if the key - is coded; for those keys, you should simply use the ``key`` variable directly - (and not ``key_code``). If you're making cross-platform projects, note that the - ``ENTER`` key is commonly used on PCs and Unix, while the ``RETURN`` key is used - on Macs. Make sure your program will work on all platforms by checking for both - ``ENTER`` and ``RETURN``. + The keys included in the ASCII specification (`BACKSPACE`, `TAB`, `ENTER`, + `RETURN`, `ESC`, and `DELETE`) do not require checking to see if the key is + coded; for those keys, you should simply use the `key` variable directly (and + not `key_code`). If you're making cross-platform projects, note that the + `ENTER` key is commonly used on PCs and Unix, while the `RETURN` key is used on + Macs. Make sure your program will work on all platforms by checking for both + `ENTER` and `RETURN`. - For those familiar with Java, the values for ``UP`` and ``DOWN`` are simply - shorter versions of Java's ``key_event.VK_UP`` and ``key_event.VK_DOWN``. Other - ``key_code`` values can be found in the Java KeyEvent reference. + For those familiar with Java, the values for `UP` and `DOWN` are simply shorter + versions of Java's `key_event.VK_UP` and `key_event.VK_DOWN`. Other `key_code` + values can be found in the Java KeyEvent reference. - There are issues with how ``key_code`` behaves across different renderers and + There are issues with how `key_code` behaves across different renderers and operating systems. Watch out for unexpected behavior as you switch renderers and operating systems and you are using keys are aren't mentioned in this reference entry. - If you are using ``P2D`` or ``P3D`` as your renderer, use the ``NEWT`` KeyEvent + If you are using `P2D` or `P3D` as your renderer, use the `NEWT` KeyEvent constants. """ return self._instance.keyCode key_code: int = property( fget=_get_key_code, - doc="""The variable ``key_code`` is used to detect special keys such as the arrow keys - (``UP``, ``DOWN``, ``LEFT``, and ``RIGHT``) as well as ``ALT``, ``CONTROL``, and - ``SHIFT``. + doc="""The variable `key_code` is used to detect special keys such as the arrow keys + (`UP`, `DOWN`, `LEFT`, and `RIGHT`) as well as `ALT`, `CONTROL`, and `SHIFT`. Underlying Processing field: PApplet.keyCode Notes ----- - The variable ``key_code`` is used to detect special keys such as the arrow keys - (``UP``, ``DOWN``, ``LEFT``, and ``RIGHT``) as well as ``ALT``, ``CONTROL``, and - ``SHIFT``. + The variable `key_code` is used to detect special keys such as the arrow keys + (`UP`, `DOWN`, `LEFT`, and `RIGHT`) as well as `ALT`, `CONTROL`, and `SHIFT`. When checking for these keys, it can be useful to first check if the key is - coded. This is done with the conditional ``if (key == CODED)``, as shown in the + coded. This is done with the conditional `if (key == CODED)`, as shown in the example. - The keys included in the ASCII specification (``BACKSPACE``, ``TAB``, ``ENTER``, - ``RETURN``, ``ESC``, and ``DELETE``) do not require checking to see if the key - is coded; for those keys, you should simply use the ``key`` variable directly - (and not ``key_code``). If you're making cross-platform projects, note that the - ``ENTER`` key is commonly used on PCs and Unix, while the ``RETURN`` key is used - on Macs. Make sure your program will work on all platforms by checking for both - ``ENTER`` and ``RETURN``. + The keys included in the ASCII specification (`BACKSPACE`, `TAB`, `ENTER`, + `RETURN`, `ESC`, and `DELETE`) do not require checking to see if the key is + coded; for those keys, you should simply use the `key` variable directly (and + not `key_code`). If you're making cross-platform projects, note that the + `ENTER` key is commonly used on PCs and Unix, while the `RETURN` key is used on + Macs. Make sure your program will work on all platforms by checking for both + `ENTER` and `RETURN`. - For those familiar with Java, the values for ``UP`` and ``DOWN`` are simply - shorter versions of Java's ``key_event.VK_UP`` and ``key_event.VK_DOWN``. Other - ``key_code`` values can be found in the Java KeyEvent reference. + For those familiar with Java, the values for `UP` and `DOWN` are simply shorter + versions of Java's `key_event.VK_UP` and `key_event.VK_DOWN`. Other `key_code` + values can be found in the Java KeyEvent reference. - There are issues with how ``key_code`` behaves across different renderers and + There are issues with how `key_code` behaves across different renderers and operating systems. Watch out for unexpected behavior as you switch renderers and operating systems and you are using keys are aren't mentioned in this reference entry. - If you are using ``P2D`` or ``P3D`` as your renderer, use the ``NEWT`` KeyEvent + If you are using `P2D` or `P3D` as your renderer, use the `NEWT` KeyEvent constants.""") def _get_mouse_button(self) -> int: - """When a mouse button is pressed, the value of the system variable - ``mouse_button`` is set to either ``LEFT``, ``RIGHT``, or ``CENTER``, depending - on which button is pressed. + """When a mouse button is pressed, the value of the system variable `mouse_button` + is set to either `LEFT`, `RIGHT`, or `CENTER`, depending on which button is + pressed. Underlying Processing field: PApplet.mouseButton Notes ----- - When a mouse button is pressed, the value of the system variable - ``mouse_button`` is set to either ``LEFT``, ``RIGHT``, or ``CENTER``, depending - on which button is pressed. (If no button is pressed, ``mouse_button`` may be - reset to ``0``. For that reason, it's best to use ``mouse_pressed`` first to - test if any button is being pressed, and only then test the value of - ``mouse_button``, as shown in the examples.) + When a mouse button is pressed, the value of the system variable `mouse_button` + is set to either `LEFT`, `RIGHT`, or `CENTER`, depending on which button is + pressed. (If no button is pressed, `mouse_button` may be reset to `0`. For that + reason, it's best to use `mouse_pressed` first to test if any button is being + pressed, and only then test the value of `mouse_button`, as shown in the + examples.) """ return self._instance.mouseButton mouse_button: int = property( fget=_get_mouse_button, - doc="""When a mouse button is pressed, the value of the system variable - ``mouse_button`` is set to either ``LEFT``, ``RIGHT``, or ``CENTER``, depending - on which button is pressed. + doc="""When a mouse button is pressed, the value of the system variable `mouse_button` + is set to either `LEFT`, `RIGHT`, or `CENTER`, depending on which button is + pressed. Underlying Processing field: PApplet.mouseButton Notes ----- - When a mouse button is pressed, the value of the system variable - ``mouse_button`` is set to either ``LEFT``, ``RIGHT``, or ``CENTER``, depending - on which button is pressed. (If no button is pressed, ``mouse_button`` may be - reset to ``0``. For that reason, it's best to use ``mouse_pressed`` first to - test if any button is being pressed, and only then test the value of - ``mouse_button``, as shown in the examples.)""") + When a mouse button is pressed, the value of the system variable `mouse_button` + is set to either `LEFT`, `RIGHT`, or `CENTER`, depending on which button is + pressed. (If no button is pressed, `mouse_button` may be reset to `0`. For that + reason, it's best to use `mouse_pressed` first to test if any button is being + pressed, and only then test the value of `mouse_button`, as shown in the + examples.)""") def _get_mouse_x(self) -> int: - """The system variable ``mouse_x`` always contains the current horizontal - coordinate of the mouse. + """The system variable `mouse_x` always contains the current horizontal coordinate + of the mouse. Underlying Processing field: PApplet.mouseX Notes ----- - The system variable ``mouse_x`` always contains the current horizontal - coordinate of the mouse. + The system variable `mouse_x` always contains the current horizontal coordinate + of the mouse. Note that py5 can only track the mouse position when the pointer is over the - current window. The default value of ``mouse_x`` is ``0``, so ``0`` will be - returned until the mouse moves in front of the Sketch window. (This typically - happens when a Sketch is first run.) Once the mouse moves away from the window, - ``mouse_x`` will continue to report its most recent position. + current window. The default value of `mouse_x` is `0`, so `0` will be returned + until the mouse moves in front of the Sketch window. (This typically happens + when a Sketch is first run.) Once the mouse moves away from the window, + `mouse_x` will continue to report its most recent position. """ return self._instance.mouseX mouse_x: int = property( fget=_get_mouse_x, - doc="""The system variable ``mouse_x`` always contains the current horizontal - coordinate of the mouse. + doc="""The system variable `mouse_x` always contains the current horizontal coordinate + of the mouse. Underlying Processing field: PApplet.mouseX Notes ----- - The system variable ``mouse_x`` always contains the current horizontal - coordinate of the mouse. + The system variable `mouse_x` always contains the current horizontal coordinate + of the mouse. Note that py5 can only track the mouse position when the pointer is over the - current window. The default value of ``mouse_x`` is ``0``, so ``0`` will be - returned until the mouse moves in front of the Sketch window. (This typically - happens when a Sketch is first run.) Once the mouse moves away from the window, - ``mouse_x`` will continue to report its most recent position.""") + current window. The default value of `mouse_x` is `0`, so `0` will be returned + until the mouse moves in front of the Sketch window. (This typically happens + when a Sketch is first run.) Once the mouse moves away from the window, + `mouse_x` will continue to report its most recent position.""") def _get_mouse_y(self) -> int: - """The system variable ``mouse_y`` always contains the current vertical coordinate - of the mouse. + """The system variable `mouse_y` always contains the current vertical coordinate of + the mouse. Underlying Processing field: PApplet.mouseY Notes ----- - The system variable ``mouse_y`` always contains the current vertical coordinate - of the mouse. + The system variable `mouse_y` always contains the current vertical coordinate of + the mouse. Note that py5 can only track the mouse position when the pointer is over the - current window. The default value of ``mouse_y`` is ``0``, so ``0`` will be - returned until the mouse moves in front of the Sketch window. (This typically - happens when a Sketch is first run.) Once the mouse moves away from the window, - ``mouse_y`` will continue to report its most recent position. + current window. The default value of `mouse_y` is `0`, so `0` will be returned + until the mouse moves in front of the Sketch window. (This typically happens + when a Sketch is first run.) Once the mouse moves away from the window, + `mouse_y` will continue to report its most recent position. """ return self._instance.mouseY mouse_y: int = property( fget=_get_mouse_y, - doc="""The system variable ``mouse_y`` always contains the current vertical coordinate - of the mouse. + doc="""The system variable `mouse_y` always contains the current vertical coordinate of + the mouse. Underlying Processing field: PApplet.mouseY Notes ----- - The system variable ``mouse_y`` always contains the current vertical coordinate - of the mouse. + The system variable `mouse_y` always contains the current vertical coordinate of + the mouse. Note that py5 can only track the mouse position when the pointer is over the - current window. The default value of ``mouse_y`` is ``0``, so ``0`` will be - returned until the mouse moves in front of the Sketch window. (This typically - happens when a Sketch is first run.) Once the mouse moves away from the window, - ``mouse_y`` will continue to report its most recent position.""") + current window. The default value of `mouse_y` is `0`, so `0` will be returned + until the mouse moves in front of the Sketch window. (This typically happens + when a Sketch is first run.) Once the mouse moves away from the window, + `mouse_y` will continue to report its most recent position.""") def _get_pixel_height(self) -> int: """Height of the display window in pixels. @@ -1909,16 +1945,15 @@ def _get_pixel_height(self) -> int: Notes ----- - Height of the display window in pixels. When ``pixel_density(2)`` is used to - make use of a high resolution display (called a Retina display on OSX or high- - dpi on Windows and Linux), the width and height of the Sketch do not change, but - the number of pixels is doubled. As a result, all operations that use pixels - (like ``load_pixels()``, ``get()``, etc.) happen in this doubled space. As a - convenience, the variables ``pixel_width`` and ``pixel_height`` hold the actual + Height of the display window in pixels. When `pixel_density(2)` is used to make + use of a high resolution display (called a Retina display on OSX or high-dpi on + Windows and Linux), the width and height of the Sketch do not change, but the + number of pixels is doubled. As a result, all operations that use pixels (like + `load_pixels()`, `get_pixels()`, etc.) happen in this doubled space. As a + convenience, the variables `pixel_width` and `pixel_height` hold the actual width and height of the Sketch in pixels. This is useful for any Sketch that use - the ``pixels[]`` or ``np_pixels[]`` arrays, for instance, because the number of - elements in each array will be ``pixel_width*pixel_height``, not - ``width*height``. + the `pixels[]` or `np_pixels[]` arrays, for instance, because the number of + elements in each array will be `pixel_width*pixel_height`, not `width*height`. """ return self._instance.pixelHeight pixel_height: int = property( @@ -1930,16 +1965,15 @@ def _get_pixel_height(self) -> int: Notes ----- - Height of the display window in pixels. When ``pixel_density(2)`` is used to - make use of a high resolution display (called a Retina display on OSX or high- - dpi on Windows and Linux), the width and height of the Sketch do not change, but - the number of pixels is doubled. As a result, all operations that use pixels - (like ``load_pixels()``, ``get()``, etc.) happen in this doubled space. As a - convenience, the variables ``pixel_width`` and ``pixel_height`` hold the actual + Height of the display window in pixels. When `pixel_density(2)` is used to make + use of a high resolution display (called a Retina display on OSX or high-dpi on + Windows and Linux), the width and height of the Sketch do not change, but the + number of pixels is doubled. As a result, all operations that use pixels (like + `load_pixels()`, `get_pixels()`, etc.) happen in this doubled space. As a + convenience, the variables `pixel_width` and `pixel_height` hold the actual width and height of the Sketch in pixels. This is useful for any Sketch that use - the ``pixels[]`` or ``np_pixels[]`` arrays, for instance, because the number of - elements in each array will be ``pixel_width*pixel_height``, not - ``width*height``.""") + the `pixels[]` or `np_pixels[]` arrays, for instance, because the number of + elements in each array will be `pixel_width*pixel_height`, not `width*height`.""") def _get_pixel_width(self) -> int: """Width of the display window in pixels. @@ -1949,16 +1983,15 @@ def _get_pixel_width(self) -> int: Notes ----- - Width of the display window in pixels. When ``pixel_density(2)`` is used to make + Width of the display window in pixels. When `pixel_density(2)` is used to make use of a high resolution display (called a Retina display on OSX or high-dpi on Windows and Linux), the width and height of the Sketch do not change, but the number of pixels is doubled. As a result, all operations that use pixels (like - ``load_pixels()``, ``get()``, etc.) happen in this doubled space. As a - convenience, the variables ``pixel_width`` and ``pixel_height`` hold the actual + `load_pixels()`, `get_pixels()`, etc.) happen in this doubled space. As a + convenience, the variables `pixel_width` and `pixel_height` hold the actual width and height of the Sketch in pixels. This is useful for any Sketch that use - the ``pixels[]`` or ``np_pixels[]`` arrays, for instance, because the number of - elements in each array will be ``pixel_width*pixel_height``, not - ``width*height``. + the `pixels[]` or `np_pixels[]` arrays, for instance, because the number of + elements in each array will be `pixel_width*pixel_height`, not `width*height`. """ return self._instance.pixelWidth pixel_width: int = property( @@ -1970,19 +2003,18 @@ def _get_pixel_width(self) -> int: Notes ----- - Width of the display window in pixels. When ``pixel_density(2)`` is used to make + Width of the display window in pixels. When `pixel_density(2)` is used to make use of a high resolution display (called a Retina display on OSX or high-dpi on Windows and Linux), the width and height of the Sketch do not change, but the number of pixels is doubled. As a result, all operations that use pixels (like - ``load_pixels()``, ``get()``, etc.) happen in this doubled space. As a - convenience, the variables ``pixel_width`` and ``pixel_height`` hold the actual + `load_pixels()`, `get_pixels()`, etc.) happen in this doubled space. As a + convenience, the variables `pixel_width` and `pixel_height` hold the actual width and height of the Sketch in pixels. This is useful for any Sketch that use - the ``pixels[]`` or ``np_pixels[]`` arrays, for instance, because the number of - elements in each array will be ``pixel_width*pixel_height``, not - ``width*height``.""") + the `pixels[]` or `np_pixels[]` arrays, for instance, because the number of + elements in each array will be `pixel_width*pixel_height`, not `width*height`.""") def _get_pmouse_x(self) -> int: - """The system variable ``pmouse_x`` always contains the horizontal position of the + """The system variable `pmouse_x` always contains the horizontal position of the mouse in the frame previous to the current frame. Underlying Processing field: PApplet.pmouseX @@ -1990,29 +2022,29 @@ def _get_pmouse_x(self) -> int: Notes ----- - The system variable ``pmouse_x`` always contains the horizontal position of the + The system variable `pmouse_x` always contains the horizontal position of the mouse in the frame previous to the current frame. - You may find that ``pmouse_x`` and ``pmouse_y`` have different values when - referenced inside of ``draw()`` and inside of mouse events like - ``mouse_pressed()`` and ``mouse_moved()``. Inside ``draw()``, ``pmouse_x`` and - ``pmouse_y`` update only once per frame (once per trip through the ``draw()`` - loop). But inside mouse events, they update each time the event is called. If - these values weren't updated immediately during mouse events, then the mouse - position would be read only once per frame, resulting in slight delays and - choppy interaction. If the mouse variables were always updated multiple times - per frame, then something like ``line(pmouse_x, pmouse_y, mouse_x, mouse_y)`` - inside ``draw()`` would have lots of gaps, because ``pmouse_x`` may have changed - several times in between the calls to ``line()``. - - If you want values relative to the previous frame, use ``pmouse_x`` and - ``pmouse_y`` inside ``draw()``. If you want continuous response, use - ``pmouse_x`` and ``pmouse_y`` inside the mouse event functions. + You may find that `pmouse_x` and `pmouse_y` have different values when + referenced inside of `draw()` and inside of mouse events like `mouse_pressed()` + and `mouse_moved()`. Inside `draw()`, `pmouse_x` and `pmouse_y` update only once + per frame (once per trip through the `draw()` loop). But inside mouse events, + they update each time the event is called. If these values weren't updated + immediately during mouse events, then the mouse position would be read only once + per frame, resulting in slight delays and choppy interaction. If the mouse + variables were always updated multiple times per frame, then something like + `line(pmouse_x, pmouse_y, mouse_x, mouse_y)` inside `draw()` would have lots of + gaps, because `pmouse_x` may have changed several times in between the calls to + `line()`. + + If you want values relative to the previous frame, use `pmouse_x` and `pmouse_y` + inside `draw()`. If you want continuous response, use `pmouse_x` and `pmouse_y` + inside the mouse event functions. """ return self._instance.pmouseX pmouse_x: int = property( fget=_get_pmouse_x, - doc="""The system variable ``pmouse_x`` always contains the horizontal position of the + doc="""The system variable `pmouse_x` always contains the horizontal position of the mouse in the frame previous to the current frame. Underlying Processing field: PApplet.pmouseX @@ -2020,27 +2052,27 @@ def _get_pmouse_x(self) -> int: Notes ----- - The system variable ``pmouse_x`` always contains the horizontal position of the + The system variable `pmouse_x` always contains the horizontal position of the mouse in the frame previous to the current frame. - You may find that ``pmouse_x`` and ``pmouse_y`` have different values when - referenced inside of ``draw()`` and inside of mouse events like - ``mouse_pressed()`` and ``mouse_moved()``. Inside ``draw()``, ``pmouse_x`` and - ``pmouse_y`` update only once per frame (once per trip through the ``draw()`` - loop). But inside mouse events, they update each time the event is called. If - these values weren't updated immediately during mouse events, then the mouse - position would be read only once per frame, resulting in slight delays and - choppy interaction. If the mouse variables were always updated multiple times - per frame, then something like ``line(pmouse_x, pmouse_y, mouse_x, mouse_y)`` - inside ``draw()`` would have lots of gaps, because ``pmouse_x`` may have changed - several times in between the calls to ``line()``. - - If you want values relative to the previous frame, use ``pmouse_x`` and - ``pmouse_y`` inside ``draw()``. If you want continuous response, use - ``pmouse_x`` and ``pmouse_y`` inside the mouse event functions.""") + You may find that `pmouse_x` and `pmouse_y` have different values when + referenced inside of `draw()` and inside of mouse events like `mouse_pressed()` + and `mouse_moved()`. Inside `draw()`, `pmouse_x` and `pmouse_y` update only once + per frame (once per trip through the `draw()` loop). But inside mouse events, + they update each time the event is called. If these values weren't updated + immediately during mouse events, then the mouse position would be read only once + per frame, resulting in slight delays and choppy interaction. If the mouse + variables were always updated multiple times per frame, then something like + `line(pmouse_x, pmouse_y, mouse_x, mouse_y)` inside `draw()` would have lots of + gaps, because `pmouse_x` may have changed several times in between the calls to + `line()`. + + If you want values relative to the previous frame, use `pmouse_x` and `pmouse_y` + inside `draw()`. If you want continuous response, use `pmouse_x` and `pmouse_y` + inside the mouse event functions.""") def _get_pmouse_y(self) -> int: - """The system variable ``pmouse_y`` always contains the vertical position of the + """The system variable `pmouse_y` always contains the vertical position of the mouse in the frame previous to the current frame. Underlying Processing field: PApplet.pmouseY @@ -2048,16 +2080,16 @@ def _get_pmouse_y(self) -> int: Notes ----- - The system variable ``pmouse_y`` always contains the vertical position of the + The system variable `pmouse_y` always contains the vertical position of the mouse in the frame previous to the current frame. - For more detail on how ``pmouse_y`` is updated inside of mouse events and - ``draw()``, see the reference for ``pmouse_x``. + For more detail on how `pmouse_y` is updated inside of mouse events and + `draw()`, see the reference for `pmouse_x`. """ return self._instance.pmouseY pmouse_y: int = property( fget=_get_pmouse_y, - doc="""The system variable ``pmouse_y`` always contains the vertical position of the + doc="""The system variable `pmouse_y` always contains the vertical position of the mouse in the frame previous to the current frame. Underlying Processing field: PApplet.pmouseY @@ -2065,11 +2097,11 @@ def _get_pmouse_y(self) -> int: Notes ----- - The system variable ``pmouse_y`` always contains the vertical position of the + The system variable `pmouse_y` always contains the vertical position of the mouse in the frame previous to the current frame. - For more detail on how ``pmouse_y`` is updated inside of mouse events and - ``draw()``, see the reference for ``pmouse_x``.""") + For more detail on how `pmouse_y` is updated inside of mouse events and + `draw()`, see the reference for `pmouse_x`.""") def _get_ratio_left(self) -> float: """Width of the left section of the window that does not fit the desired aspect @@ -2084,7 +2116,7 @@ def _get_ratio_left(self) -> float: ratio of a scale invariant Sketch. This will always be greater than or equal to zero. Experimenting with the example and seeing how this value changes will provide more understanding than what can be explained with words. See - ``window_ratio()`` for more information about how to activate scale invariant + `window_ratio()` for more information about how to activate scale invariant drawing and why it is useful. """ return self._instance.ratioLeft @@ -2102,7 +2134,7 @@ def _get_ratio_left(self) -> float: ratio of a scale invariant Sketch. This will always be greater than or equal to zero. Experimenting with the example and seeing how this value changes will provide more understanding than what can be explained with words. See - ``window_ratio()`` for more information about how to activate scale invariant + `window_ratio()` for more information about how to activate scale invariant drawing and why it is useful.""") def _get_ratio_scale(self) -> float: @@ -2115,7 +2147,7 @@ def _get_ratio_scale(self) -> float: Scaling factor used to maintain scale invariant drawing. Experimenting with the example and seeing how this value changes will provide more understanding than - what can be explained with words. See ``window_ratio()`` for more information + what can be explained with words. See `window_ratio()` for more information about how to activate scale invariant drawing and why it is useful. """ return self._instance.ratioScale @@ -2130,7 +2162,7 @@ def _get_ratio_scale(self) -> float: Scaling factor used to maintain scale invariant drawing. Experimenting with the example and seeing how this value changes will provide more understanding than - what can be explained with words. See ``window_ratio()`` for more information + what can be explained with words. See `window_ratio()` for more information about how to activate scale invariant drawing and why it is useful.""") def _get_ratio_top(self) -> float: @@ -2146,7 +2178,7 @@ def _get_ratio_top(self) -> float: ratio of a scale invariant Sketch. This will always be greater than or equal to zero. Experimenting with the example and seeing how this value changes will provide more understanding than what can be explained with words. See - ``window_ratio()`` for more information about how to activate scale invariant + `window_ratio()` for more information about how to activate scale invariant drawing and why it is useful. """ return self._instance.ratioTop @@ -2164,7 +2196,7 @@ def _get_ratio_top(self) -> float: ratio of a scale invariant Sketch. This will always be greater than or equal to zero. Experimenting with the example and seeing how this value changes will provide more understanding than what can be explained with words. See - ``window_ratio()`` for more information about how to activate scale invariant + `window_ratio()` for more information about how to activate scale invariant drawing and why it is useful.""") def _get_rheight(self) -> int: @@ -2176,10 +2208,10 @@ def _get_rheight(self) -> int: ----- The height of the scale invariant display window. This will be the value of the - ``high`` parameter used in the call to ``window_ratio()`` that activates scale + `high` parameter used in the call to `window_ratio()` that activates scale invariant drawing. This field should only be used in a scale invariant Sketch. - See ``window_ratio()`` for more information about how to activate this and why - it is useful. + See `window_ratio()` for more information about how to activate this and why it + is useful. """ return self._instance.rheight rheight: int = property( @@ -2192,10 +2224,10 @@ def _get_rheight(self) -> int: ----- The height of the scale invariant display window. This will be the value of the - ``high`` parameter used in the call to ``window_ratio()`` that activates scale + `high` parameter used in the call to `window_ratio()` that activates scale invariant drawing. This field should only be used in a scale invariant Sketch. - See ``window_ratio()`` for more information about how to activate this and why - it is useful.""") + See `window_ratio()` for more information about how to activate this and why it + is useful.""") def _get_rmouse_x(self) -> int: """The current horizonal coordinate of the mouse after activating scale invariant @@ -2207,14 +2239,14 @@ def _get_rmouse_x(self) -> int: ----- The current horizonal coordinate of the mouse after activating scale invariant - drawing. See ``window_ratio()`` for more information about how to activate this + drawing. See `window_ratio()` for more information about how to activate this and why it is useful. Note that py5 can only track the mouse position when the pointer is over the - current window. The default value of ``rmouse_x`` is ``0``, so ``0`` will be - returned until the mouse moves in front of the Sketch window. (This typically - happens when a Sketch is first run.) Once the mouse moves away from the window, - ``rmouse_x`` will continue to report its most recent position. + current window. The default value of `rmouse_x` is `0`, so `0` will be returned + until the mouse moves in front of the Sketch window. (This typically happens + when a Sketch is first run.) Once the mouse moves away from the window, + `rmouse_x` will continue to report its most recent position. """ return self._instance.rmouseX rmouse_x: int = property( @@ -2228,14 +2260,14 @@ def _get_rmouse_x(self) -> int: ----- The current horizonal coordinate of the mouse after activating scale invariant - drawing. See ``window_ratio()`` for more information about how to activate this + drawing. See `window_ratio()` for more information about how to activate this and why it is useful. Note that py5 can only track the mouse position when the pointer is over the - current window. The default value of ``rmouse_x`` is ``0``, so ``0`` will be - returned until the mouse moves in front of the Sketch window. (This typically - happens when a Sketch is first run.) Once the mouse moves away from the window, - ``rmouse_x`` will continue to report its most recent position.""") + current window. The default value of `rmouse_x` is `0`, so `0` will be returned + until the mouse moves in front of the Sketch window. (This typically happens + when a Sketch is first run.) Once the mouse moves away from the window, + `rmouse_x` will continue to report its most recent position.""") def _get_rmouse_y(self) -> int: """The current vertical coordinate of the mouse after activating scale invariant @@ -2247,14 +2279,14 @@ def _get_rmouse_y(self) -> int: ----- The current vertical coordinate of the mouse after activating scale invariant - drawing. See ``window_ratio()`` for more information about how to activate this + drawing. See `window_ratio()` for more information about how to activate this and why it is useful. Note that py5 can only track the mouse position when the pointer is over the - current window. The default value of ``rmouse_y`` is ``0``, so ``0`` will be - returned until the mouse moves in front of the Sketch window. (This typically - happens when a Sketch is first run.) Once the mouse moves away from the window, - ``rmouse_y`` will continue to report its most recent position. + current window. The default value of `rmouse_y` is `0`, so `0` will be returned + until the mouse moves in front of the Sketch window. (This typically happens + when a Sketch is first run.) Once the mouse moves away from the window, + `rmouse_y` will continue to report its most recent position. """ return self._instance.rmouseY rmouse_y: int = property( @@ -2268,14 +2300,14 @@ def _get_rmouse_y(self) -> int: ----- The current vertical coordinate of the mouse after activating scale invariant - drawing. See ``window_ratio()`` for more information about how to activate this + drawing. See `window_ratio()` for more information about how to activate this and why it is useful. Note that py5 can only track the mouse position when the pointer is over the - current window. The default value of ``rmouse_y`` is ``0``, so ``0`` will be - returned until the mouse moves in front of the Sketch window. (This typically - happens when a Sketch is first run.) Once the mouse moves away from the window, - ``rmouse_y`` will continue to report its most recent position.""") + current window. The default value of `rmouse_y` is `0`, so `0` will be returned + until the mouse moves in front of the Sketch window. (This typically happens + when a Sketch is first run.) Once the mouse moves away from the window, + `rmouse_y` will continue to report its most recent position.""") def _get_rwidth(self) -> int: """The width of the scale invariant display window. @@ -2286,10 +2318,10 @@ def _get_rwidth(self) -> int: ----- The width of the scale invariant display window. This will be the value of the - ``wide`` parameter used in the call to ``window_ratio()`` that activates scale + `wide` parameter used in the call to `window_ratio()` that activates scale invariant drawing. This field should only be used in a scale invariant Sketch. - See ``window_ratio()`` for more information about how to activate this and why - it is useful. + See `window_ratio()` for more information about how to activate this and why it + is useful. """ return self._instance.rwidth rwidth: int = property( @@ -2302,10 +2334,10 @@ def _get_rwidth(self) -> int: ----- The width of the scale invariant display window. This will be the value of the - ``wide`` parameter used in the call to ``window_ratio()`` that activates scale + `wide` parameter used in the call to `window_ratio()` that activates scale invariant drawing. This field should only be used in a scale invariant Sketch. - See ``window_ratio()`` for more information about how to activate this and why - it is useful.""") + See `window_ratio()` for more information about how to activate this and why it + is useful.""") def _get_width(self) -> int: """System variable that stores the width of the display window. @@ -2316,9 +2348,9 @@ def _get_width(self) -> int: ----- System variable that stores the width of the display window. This value is set - by the first parameter of the ``size()`` function. For example, the function - call ``size(320, 240)`` sets the ``width`` variable to the value 320. The value - of ``width`` defaults to 100 if ``size()`` is not used in a program. + by the first parameter of the `size()` function. For example, the function call + `size(320, 240)` sets the `width` variable to the value 320. The value of + `width` defaults to 100 if `size()` is not used in a program. """ return self._instance.width width: int = property( @@ -2331,9 +2363,9 @@ def _get_width(self) -> int: ----- System variable that stores the width of the display window. This value is set - by the first parameter of the ``size()`` function. For example, the function - call ``size(320, 240)`` sets the ``width`` variable to the value 320. The value - of ``width`` defaults to 100 if ``size()`` is not used in a program.""") + by the first parameter of the `size()` function. For example, the function call + `size(320, 240)` sets the `width` variable to the value 320. The value of + `width` defaults to 100 if `size()` is not used in a program.""") def _get_window_x(self) -> int: """The x-coordinate of the current window location. @@ -2385,7 +2417,7 @@ def _get_window_y(self) -> int: @_convert_hex_color() def alpha(self, rgb: int, /) -> float: - """Extracts the alpha value from a color, scaled to match current ``color_mode()``. + """Extracts the alpha value from a color, scaled to match current `color_mode()`. Underlying Processing method: PApplet.alpha @@ -2398,14 +2430,14 @@ def alpha(self, rgb: int, /) -> float: Notes ----- - Extracts the alpha value from a color, scaled to match current ``color_mode()``. + Extracts the alpha value from a color, scaled to match current `color_mode()`. - The ``alpha()`` function is easy to use and understand, but it is slower than a - technique called bit shifting. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``alpha()`` but with greater speed by using the - right shift operator (``>>``) with a bit mask. For example, ``alpha(c)`` and ``c - >> 24 & 0xFF`` both extract the alpha value from a color variable ``c`` but the - later is faster. + The `alpha()` function is easy to use and understand, but it is slower than a + technique called bit shifting. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `alpha()` but with greater speed by using the right + shift operator (`>>`) with a bit mask. For example, `alpha(c)` and `c >> 24 & + 0xFF` both extract the alpha value from a color variable `c` but the later is + faster. """ return self._instance.alpha(rgb) @@ -2448,9 +2480,9 @@ def ambient(self, gray: float, /) -> None: Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with ``emissive()``, - ``specular()``, and ``shininess()`` to set the material properties of shapes. + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect + and half of the green light to reflect. Use in combination with `emissive()`, + `specular()`, and `shininess()` to set the material properties of shapes. """ pass @@ -2493,9 +2525,9 @@ def ambient(self, v1: float, v2: float, v3: float, /) -> None: Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with ``emissive()``, - ``specular()``, and ``shininess()`` to set the material properties of shapes. + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect + and half of the green light to reflect. Use in combination with `emissive()`, + `specular()`, and `shininess()` to set the material properties of shapes. """ pass @@ -2538,9 +2570,9 @@ def ambient(self, rgb: int, /) -> None: Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with ``emissive()``, - ``specular()``, and ``shininess()`` to set the material properties of shapes. + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect + and half of the green light to reflect. Use in combination with `emissive()`, + `specular()`, and `shininess()` to set the material properties of shapes. """ pass @@ -2583,9 +2615,9 @@ def ambient(self, *args): Sets the ambient reflectance for shapes drawn to the screen. This is combined with the ambient light component of the environment. The color components set through the parameters define the reflectance. For example in the default color - mode, setting ``ambient(255, 127, 0)``, would cause all the red light to reflect - and half of the green light to reflect. Use in combination with ``emissive()``, - ``specular()``, and ``shininess()`` to set the material properties of shapes. + mode, setting `ambient(255, 127, 0)`, would cause all the red light to reflect + and half of the green light to reflect. Use in combination with `emissive()`, + `specular()`, and `shininess()` to set the material properties of shapes. """ return self._instance.ambient(*args) @@ -2630,11 +2662,11 @@ def ambient_light(self, v1: float, v2: float, v3: float, /) -> None: Adds an ambient light. Ambient light doesn't come from a specific direction, the rays of light have bounced around so much that objects are evenly lit from all sides. Ambient lights are almost always used in combination with other types of - lights. Lights need to be included in the ``draw()`` to remain persistent in a - looping program. Placing them in the ``setup()`` of a looping program will cause - them to only have an effect the first time through the loop. The ``v1``, ``v2``, - and ``v3`` parameters are interpreted as either ``RGB`` or ``HSB`` values, - depending on the current color mode. + lights. Lights need to be included in the `draw()` to remain persistent in a + looping program. Placing them in the `setup()` of a looping program will cause + them to only have an effect the first time through the loop. The `v1`, `v2`, and + `v3` parameters are interpreted as either `RGB` or `HSB` values, depending on + the current color mode. """ pass @@ -2680,11 +2712,11 @@ def ambient_light(self, v1: float, v2: float, v3: float, Adds an ambient light. Ambient light doesn't come from a specific direction, the rays of light have bounced around so much that objects are evenly lit from all sides. Ambient lights are almost always used in combination with other types of - lights. Lights need to be included in the ``draw()`` to remain persistent in a - looping program. Placing them in the ``setup()`` of a looping program will cause - them to only have an effect the first time through the loop. The ``v1``, ``v2``, - and ``v3`` parameters are interpreted as either ``RGB`` or ``HSB`` values, - depending on the current color mode. + lights. Lights need to be included in the `draw()` to remain persistent in a + looping program. Placing them in the `setup()` of a looping program will cause + them to only have an effect the first time through the loop. The `v1`, `v2`, and + `v3` parameters are interpreted as either `RGB` or `HSB` values, depending on + the current color mode. """ pass @@ -2728,11 +2760,11 @@ def ambient_light(self, *args): Adds an ambient light. Ambient light doesn't come from a specific direction, the rays of light have bounced around so much that objects are evenly lit from all sides. Ambient lights are almost always used in combination with other types of - lights. Lights need to be included in the ``draw()`` to remain persistent in a - looping program. Placing them in the ``setup()`` of a looping program will cause - them to only have an effect the first time through the loop. The ``v1``, ``v2``, - and ``v3`` parameters are interpreted as either ``RGB`` or ``HSB`` values, - depending on the current color mode. + lights. Lights need to be included in the `draw()` to remain persistent in a + looping program. Placing them in the `setup()` of a looping program will cause + them to only have an effect the first time through the loop. The `v1`, `v2`, and + `v3` parameters are interpreted as either `RGB` or `HSB` values, depending on + the current color mode. """ return self._instance.ambientLight(*args) @@ -2812,7 +2844,7 @@ def apply_matrix(self, n00: float, n01: float, n02: float, Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. """ pass @@ -2909,7 +2941,7 @@ def apply_matrix( Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. """ pass @@ -2988,7 +3020,7 @@ def apply_matrix(self, source: npt.NDArray[np.floating], /) -> None: Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. """ pass @@ -3066,7 +3098,7 @@ def apply_matrix(self, *args): Multiplies the current matrix by the one specified through the parameters. This is very slow because it will try to calculate the inverse of the transform, so avoid it whenever possible. The equivalent function in OpenGL is - ``gl_mult_matrix()``. + `gl_mult_matrix()`. """ return self._instance.applyMatrix(*args) @@ -3113,20 +3145,20 @@ def arc(self, a: float, b: float, c: float, d: float, ----- Draws an arc to the screen. Arcs are drawn along the outer edge of an ellipse - defined by the ``a``, ``b``, ``c``, and ``d`` parameters. The origin of the - arc's ellipse may be changed with the ``ellipse_mode()`` function. Use the - ``start`` and ``stop`` parameters to specify the angles (in radians) at which to - draw the arc. The start/stop values must be in clockwise order. + defined by the `a`, `b`, `c`, and `d` parameters. The origin of the arc's + ellipse may be changed with the `ellipse_mode()` function. Use the `start` and + `stop` parameters to specify the angles (in radians) at which to draw the arc. + The start/stop values must be in clockwise order. There are three ways to draw an arc; the rendering technique used is defined by the optional seventh parameter. The three options, depicted in the examples, are - ``PIE``, ``OPEN``, and ``CHORD``. The default mode is the ``OPEN`` stroke with a - ``PIE`` fill. + `PIE`, `OPEN`, and `CHORD`. The default mode is the `OPEN` stroke with a `PIE` + fill. - In some cases, the ``arc()`` function isn't accurate enough for smooth drawing. + In some cases, the `arc()` function isn't accurate enough for smooth drawing. For example, the shape may jitter on screen when rotating slowly. If you're having an issue with how arcs are rendered, you'll need to draw the arc yourself - with ``begin_shape()`` & ``end_shape()`` or a ``Py5Shape``. + with `begin_shape()` & `end_shape()` or a `Py5Shape`. """ pass @@ -3173,20 +3205,20 @@ def arc(self, a: float, b: float, c: float, d: float, ----- Draws an arc to the screen. Arcs are drawn along the outer edge of an ellipse - defined by the ``a``, ``b``, ``c``, and ``d`` parameters. The origin of the - arc's ellipse may be changed with the ``ellipse_mode()`` function. Use the - ``start`` and ``stop`` parameters to specify the angles (in radians) at which to - draw the arc. The start/stop values must be in clockwise order. + defined by the `a`, `b`, `c`, and `d` parameters. The origin of the arc's + ellipse may be changed with the `ellipse_mode()` function. Use the `start` and + `stop` parameters to specify the angles (in radians) at which to draw the arc. + The start/stop values must be in clockwise order. There are three ways to draw an arc; the rendering technique used is defined by the optional seventh parameter. The three options, depicted in the examples, are - ``PIE``, ``OPEN``, and ``CHORD``. The default mode is the ``OPEN`` stroke with a - ``PIE`` fill. + `PIE`, `OPEN`, and `CHORD`. The default mode is the `OPEN` stroke with a `PIE` + fill. - In some cases, the ``arc()`` function isn't accurate enough for smooth drawing. + In some cases, the `arc()` function isn't accurate enough for smooth drawing. For example, the shape may jitter on screen when rotating slowly. If you're having an issue with how arcs are rendered, you'll need to draw the arc yourself - with ``begin_shape()`` & ``end_shape()`` or a ``Py5Shape``. + with `begin_shape()` & `end_shape()` or a `Py5Shape`. """ pass @@ -3231,26 +3263,26 @@ def arc(self, *args): ----- Draws an arc to the screen. Arcs are drawn along the outer edge of an ellipse - defined by the ``a``, ``b``, ``c``, and ``d`` parameters. The origin of the - arc's ellipse may be changed with the ``ellipse_mode()`` function. Use the - ``start`` and ``stop`` parameters to specify the angles (in radians) at which to - draw the arc. The start/stop values must be in clockwise order. + defined by the `a`, `b`, `c`, and `d` parameters. The origin of the arc's + ellipse may be changed with the `ellipse_mode()` function. Use the `start` and + `stop` parameters to specify the angles (in radians) at which to draw the arc. + The start/stop values must be in clockwise order. There are three ways to draw an arc; the rendering technique used is defined by the optional seventh parameter. The three options, depicted in the examples, are - ``PIE``, ``OPEN``, and ``CHORD``. The default mode is the ``OPEN`` stroke with a - ``PIE`` fill. + `PIE`, `OPEN`, and `CHORD`. The default mode is the `OPEN` stroke with a `PIE` + fill. - In some cases, the ``arc()`` function isn't accurate enough for smooth drawing. + In some cases, the `arc()` function isn't accurate enough for smooth drawing. For example, the shape may jitter on screen when rotating slowly. If you're having an issue with how arcs are rendered, you'll need to draw the arc yourself - with ``begin_shape()`` & ``end_shape()`` or a ``Py5Shape``. + with `begin_shape()` & `end_shape()` or a `Py5Shape`. """ return self._instance.arc(*args) @overload def background(self, gray: float, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -3295,26 +3327,26 @@ def background(self, gray: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(self, gray: float, alpha: float, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -3359,26 +3391,26 @@ def background(self, gray: float, alpha: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(self, v1: float, v2: float, v3: float, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -3423,27 +3455,27 @@ def background(self, v1: float, v2: float, v3: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(self, v1: float, v2: float, v3: float, alpha: float, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -3488,26 +3520,26 @@ def background(self, v1: float, v2: float, Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(self, rgb: int, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -3552,26 +3584,26 @@ def background(self, rgb: int, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(self, rgb: int, alpha: float, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -3616,26 +3648,26 @@ def background(self, rgb: int, alpha: float, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass @overload def background(self, image: Py5Image, /) -> None: - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -3680,27 +3712,27 @@ def background(self, image: Py5Image, /) -> None: Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ pass - @_auto_convert_to_py5image + @_auto_convert_to_py5image(0) @_convert_hex_color() def background(self, *args): - """The ``background()`` function sets the color used for the background of the py5 + """The `background()` function sets the color used for the background of the py5 window. Underlying Processing method: PApplet.background @@ -3745,87 +3777,84 @@ def background(self, *args): Notes ----- - The ``background()`` function sets the color used for the background of the py5 + The `background()` function sets the color used for the background of the py5 window. The default background is light gray. This function is typically used - within ``draw()`` to clear the display window at the beginning of each frame, - but it can be used inside ``setup()`` to set the background on the first frame - of animation or if the backgound need only be set once. + within `draw()` to clear the display window at the beginning of each frame, but + it can be used inside `setup()` to set the background on the first frame of + animation or if the backgound need only be set once. An image can also be used as the background for a Sketch, although the image's width and height must match that of the Sketch window. Images used with - ``background()`` will ignore the current ``tint()`` setting. To resize an image - to the size of the Sketch window, use ``image.resize(width, height)``. + `background()` will ignore the current `tint()` setting. To resize an image to + the size of the Sketch window, use `image.resize(width, height)`. - It is not possible to use the transparency ``alpha`` parameter with background + It is not possible to use the transparency `alpha` parameter with background colors on the main drawing surface. It can only be used along with a - ``Py5Graphics`` object and ``create_graphics()``. + `Py5Graphics` object and `create_graphics()`. """ return self._instance.background(*args) @_context_wrapper('end_camera') def begin_camera(self) -> None: - """The ``begin_camera()`` and ``end_camera()`` functions enable advanced - customization of the camera space. + """The `begin_camera()` and `end_camera()` functions enable advanced customization + of the camera space. Underlying Processing method: PApplet.beginCamera Notes ----- - The ``begin_camera()`` and ``end_camera()`` functions enable advanced - customization of the camera space. The functions are useful if you want to more - control over camera movement, however for most users, the ``camera()`` function - will be sufficient. The camera functions will replace any transformations (such - as ``rotate()`` or ``translate()``) that occur before them in ``draw()``, but - they will not automatically replace the camera transform itself. For this - reason, camera functions should be placed at the beginning of ``draw()`` (so - that transformations happen afterwards), and the ``camera()`` function can be - used after ``begin_camera()`` if you want to reset the camera before applying + The `begin_camera()` and `end_camera()` functions enable advanced customization + of the camera space. The functions are useful if you want to more control over + camera movement, however for most users, the `camera()` function will be + sufficient. The camera functions will replace any transformations (such as + `rotate()` or `translate()`) that occur before them in `draw()`, but they will + not automatically replace the camera transform itself. For this reason, camera + functions should be placed at the beginning of `draw()` (so that transformations + happen afterwards), and the `camera()` function can be used after + `begin_camera()` if you want to reset the camera before applying transformations. This function sets the matrix mode to the camera matrix so calls such as - ``translate()``, ``rotate()``, ``apply_matrix()`` and ``reset_matrix()`` affect - the camera. ``begin_camera()`` should always be used with a following - ``end_camera()`` and pairs of ``begin_camera()`` and ``end_camera()`` cannot be - nested. + `translate()`, `rotate()`, `apply_matrix()` and `reset_matrix()` affect the + camera. `begin_camera()` should always be used with a following `end_camera()` + and pairs of `begin_camera()` and `end_camera()` cannot be nested. - This method can be used as a context manager to ensure that ``end_camera()`` + This method can be used as a context manager to ensure that `end_camera()` always gets called, as shown in the last example. """ return self._instance.beginCamera() @_context_wrapper('end_contour') def begin_contour(self) -> None: - """Use the ``begin_contour()`` and ``end_contour()`` methods to create negative - shapes within shapes such as the center of the letter 'O'. + """Use the `begin_contour()` and `end_contour()` methods to create negative shapes + within shapes such as the center of the letter 'O'. Underlying Processing method: PApplet.beginContour Notes ----- - Use the ``begin_contour()`` and ``end_contour()`` methods to create negative - shapes within shapes such as the center of the letter 'O'. The - ``begin_contour()`` method begins recording vertices for the shape and - ``end_contour()`` stops recording. The vertices that define a negative shape - must "wind" in the opposite direction from the exterior shape. First draw - vertices for the exterior shape in clockwise order, then for internal shapes, - draw vertices counterclockwise. + Use the `begin_contour()` and `end_contour()` methods to create negative shapes + within shapes such as the center of the letter 'O'. The `begin_contour()` method + begins recording vertices for the shape and `end_contour()` stops recording. The + vertices that define a negative shape must "wind" in the opposite direction from + the exterior shape. First draw vertices for the exterior shape in clockwise + order, then for internal shapes, draw vertices counterclockwise. - These methods can only be used within a ``begin_shape()`` & ``end_shape()`` pair - and transformations such as ``translate()``, ``rotate()``, and ``scale()`` do - not work within a ``begin_contour()`` & ``end_contour()`` pair. It is also not - possible to use other shapes, such as ``ellipse()`` or ``rect()`` within. + These methods can only be used within a `begin_shape()` & `end_shape()` pair and + transformations such as `translate()`, `rotate()`, and `scale()` do not work + within a `begin_contour()` & `end_contour()` pair. It is also not possible to + use other shapes, such as `ellipse()` or `rect()` within. - This method can be used as a context manager to ensure that ``end_contour()`` + This method can be used as a context manager to ensure that `end_contour()` always gets called, as shown in the second example. """ return self._instance.beginContour() @overload def begin_raw(self, renderer: str, filename: str, /) -> Py5Graphics: - """To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. + """To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. Underlying Processing method: PApplet.beginRaw @@ -3852,36 +3881,35 @@ def begin_raw(self, renderer: str, filename: str, /) -> Py5Graphics: Notes ----- - To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. These commands will grab the shape data just before it is rendered to - the screen. At this stage, your entire scene is nothing but a long list of - individual lines and triangles. This means that a shape created with - ``sphere()`` function will be made up of hundreds of triangles, rather than a - single object. Or that a multi-segment line shape (such as a curve) will be - rendered as individual segments. + To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. + These commands will grab the shape data just before it is rendered to the + screen. At this stage, your entire scene is nothing but a long list of + individual lines and triangles. This means that a shape created with `sphere()` + function will be made up of hundreds of triangles, rather than a single object. + Or that a multi-segment line shape (such as a curve) will be rendered as + individual segments. - When using ``begin_raw()`` and ``end_raw()``, it's possible to write to either a - 2D or 3D renderer. For instance, ``begin_raw()`` with the ``PDF`` library will - write the geometry as flattened triangles and lines, even if recording from the - ``P3D`` renderer. + When using `begin_raw()` and `end_raw()`, it's possible to write to either a 2D + or 3D renderer. For instance, `begin_raw()` with the `PDF` library will write + the geometry as flattened triangles and lines, even if recording from the `P3D` + renderer. - If you want a background to show up in your files, use ``rect(0, 0, width, - height)`` after setting the ``fill()`` to the background color. Otherwise the + If you want a background to show up in your files, use `rect(0, 0, width, + height)` after setting the `fill()` to the background color. Otherwise the background will not be rendered to the file because the background is not a shape. - This method can be used as a context manager to ensure that ``end_raw()`` always + This method can be used as a context manager to ensure that `end_raw()` always gets called, as shown in the last example. - Using ``hint(ENABLE_DEPTH_SORT)`` can improve the appearance of 3D geometry - drawn to 2D file formats. + Using `hint(ENABLE_DEPTH_SORT)` can improve the appearance of 3D geometry drawn + to 2D file formats. """ pass @overload def begin_raw(self, raw_graphics: Py5Graphics, /) -> None: - """To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. + """To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. Underlying Processing method: PApplet.beginRaw @@ -3908,37 +3936,36 @@ def begin_raw(self, raw_graphics: Py5Graphics, /) -> None: Notes ----- - To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. These commands will grab the shape data just before it is rendered to - the screen. At this stage, your entire scene is nothing but a long list of - individual lines and triangles. This means that a shape created with - ``sphere()`` function will be made up of hundreds of triangles, rather than a - single object. Or that a multi-segment line shape (such as a curve) will be - rendered as individual segments. + To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. + These commands will grab the shape data just before it is rendered to the + screen. At this stage, your entire scene is nothing but a long list of + individual lines and triangles. This means that a shape created with `sphere()` + function will be made up of hundreds of triangles, rather than a single object. + Or that a multi-segment line shape (such as a curve) will be rendered as + individual segments. - When using ``begin_raw()`` and ``end_raw()``, it's possible to write to either a - 2D or 3D renderer. For instance, ``begin_raw()`` with the ``PDF`` library will - write the geometry as flattened triangles and lines, even if recording from the - ``P3D`` renderer. + When using `begin_raw()` and `end_raw()`, it's possible to write to either a 2D + or 3D renderer. For instance, `begin_raw()` with the `PDF` library will write + the geometry as flattened triangles and lines, even if recording from the `P3D` + renderer. - If you want a background to show up in your files, use ``rect(0, 0, width, - height)`` after setting the ``fill()`` to the background color. Otherwise the + If you want a background to show up in your files, use `rect(0, 0, width, + height)` after setting the `fill()` to the background color. Otherwise the background will not be rendered to the file because the background is not a shape. - This method can be used as a context manager to ensure that ``end_raw()`` always + This method can be used as a context manager to ensure that `end_raw()` always gets called, as shown in the last example. - Using ``hint(ENABLE_DEPTH_SORT)`` can improve the appearance of 3D geometry - drawn to 2D file formats. + Using `hint(ENABLE_DEPTH_SORT)` can improve the appearance of 3D geometry drawn + to 2D file formats. """ pass @_context_wrapper('end_raw') @_return_py5graphics def begin_raw(self, *args): - """To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. + """To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. Underlying Processing method: PApplet.beginRaw @@ -3965,29 +3992,29 @@ def begin_raw(self, *args): Notes ----- - To create vectors from 3D data, use the ``begin_raw()`` and ``end_raw()`` - commands. These commands will grab the shape data just before it is rendered to - the screen. At this stage, your entire scene is nothing but a long list of - individual lines and triangles. This means that a shape created with - ``sphere()`` function will be made up of hundreds of triangles, rather than a - single object. Or that a multi-segment line shape (such as a curve) will be - rendered as individual segments. + To create vectors from 3D data, use the `begin_raw()` and `end_raw()` commands. + These commands will grab the shape data just before it is rendered to the + screen. At this stage, your entire scene is nothing but a long list of + individual lines and triangles. This means that a shape created with `sphere()` + function will be made up of hundreds of triangles, rather than a single object. + Or that a multi-segment line shape (such as a curve) will be rendered as + individual segments. - When using ``begin_raw()`` and ``end_raw()``, it's possible to write to either a - 2D or 3D renderer. For instance, ``begin_raw()`` with the ``PDF`` library will - write the geometry as flattened triangles and lines, even if recording from the - ``P3D`` renderer. + When using `begin_raw()` and `end_raw()`, it's possible to write to either a 2D + or 3D renderer. For instance, `begin_raw()` with the `PDF` library will write + the geometry as flattened triangles and lines, even if recording from the `P3D` + renderer. - If you want a background to show up in your files, use ``rect(0, 0, width, - height)`` after setting the ``fill()`` to the background color. Otherwise the + If you want a background to show up in your files, use `rect(0, 0, width, + height)` after setting the `fill()` to the background color. Otherwise the background will not be rendered to the file because the background is not a shape. - This method can be used as a context manager to ensure that ``end_raw()`` always + This method can be used as a context manager to ensure that `end_raw()` always gets called, as shown in the last example. - Using ``hint(ENABLE_DEPTH_SORT)`` can improve the appearance of 3D geometry - drawn to 2D file formats. + Using `hint(ENABLE_DEPTH_SORT)` can improve the appearance of 3D geometry drawn + to 2D file formats. """ return self._instance.beginRaw(*args) @@ -4022,19 +4049,19 @@ def begin_record(self, renderer: str, filename: str, /) -> Py5Graphics: ----- Opens a new file and all subsequent drawing functions are echoed to this file as - well as the display window. The ``begin_record()`` function requires two + well as the display window. The `begin_record()` function requires two parameters, the first is the renderer and the second is the file name. This - function is always used with ``end_record()`` to stop the recording process and + function is always used with `end_record()` to stop the recording process and close the file. - Note that ``begin_record()`` will only pick up any settings that happen after it - has been called. For instance, if you call ``text_font()`` before - ``begin_record()``, then that font will not be set for the file that you're + Note that `begin_record()` will only pick up any settings that happen after it + has been called. For instance, if you call `text_font()` before + `begin_record()`, then that font will not be set for the file that you're recording to. - ``begin_record()`` works only with the ``PDF`` and ``SVG`` renderers. + `begin_record()` works only with the `PDF` and `SVG` renderers. - This method can be used as a context manager to ensure that ``end_record()`` + This method can be used as a context manager to ensure that `end_record()` always gets called, as shown in the last example. """ pass @@ -4070,19 +4097,19 @@ def begin_record(self, recorder: Py5Graphics, /) -> None: ----- Opens a new file and all subsequent drawing functions are echoed to this file as - well as the display window. The ``begin_record()`` function requires two + well as the display window. The `begin_record()` function requires two parameters, the first is the renderer and the second is the file name. This - function is always used with ``end_record()`` to stop the recording process and + function is always used with `end_record()` to stop the recording process and close the file. - Note that ``begin_record()`` will only pick up any settings that happen after it - has been called. For instance, if you call ``text_font()`` before - ``begin_record()``, then that font will not be set for the file that you're + Note that `begin_record()` will only pick up any settings that happen after it + has been called. For instance, if you call `text_font()` before + `begin_record()`, then that font will not be set for the file that you're recording to. - ``begin_record()`` works only with the ``PDF`` and ``SVG`` renderers. + `begin_record()` works only with the `PDF` and `SVG` renderers. - This method can be used as a context manager to ensure that ``end_record()`` + This method can be used as a context manager to ensure that `end_record()` always gets called, as shown in the last example. """ pass @@ -4119,26 +4146,26 @@ def begin_record(self, *args): ----- Opens a new file and all subsequent drawing functions are echoed to this file as - well as the display window. The ``begin_record()`` function requires two + well as the display window. The `begin_record()` function requires two parameters, the first is the renderer and the second is the file name. This - function is always used with ``end_record()`` to stop the recording process and + function is always used with `end_record()` to stop the recording process and close the file. - Note that ``begin_record()`` will only pick up any settings that happen after it - has been called. For instance, if you call ``text_font()`` before - ``begin_record()``, then that font will not be set for the file that you're + Note that `begin_record()` will only pick up any settings that happen after it + has been called. For instance, if you call `text_font()` before + `begin_record()`, then that font will not be set for the file that you're recording to. - ``begin_record()`` works only with the ``PDF`` and ``SVG`` renderers. + `begin_record()` works only with the `PDF` and `SVG` renderers. - This method can be used as a context manager to ensure that ``end_record()`` + This method can be used as a context manager to ensure that `end_record()` always gets called, as shown in the last example. """ return self._instance.beginRecord(*args) @overload def begin_shape(self) -> None: - """Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more + """Using the `begin_shape()` and `end_shape()` functions allow creating more complex forms. Underlying Processing method: PApplet.beginShape @@ -4160,39 +4187,38 @@ def begin_shape(self) -> None: Notes ----- - Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more - complex forms. ``begin_shape()`` begins recording vertices for a shape and - ``end_shape()`` stops recording. The value of the ``kind`` parameter tells it - which types of shapes to create from the provided vertices. With no mode - specified, the shape can be any irregular polygon. The parameters available for - ``begin_shape()`` are ``POINTS``, ``LINES``, ``TRIANGLES``, ``TRIANGLE_FAN``, - ``TRIANGLE_STRIP``, ``QUADS``, and ``QUAD_STRIP``. After calling the - ``begin_shape()`` function, a series of ``vertex()`` commands must follow. To - stop drawing the shape, call ``end_shape()``. The ``vertex()`` function with two - parameters specifies a position in 2D and the ``vertex()`` function with three - parameters specifies a position in 3D. Each shape will be outlined with the - current stroke color and filled with the fill color. + Using the `begin_shape()` and `end_shape()` functions allow creating more + complex forms. `begin_shape()` begins recording vertices for a shape and + `end_shape()` stops recording. The value of the `kind` parameter tells it which + types of shapes to create from the provided vertices. With no mode specified, + the shape can be any irregular polygon. The parameters available for + `begin_shape()` are `POINTS`, `LINES`, `TRIANGLES`, `TRIANGLE_FAN`, + `TRIANGLE_STRIP`, `QUADS`, and `QUAD_STRIP`. After calling the `begin_shape()` + function, a series of `vertex()` commands must follow. To stop drawing the + shape, call `end_shape()`. The `vertex()` function with two parameters specifies + a position in 2D and the `vertex()` function with three parameters specifies a + position in 3D. Each shape will be outlined with the current stroke color and + filled with the fill color. - Transformations such as ``translate()``, ``rotate()``, and ``scale()`` do not - work within ``begin_shape()``. It is also not possible to use other shapes, such - as ``ellipse()`` or ``rect()`` within ``begin_shape()``. + Transformations such as `translate()`, `rotate()`, and `scale()` do not work + within `begin_shape()`. It is also not possible to use other shapes, such as + `ellipse()` or `rect()` within `begin_shape()`. - The ``P2D`` and ``P3D`` renderers allow ``stroke()`` and ``fill()`` to be - altered on a per-vertex basis, but the default renderer does not. Settings such - as ``stroke_weight()``, ``stroke_cap()``, and ``stroke_join()`` cannot be - changed while inside a ``begin_shape()`` & ``end_shape()`` block with any - renderer. + The `P2D` and `P3D` renderers allow `stroke()` and `fill()` to be altered on a + per-vertex basis, but the default renderer does not. Settings such as + `stroke_weight()`, `stroke_cap()`, and `stroke_join()` cannot be changed while + inside a `begin_shape()` & `end_shape()` block with any renderer. - This method can be used as a context manager to ensure that ``end_shape()`` - always gets called, as shown in the last example. Use ``begin_closed_shape()`` - to create a context manager that will pass the ``CLOSE`` parameter to - ``end_shape()``, closing the shape. + This method can be used as a context manager to ensure that `end_shape()` always + gets called, as shown in the last example. Use `begin_closed_shape()` to create + a context manager that will pass the `CLOSE` parameter to `end_shape()`, closing + the shape. """ pass @overload def begin_shape(self, kind: int, /) -> None: - """Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more + """Using the `begin_shape()` and `end_shape()` functions allow creating more complex forms. Underlying Processing method: PApplet.beginShape @@ -4214,39 +4240,38 @@ def begin_shape(self, kind: int, /) -> None: Notes ----- - Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more - complex forms. ``begin_shape()`` begins recording vertices for a shape and - ``end_shape()`` stops recording. The value of the ``kind`` parameter tells it - which types of shapes to create from the provided vertices. With no mode - specified, the shape can be any irregular polygon. The parameters available for - ``begin_shape()`` are ``POINTS``, ``LINES``, ``TRIANGLES``, ``TRIANGLE_FAN``, - ``TRIANGLE_STRIP``, ``QUADS``, and ``QUAD_STRIP``. After calling the - ``begin_shape()`` function, a series of ``vertex()`` commands must follow. To - stop drawing the shape, call ``end_shape()``. The ``vertex()`` function with two - parameters specifies a position in 2D and the ``vertex()`` function with three - parameters specifies a position in 3D. Each shape will be outlined with the - current stroke color and filled with the fill color. + Using the `begin_shape()` and `end_shape()` functions allow creating more + complex forms. `begin_shape()` begins recording vertices for a shape and + `end_shape()` stops recording. The value of the `kind` parameter tells it which + types of shapes to create from the provided vertices. With no mode specified, + the shape can be any irregular polygon. The parameters available for + `begin_shape()` are `POINTS`, `LINES`, `TRIANGLES`, `TRIANGLE_FAN`, + `TRIANGLE_STRIP`, `QUADS`, and `QUAD_STRIP`. After calling the `begin_shape()` + function, a series of `vertex()` commands must follow. To stop drawing the + shape, call `end_shape()`. The `vertex()` function with two parameters specifies + a position in 2D and the `vertex()` function with three parameters specifies a + position in 3D. Each shape will be outlined with the current stroke color and + filled with the fill color. - Transformations such as ``translate()``, ``rotate()``, and ``scale()`` do not - work within ``begin_shape()``. It is also not possible to use other shapes, such - as ``ellipse()`` or ``rect()`` within ``begin_shape()``. + Transformations such as `translate()`, `rotate()`, and `scale()` do not work + within `begin_shape()`. It is also not possible to use other shapes, such as + `ellipse()` or `rect()` within `begin_shape()`. - The ``P2D`` and ``P3D`` renderers allow ``stroke()`` and ``fill()`` to be - altered on a per-vertex basis, but the default renderer does not. Settings such - as ``stroke_weight()``, ``stroke_cap()``, and ``stroke_join()`` cannot be - changed while inside a ``begin_shape()`` & ``end_shape()`` block with any - renderer. + The `P2D` and `P3D` renderers allow `stroke()` and `fill()` to be altered on a + per-vertex basis, but the default renderer does not. Settings such as + `stroke_weight()`, `stroke_cap()`, and `stroke_join()` cannot be changed while + inside a `begin_shape()` & `end_shape()` block with any renderer. - This method can be used as a context manager to ensure that ``end_shape()`` - always gets called, as shown in the last example. Use ``begin_closed_shape()`` - to create a context manager that will pass the ``CLOSE`` parameter to - ``end_shape()``, closing the shape. + This method can be used as a context manager to ensure that `end_shape()` always + gets called, as shown in the last example. Use `begin_closed_shape()` to create + a context manager that will pass the `CLOSE` parameter to `end_shape()`, closing + the shape. """ pass @_context_wrapper('end_shape') def begin_shape(self, *args): - """Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more + """Using the `begin_shape()` and `end_shape()` functions allow creating more complex forms. Underlying Processing method: PApplet.beginShape @@ -4268,33 +4293,32 @@ def begin_shape(self, *args): Notes ----- - Using the ``begin_shape()`` and ``end_shape()`` functions allow creating more - complex forms. ``begin_shape()`` begins recording vertices for a shape and - ``end_shape()`` stops recording. The value of the ``kind`` parameter tells it - which types of shapes to create from the provided vertices. With no mode - specified, the shape can be any irregular polygon. The parameters available for - ``begin_shape()`` are ``POINTS``, ``LINES``, ``TRIANGLES``, ``TRIANGLE_FAN``, - ``TRIANGLE_STRIP``, ``QUADS``, and ``QUAD_STRIP``. After calling the - ``begin_shape()`` function, a series of ``vertex()`` commands must follow. To - stop drawing the shape, call ``end_shape()``. The ``vertex()`` function with two - parameters specifies a position in 2D and the ``vertex()`` function with three - parameters specifies a position in 3D. Each shape will be outlined with the - current stroke color and filled with the fill color. + Using the `begin_shape()` and `end_shape()` functions allow creating more + complex forms. `begin_shape()` begins recording vertices for a shape and + `end_shape()` stops recording. The value of the `kind` parameter tells it which + types of shapes to create from the provided vertices. With no mode specified, + the shape can be any irregular polygon. The parameters available for + `begin_shape()` are `POINTS`, `LINES`, `TRIANGLES`, `TRIANGLE_FAN`, + `TRIANGLE_STRIP`, `QUADS`, and `QUAD_STRIP`. After calling the `begin_shape()` + function, a series of `vertex()` commands must follow. To stop drawing the + shape, call `end_shape()`. The `vertex()` function with two parameters specifies + a position in 2D and the `vertex()` function with three parameters specifies a + position in 3D. Each shape will be outlined with the current stroke color and + filled with the fill color. - Transformations such as ``translate()``, ``rotate()``, and ``scale()`` do not - work within ``begin_shape()``. It is also not possible to use other shapes, such - as ``ellipse()`` or ``rect()`` within ``begin_shape()``. + Transformations such as `translate()`, `rotate()`, and `scale()` do not work + within `begin_shape()`. It is also not possible to use other shapes, such as + `ellipse()` or `rect()` within `begin_shape()`. - The ``P2D`` and ``P3D`` renderers allow ``stroke()`` and ``fill()`` to be - altered on a per-vertex basis, but the default renderer does not. Settings such - as ``stroke_weight()``, ``stroke_cap()``, and ``stroke_join()`` cannot be - changed while inside a ``begin_shape()`` & ``end_shape()`` block with any - renderer. + The `P2D` and `P3D` renderers allow `stroke()` and `fill()` to be altered on a + per-vertex basis, but the default renderer does not. Settings such as + `stroke_weight()`, `stroke_cap()`, and `stroke_join()` cannot be changed while + inside a `begin_shape()` & `end_shape()` block with any renderer. - This method can be used as a context manager to ensure that ``end_shape()`` - always gets called, as shown in the last example. Use ``begin_closed_shape()`` - to create a context manager that will pass the ``CLOSE`` parameter to - ``end_shape()``, closing the shape. + This method can be used as a context manager to ensure that `end_shape()` always + gets called, as shown in the last example. Use `begin_closed_shape()` to create + a context manager that will pass the `CLOSE` parameter to `end_shape()`, closing + the shape. """ return self._instance.beginShape(*args) @@ -4323,12 +4347,12 @@ def begin_closed_shape(self) -> None: This method is used to start a custom closed shape. This method should only be used as a context manager, as shown in the examples. When used as a context - manager, this will ensure that ``end_shape()`` always gets called, just like - when using ``begin_shape()`` as a context manager. The difference is that when - exiting, the parameter ``CLOSE`` will be passed to ``end_shape()``, connecting - the last vertex to the first. This will close the shape. If this method were to - be used not as a context manager, it won't be able to close the shape by making - the call to ``end_shape()``. + manager, this will ensure that `end_shape()` always gets called, just like when + using `begin_shape()` as a context manager. The difference is that when exiting, + the parameter `CLOSE` will be passed to `end_shape()`, connecting the last + vertex to the first. This will close the shape. If this method were to be used + not as a context manager, it won't be able to close the shape by making the call + to `end_shape()`. """ pass @@ -4357,12 +4381,12 @@ def begin_closed_shape(self, kind: int, /) -> None: This method is used to start a custom closed shape. This method should only be used as a context manager, as shown in the examples. When used as a context - manager, this will ensure that ``end_shape()`` always gets called, just like - when using ``begin_shape()`` as a context manager. The difference is that when - exiting, the parameter ``CLOSE`` will be passed to ``end_shape()``, connecting - the last vertex to the first. This will close the shape. If this method were to - be used not as a context manager, it won't be able to close the shape by making - the call to ``end_shape()``. + manager, this will ensure that `end_shape()` always gets called, just like when + using `begin_shape()` as a context manager. The difference is that when exiting, + the parameter `CLOSE` will be passed to `end_shape()`, connecting the last + vertex to the first. This will close the shape. If this method were to be used + not as a context manager, it won't be able to close the shape by making the call + to `end_shape()`. """ pass @@ -4391,12 +4415,12 @@ def begin_closed_shape(self, *args): This method is used to start a custom closed shape. This method should only be used as a context manager, as shown in the examples. When used as a context - manager, this will ensure that ``end_shape()`` always gets called, just like - when using ``begin_shape()`` as a context manager. The difference is that when - exiting, the parameter ``CLOSE`` will be passed to ``end_shape()``, connecting - the last vertex to the first. This will close the shape. If this method were to - be used not as a context manager, it won't be able to close the shape by making - the call to ``end_shape()``. + manager, this will ensure that `end_shape()` always gets called, just like when + using `begin_shape()` as a context manager. The difference is that when exiting, + the parameter `CLOSE` will be passed to `end_shape()`, connecting the last + vertex to the first. This will close the shape. If this method were to be used + not as a context manager, it won't be able to close the shape by making the call + to `end_shape()`. """ return self._instance.beginShape(*args) @@ -4462,7 +4486,7 @@ def bezier(self, x1: float, y1: float, x2: float, y2: float, point and the last two parameters specify the other anchor point. The middle parameters specify the control points which define the shape of the curve. Bezier curves were developed by French engineer Pierre Bezier. Using the 3D - version requires rendering with ``P3D``. + version requires rendering with `P3D`. """ pass @@ -4528,7 +4552,7 @@ def bezier(self, x1: float, y1: float, z1: float, x2: float, y2: float, z2: floa point and the last two parameters specify the other anchor point. The middle parameters specify the control points which define the shape of the curve. Bezier curves were developed by French engineer Pierre Bezier. Using the 3D - version requires rendering with ``P3D``. + version requires rendering with `P3D`. """ pass @@ -4592,7 +4616,7 @@ def bezier(self, *args): point and the last two parameters specify the other anchor point. The middle parameters specify the control points which define the shape of the curve. Bezier curves were developed by French engineer Pierre Bezier. Using the 3D - version requires rendering with ``P3D``. + version requires rendering with `P3D`. """ return self._instance.bezier(*args) @@ -4611,7 +4635,7 @@ def bezier_detail(self, detail: int, /) -> None: ----- Sets the resolution at which Beziers display. The default value is 20. This - function is only useful when using the ``P3D`` renderer; the default ``P2D`` + function is only useful when using the `P3D` renderer; the default `P2D` renderer does not use this information. """ return self._instance.bezierDetail(detail) @@ -4730,14 +4754,14 @@ def bezier_vertex(self, x2: float, y2: float, x3: float, Notes ----- - Specifies vertex coordinates for Bezier curves. Each call to ``bezier_vertex()`` + Specifies vertex coordinates for Bezier curves. Each call to `bezier_vertex()` defines the position of two control points and one anchor point of a Bezier - curve, adding a new segment to a line or shape. The first time - ``bezier_vertex()`` is used within a ``begin_shape()`` call, it must be prefaced - with a call to ``vertex()`` to set the first anchor point. This function must be - used between ``begin_shape()`` and ``end_shape()`` and only when there is no - ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + curve, adding a new segment to a line or shape. The first time `bezier_vertex()` + is used within a `begin_shape()` call, it must be prefaced with a call to + `vertex()` to set the first anchor point. This function must be used between + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. Using the 3D version requires rendering with + `P3D`. """ pass @@ -4789,14 +4813,14 @@ def bezier_vertex(self, x2: float, y2: float, z2: float, x3: float, Notes ----- - Specifies vertex coordinates for Bezier curves. Each call to ``bezier_vertex()`` + Specifies vertex coordinates for Bezier curves. Each call to `bezier_vertex()` defines the position of two control points and one anchor point of a Bezier - curve, adding a new segment to a line or shape. The first time - ``bezier_vertex()`` is used within a ``begin_shape()`` call, it must be prefaced - with a call to ``vertex()`` to set the first anchor point. This function must be - used between ``begin_shape()`` and ``end_shape()`` and only when there is no - ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + curve, adding a new segment to a line or shape. The first time `bezier_vertex()` + is used within a `begin_shape()` call, it must be prefaced with a call to + `vertex()` to set the first anchor point. This function must be used between + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. Using the 3D version requires rendering with + `P3D`. """ pass @@ -4846,17 +4870,18 @@ def bezier_vertex(self, *args): Notes ----- - Specifies vertex coordinates for Bezier curves. Each call to ``bezier_vertex()`` + Specifies vertex coordinates for Bezier curves. Each call to `bezier_vertex()` defines the position of two control points and one anchor point of a Bezier - curve, adding a new segment to a line or shape. The first time - ``bezier_vertex()`` is used within a ``begin_shape()`` call, it must be prefaced - with a call to ``vertex()`` to set the first anchor point. This function must be - used between ``begin_shape()`` and ``end_shape()`` and only when there is no - ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version requires - rendering with ``P3D``. + curve, adding a new segment to a line or shape. The first time `bezier_vertex()` + is used within a `begin_shape()` call, it must be prefaced with a call to + `vertex()` to set the first anchor point. This function must be used between + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. Using the 3D version requires rendering with + `P3D`. """ return self._instance.bezierVertex(*args) + @_generator_to_list def bezier_vertices( self, coordinates: npt.NDArray[np.floating], /) -> None: """Create a collection of bezier vertices. @@ -4873,14 +4898,14 @@ def bezier_vertices( ----- Create a collection of bezier vertices. The purpose of this method is to provide - an alternative to repeatedly calling ``bezier_vertex()`` in a loop. For a large - number of bezier vertices, the performance of ``bezier_vertices()`` will be much + an alternative to repeatedly calling `bezier_vertex()` in a loop. For a large + number of bezier vertices, the performance of `bezier_vertices()` will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each - bezier vertex. The first few columns are for the first control point, the next - few columns are for the second control point, and the final few columns are for - the anchor point. There should be six or nine columns for 2D or 3D points, + The `coordinates` parameter should be a numpy array with one row for each bezier + vertex. The first few columns are for the first control point, the next few + columns are for the second control point, and the final few columns are for the + anchor point. There should be six or nine columns for 2D or 3D points, respectively. """ return self._instance.bezierVertices(coordinates) @@ -4941,11 +4966,11 @@ def blend(self, sx: int, sy: int, sw: int, sh: int, dx: int, full alpha channel support. There is a choice of the following modes to blend the source pixels (A) with the ones of pixels in the destination image (B): - * BLEND: linear interpolation of colors: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colors: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -4962,10 +4987,10 @@ def blend(self, sx: int, sy: int, sw: int, sh: int, dx: int, All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the display window is used as the source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the display window is used as the source image. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @@ -5025,11 +5050,11 @@ def blend(self, src: Py5Image, sx: int, sy: int, sw: int, sh: int, full alpha channel support. There is a choice of the following modes to blend the source pixels (A) with the ones of pixels in the destination image (B): - * BLEND: linear interpolation of colors: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colors: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -5046,14 +5071,14 @@ def blend(self, src: Py5Image, sx: int, sy: int, sw: int, sh: int, All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the display window is used as the source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the display window is used as the source image. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass - @_auto_convert_to_py5image + @_auto_convert_to_py5image(0) def blend(self, *args): """Blends a region of pixels from one image into another (or in itself again) with full alpha channel support. @@ -5108,11 +5133,11 @@ def blend(self, *args): full alpha channel support. There is a choice of the following modes to blend the source pixels (A) with the ones of pixels in the destination image (B): - * BLEND: linear interpolation of colors: ``C = A*factor + B`` - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * BLEND: linear interpolation of colors: `C = A*factor + B` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: Multiply the colors, result will always be darker. @@ -5129,10 +5154,10 @@ def blend(self, *args): All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the - image will be automatically resized to match the destination size. If the - ``src`` parameter is not used, the display window is used as the source image. + image will be automatically resized to match the destination size. If the `src` + parameter is not used, the display window is used as the source image. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ return self._instance.blend(*args) @@ -5157,12 +5182,12 @@ def blend_mode(self, mode: int, /) -> None: independently. The red channel is compared with red, green with green, and blue with blue. - * BLEND: linear interpolation of colors: ``C = A*factor + B``. This is the + * BLEND: linear interpolation of colors: `C = A*factor + B`. This is the default. - * ADD: additive blending with white clip: ``C = min(A*factor + B, 255)`` - * SUBTRACT: subtractive blending with black clip: ``C = max(B - A*factor, 0)`` - * DARKEST: only the darkest color succeeds: ``C = min(A*factor, B)`` - * LIGHTEST: only the lightest color succeeds: ``C = max(A*factor, B)`` + * ADD: additive blending with white clip: `C = min(A*factor + B, 255)` + * SUBTRACT: subtractive blending with black clip: `C = max(B - A*factor, 0)` + * DARKEST: only the darkest color succeeds: `C = min(A*factor, B)` + * LIGHTEST: only the lightest color succeeds: `C = max(A*factor, B)` * DIFFERENCE: subtract colors from underlying image. * EXCLUSION: similar to DIFFERENCE, but less extreme. * MULTIPLY: multiply the colors, result will always be darker. @@ -5170,17 +5195,17 @@ def blend_mode(self, mode: int, /) -> None: * REPLACE: the pixels entirely replace the others and don't utilize alpha (transparency) values - We recommend using ``blend_mode()`` and not the previous ``blend()`` function. - However, unlike ``blend()``, the ``blend_mode()`` function does not support the - following: ``HARD_LIGHT``, ``SOFT_LIGHT``, ``OVERLAY``, ``DODGE``, ``BURN``. On - older hardware, the ``LIGHTEST``, ``DARKEST``, and ``DIFFERENCE`` modes might - not be available as well. + We recommend using `blend_mode()` and not the previous `blend()` function. + However, unlike `blend()`, the `blend_mode()` function does not support the + following: `HARD_LIGHT`, `SOFT_LIGHT`, `OVERLAY`, `DODGE`, `BURN`. On older + hardware, the `LIGHTEST`, `DARKEST`, and `DIFFERENCE` modes might not be + available as well. """ return self._instance.blendMode(mode) @_convert_hex_color() def blue(self, rgb: int, /) -> float: - """Extracts the blue value from a color, scaled to match current ``color_mode()``. + """Extracts the blue value from a color, scaled to match current `color_mode()`. Underlying Processing method: PApplet.blue @@ -5193,14 +5218,13 @@ def blue(self, rgb: int, /) -> float: Notes ----- - Extracts the blue value from a color, scaled to match current ``color_mode()``. + Extracts the blue value from a color, scaled to match current `color_mode()`. - The ``blue()`` function is easy to use and understand, but it is slower than a - technique called bit masking. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``blue()`` but with greater speed by using a bit - mask to remove the other color components. For example, ``blue(c)`` and ``c & - 0xFF`` both extract the blue value from a color variable ``c`` but the later is - faster. + The `blue()` function is easy to use and understand, but it is slower than a + technique called bit masking. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `blue()` but with greater speed by using a bit mask + to remove the other color components. For example, `blue(c)` and `c & 0xFF` both + extract the blue value from a color variable `c` but the later is faster. """ return self._instance.blue(rgb) @@ -5386,9 +5410,9 @@ def camera(self) -> None: direction it is pointing (the center of the scene) allows the images to be seen from different angles. The version without any parameters sets the camera to the default position, pointing to the center of the display window with the Y axis - as up. The default values are ``camera(width//2.0, height//2.0, (height//2.0) / - tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)``. This function is - similar to ``glu_look_at()`` in OpenGL, but it first clears the current camera + as up. The default values are `camera(width//2.0, height//2.0, (height//2.0) / + tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)`. This function is + similar to `glu_look_at()` in OpenGL, but it first clears the current camera settings. """ pass @@ -5457,9 +5481,9 @@ def camera( direction it is pointing (the center of the scene) allows the images to be seen from different angles. The version without any parameters sets the camera to the default position, pointing to the center of the display window with the Y axis - as up. The default values are ``camera(width//2.0, height//2.0, (height//2.0) / - tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)``. This function is - similar to ``glu_look_at()`` in OpenGL, but it first clears the current camera + as up. The default values are `camera(width//2.0, height//2.0, (height//2.0) / + tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)`. This function is + similar to `glu_look_at()` in OpenGL, but it first clears the current camera settings. """ pass @@ -5516,9 +5540,9 @@ def camera(self, *args): direction it is pointing (the center of the scene) allows the images to be seen from different angles. The version without any parameters sets the camera to the default position, pointing to the center of the display window with the Y axis - as up. The default values are ``camera(width//2.0, height//2.0, (height//2.0) / - tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)``. This function is - similar to ``glu_look_at()`` in OpenGL, but it first clears the current camera + as up. The default values are `camera(width//2.0, height//2.0, (height//2.0) / + tan(PI*30.0 / 180.0), width//2.0, height//2.0, 0, 0, 1, 0)`. This function is + similar to `glu_look_at()` in OpenGL, but it first clears the current camera settings. """ return self._instance.camera(*args) @@ -5545,7 +5569,7 @@ def circle(self, x: float, y: float, extent: float, /) -> None: Draws a circle to the screen. By default, the first two parameters set the location of the center, and the third sets the shape's width and height. The - origin may be changed with the ``ellipse_mode()`` function. + origin may be changed with the `ellipse_mode()` function. """ return self._instance.circle(x, y, extent) @@ -5558,11 +5582,10 @@ def clear(self) -> None: ----- Clear the drawing surface by setting every pixel to black. Calling this method - is the same as passing ``0`` to the ``background()`` method, as in - ``background(0)``. + is the same as passing `0` to the `background()` method, as in `background(0)`. - This method behaves differently than ``Py5Graphics.clear()`` because - ``Py5Graphics`` objects allow transparent pixels. + This method behaves differently than `Py5Graphics.clear()` because `Py5Graphics` + objects allow transparent pixels. """ return self._instance.clear() @@ -5590,14 +5613,14 @@ def clip(self, a: float, b: float, c: float, d: float, /) -> None: ----- Limits the rendering to the boundaries of a rectangle defined by the parameters. - The boundaries are drawn based on the state of the ``image_mode()`` fuction, - either ``CORNER``, ``CORNERS``, or ``CENTER``. + The boundaries are drawn based on the state of the `image_mode()` fuction, + either `CORNER`, `CORNERS`, or `CENTER`. """ return self._instance.clip(a, b, c, d) @overload def color(self, fgray: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -5655,42 +5678,42 @@ def color(self, fgray: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(self, fgray: float, falpha: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -5748,42 +5771,42 @@ def color(self, fgray: float, falpha: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(self, v1: float, v2: float, v3: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -5841,42 +5864,42 @@ def color(self, v1: float, v2: float, v3: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(self, v1: float, v2: float, v3: float, alpha: float, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -5934,42 +5957,42 @@ def color(self, v1: float, v2: float, v3: float, alpha: float, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(self, gray: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -6027,42 +6050,42 @@ def color(self, gray: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(self, gray: int, alpha: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -6120,42 +6143,42 @@ def color(self, gray: int, alpha: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(self, v1: int, v2: int, v3: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -6213,42 +6236,42 @@ def color(self, v1: int, v2: int, v3: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @overload def color(self, v1: int, v2: int, v3: int, alpha: int, /) -> int: - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -6306,42 +6329,42 @@ def color(self, v1: int, v2: int, v3: int, alpha: int, /) -> int: Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ pass @_convert_hex_color() def color(self, *args): - """Creates colors for storing in variables of the ``color`` datatype (a 32 bit + """Creates colors for storing in variables of the `color` datatype (a 32 bit integer). Underlying Processing method: PApplet.color @@ -6399,36 +6422,36 @@ def color(self, *args): Notes ----- - Creates colors for storing in variables of the ``color`` datatype (a 32 bit - integer). The parameters are interpreted as ``RGB`` or ``HSB`` values depending - on the current ``color_mode()``. The default mode is ``RGB`` values from 0 to - 255 and, therefore, ``color(255, 204, 0)`` will return a bright yellow color - (see the first example). + Creates colors for storing in variables of the `color` datatype (a 32 bit + integer). The parameters are interpreted as `RGB` or `HSB` values depending on + the current `color_mode()`. The default mode is `RGB` values from 0 to 255 and, + therefore, `color(255, 204, 0)` will return a bright yellow color (see the first + example). - Note that if only one value is provided to ``color()``, it will be interpreted - as a grayscale value. Add a second value, and it will be used for alpha + Note that if only one value is provided to `color()`, it will be interpreted as + a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either - ``RGB`` or ``HSB`` values. Adding a fourth value applies alpha transparency. + `RGB` or `HSB` values. Adding a fourth value applies alpha transparency. Note that you can also use hexadecimal notation and web color notation to - specify colors, as in ``c = 0xFFDDCC33`` or ``c = "#DDCC33FF"`` in place of ``c - = color(221, 204, 51, 255)``. Additionally, the ``color()`` method can accept - both color notations as a parameter. + specify colors, as in `c = 0xFFDDCC33` or `c = "#DDCC33FF"` in place of `c = + color(221, 204, 51, 255)`. Additionally, the `color()` method can accept both + color notations as a parameter. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. """ return self._instance.color(*args) @@ -6473,21 +6496,20 @@ def color_mode(self, mode: int, /) -> None: ----- Changes the way py5 interprets color data. By default, the parameters for - ``fill()``, ``stroke()``, ``background()``, and ``color()`` are defined by - values between 0 and 255 using the ``RGB`` color model. The ``color_mode()`` - function is used to change the numerical range used for specifying colors and to - switch color systems. For example, calling ``color_mode(RGB, 1.0)`` will specify - that values are specified between 0 and 1. The limits for defining colors are - altered by setting the parameters ``max``, ``max1``, ``max2``, ``max3``, and - ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `fill()`, `stroke()`, `background()`, and `color()` are defined by values + between 0 and 255 using the `RGB` color model. The `color_mode()` function is + used to change the numerical range used for specifying colors and to switch + color systems. For example, calling `color_mode(RGB, 1.0)` will specify that + values are specified between 0 and 1. The limits for defining colors are altered + by setting the parameters `max`, `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. """ pass @@ -6532,21 +6554,20 @@ def color_mode(self, mode: int, max: float, /) -> None: ----- Changes the way py5 interprets color data. By default, the parameters for - ``fill()``, ``stroke()``, ``background()``, and ``color()`` are defined by - values between 0 and 255 using the ``RGB`` color model. The ``color_mode()`` - function is used to change the numerical range used for specifying colors and to - switch color systems. For example, calling ``color_mode(RGB, 1.0)`` will specify - that values are specified between 0 and 1. The limits for defining colors are - altered by setting the parameters ``max``, ``max1``, ``max2``, ``max3``, and - ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `fill()`, `stroke()`, `background()`, and `color()` are defined by values + between 0 and 255 using the `RGB` color model. The `color_mode()` function is + used to change the numerical range used for specifying colors and to switch + color systems. For example, calling `color_mode(RGB, 1.0)` will specify that + values are specified between 0 and 1. The limits for defining colors are altered + by setting the parameters `max`, `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. """ pass @@ -6592,21 +6613,20 @@ def color_mode(self, mode: int, max1: float, ----- Changes the way py5 interprets color data. By default, the parameters for - ``fill()``, ``stroke()``, ``background()``, and ``color()`` are defined by - values between 0 and 255 using the ``RGB`` color model. The ``color_mode()`` - function is used to change the numerical range used for specifying colors and to - switch color systems. For example, calling ``color_mode(RGB, 1.0)`` will specify - that values are specified between 0 and 1. The limits for defining colors are - altered by setting the parameters ``max``, ``max1``, ``max2``, ``max3``, and - ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `fill()`, `stroke()`, `background()`, and `color()` are defined by values + between 0 and 255 using the `RGB` color model. The `color_mode()` function is + used to change the numerical range used for specifying colors and to switch + color systems. For example, calling `color_mode(RGB, 1.0)` will specify that + values are specified between 0 and 1. The limits for defining colors are altered + by setting the parameters `max`, `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. """ pass @@ -6652,21 +6672,20 @@ def color_mode(self, mode: int, max1: float, max2: float, ----- Changes the way py5 interprets color data. By default, the parameters for - ``fill()``, ``stroke()``, ``background()``, and ``color()`` are defined by - values between 0 and 255 using the ``RGB`` color model. The ``color_mode()`` - function is used to change the numerical range used for specifying colors and to - switch color systems. For example, calling ``color_mode(RGB, 1.0)`` will specify - that values are specified between 0 and 1. The limits for defining colors are - altered by setting the parameters ``max``, ``max1``, ``max2``, ``max3``, and - ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `fill()`, `stroke()`, `background()`, and `color()` are defined by values + between 0 and 255 using the `RGB` color model. The `color_mode()` function is + used to change the numerical range used for specifying colors and to switch + color systems. For example, calling `color_mode(RGB, 1.0)` will specify that + values are specified between 0 and 1. The limits for defining colors are altered + by setting the parameters `max`, `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. """ pass @@ -6710,28 +6729,27 @@ def color_mode(self, *args): ----- Changes the way py5 interprets color data. By default, the parameters for - ``fill()``, ``stroke()``, ``background()``, and ``color()`` are defined by - values between 0 and 255 using the ``RGB`` color model. The ``color_mode()`` - function is used to change the numerical range used for specifying colors and to - switch color systems. For example, calling ``color_mode(RGB, 1.0)`` will specify - that values are specified between 0 and 1. The limits for defining colors are - altered by setting the parameters ``max``, ``max1``, ``max2``, ``max3``, and - ``max_a``. - - After changing the range of values for colors with code like ``color_mode(HSB, - 360, 100, 100)``, those ranges remain in use until they are explicitly changed - again. For example, after running ``color_mode(HSB, 360, 100, 100)`` and then - changing back to ``color_mode(RGB)``, the range for R will be 0 to 360 and the + `fill()`, `stroke()`, `background()`, and `color()` are defined by values + between 0 and 255 using the `RGB` color model. The `color_mode()` function is + used to change the numerical range used for specifying colors and to switch + color systems. For example, calling `color_mode(RGB, 1.0)` will specify that + values are specified between 0 and 1. The limits for defining colors are altered + by setting the parameters `max`, `max1`, `max2`, `max3`, and `max_a`. + + After changing the range of values for colors with code like `color_mode(HSB, + 360, 100, 100)`, those ranges remain in use until they are explicitly changed + again. For example, after running `color_mode(HSB, 360, 100, 100)` and then + changing back to `color_mode(RGB)`, the range for R will be 0 to 360 and the range for G and B will be 0 to 100. To avoid this, be explicit about the ranges - when changing the color mode. For instance, instead of ``color_mode(RGB)``, - write ``color_mode(RGB, 255, 255, 255)``. + when changing the color mode. For instance, instead of `color_mode(RGB)`, write + `color_mode(RGB, 255, 255, 255)`. """ return self._instance.colorMode(*args) @overload def copy(self) -> Py5Image: """Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. Underlying Processing method: PApplet.copy @@ -6779,13 +6797,13 @@ def copy(self) -> Py5Image: ----- Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @@ -6793,7 +6811,7 @@ def copy(self) -> Py5Image: def copy(self, sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, /) -> None: """Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. Underlying Processing method: PApplet.copy @@ -6841,13 +6859,13 @@ def copy(self, sx: int, sy: int, sw: int, sh: int, ----- Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass @@ -6855,7 +6873,7 @@ def copy(self, sx: int, sy: int, sw: int, sh: int, def copy(self, src: Py5Image, sx: int, sy: int, sw: int, sh: int, dx: int, dy: int, dw: int, dh: int, /) -> None: """Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. Underlying Processing method: PApplet.copy @@ -6903,21 +6921,21 @@ def copy(self, src: Py5Image, sx: int, sy: int, sw: int, ----- Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ pass - @_auto_convert_to_py5image + @_auto_convert_to_py5image(0) @_return_py5image def copy(self, *args): """Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. Underlying Processing method: PApplet.copy @@ -6965,13 +6983,13 @@ def copy(self, *args): ----- Copies a region of pixels from the display window to another area of the display - window and copies a region of pixels from an image used as the ``src_img`` + window and copies a region of pixels from an image used as the `src_img` parameter into the display window. If the source and destination regions aren't the same size, it will automatically resize the source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well. - This function ignores ``image_mode()``. + This function ignores `image_mode()`. """ return self._instance.copy(*args) @@ -7013,24 +7031,24 @@ def create_font(self, name: str, size: float, /) -> Py5Font: Dynamically converts a font to the format used by py5 from a .ttf or .otf file inside the Sketch's "data" folder or a font that's installed elsewhere on the computer. If you want to use a font installed on your computer, use the - ``Py5Font.list()`` method to first determine the names for the fonts recognized - by the computer and are compatible with this function. Not all fonts can be used + `Py5Font.list()` method to first determine the names for the fonts recognized by + the computer and are compatible with this function. Not all fonts can be used and some might work with one operating system and not others. When sharing a Sketch with other people or posting it on the web, you may need to include a .ttf or .otf version of your font in the data directory of the Sketch because other people might not have the font installed on their computer. Only fonts that can legally be distributed should be included with a Sketch. - The ``size`` parameter states the font size you want to generate. The ``smooth`` - parameter specifies if the font should be antialiased or not. The ``charset`` + The `size` parameter states the font size you want to generate. The `smooth` + parameter specifies if the font should be antialiased or not. The `charset` parameter is an array of chars that specifies the characters to generate. This function allows py5 to work with the font natively in the default renderer, so the letters are defined by vector geometry and are rendered quickly. In the - ``P2D`` and ``P3D`` renderers, the function sets the project to render the font - as a series of small textures. For instance, when using the default renderer, - the actual native version of the font will be employed by the Sketch, improving - drawing quality and performance. With the ``P2D`` and ``P3D`` renderers, the + `P2D` and `P3D` renderers, the function sets the project to render the font as a + series of small textures. For instance, when using the default renderer, the + actual native version of the font will be employed by the Sketch, improving + drawing quality and performance. With the `P2D` and `P3D` renderers, the bitmapped version will be used to improve speed and appearance, but the results are poor when exporting if the Sketch does not include the .otf or .ttf file, and the requested font is not available on the machine running the Sketch. @@ -7075,24 +7093,24 @@ def create_font(self, name: str, size: float, smooth: bool, /) -> Py5Font: Dynamically converts a font to the format used by py5 from a .ttf or .otf file inside the Sketch's "data" folder or a font that's installed elsewhere on the computer. If you want to use a font installed on your computer, use the - ``Py5Font.list()`` method to first determine the names for the fonts recognized - by the computer and are compatible with this function. Not all fonts can be used + `Py5Font.list()` method to first determine the names for the fonts recognized by + the computer and are compatible with this function. Not all fonts can be used and some might work with one operating system and not others. When sharing a Sketch with other people or posting it on the web, you may need to include a .ttf or .otf version of your font in the data directory of the Sketch because other people might not have the font installed on their computer. Only fonts that can legally be distributed should be included with a Sketch. - The ``size`` parameter states the font size you want to generate. The ``smooth`` - parameter specifies if the font should be antialiased or not. The ``charset`` + The `size` parameter states the font size you want to generate. The `smooth` + parameter specifies if the font should be antialiased or not. The `charset` parameter is an array of chars that specifies the characters to generate. This function allows py5 to work with the font natively in the default renderer, so the letters are defined by vector geometry and are rendered quickly. In the - ``P2D`` and ``P3D`` renderers, the function sets the project to render the font - as a series of small textures. For instance, when using the default renderer, - the actual native version of the font will be employed by the Sketch, improving - drawing quality and performance. With the ``P2D`` and ``P3D`` renderers, the + `P2D` and `P3D` renderers, the function sets the project to render the font as a + series of small textures. For instance, when using the default renderer, the + actual native version of the font will be employed by the Sketch, improving + drawing quality and performance. With the `P2D` and `P3D` renderers, the bitmapped version will be used to improve speed and appearance, but the results are poor when exporting if the Sketch does not include the .otf or .ttf file, and the requested font is not available on the machine running the Sketch. @@ -7138,24 +7156,24 @@ def create_font(self, name: str, size: float, smooth: bool, Dynamically converts a font to the format used by py5 from a .ttf or .otf file inside the Sketch's "data" folder or a font that's installed elsewhere on the computer. If you want to use a font installed on your computer, use the - ``Py5Font.list()`` method to first determine the names for the fonts recognized - by the computer and are compatible with this function. Not all fonts can be used + `Py5Font.list()` method to first determine the names for the fonts recognized by + the computer and are compatible with this function. Not all fonts can be used and some might work with one operating system and not others. When sharing a Sketch with other people or posting it on the web, you may need to include a .ttf or .otf version of your font in the data directory of the Sketch because other people might not have the font installed on their computer. Only fonts that can legally be distributed should be included with a Sketch. - The ``size`` parameter states the font size you want to generate. The ``smooth`` - parameter specifies if the font should be antialiased or not. The ``charset`` + The `size` parameter states the font size you want to generate. The `smooth` + parameter specifies if the font should be antialiased or not. The `charset` parameter is an array of chars that specifies the characters to generate. This function allows py5 to work with the font natively in the default renderer, so the letters are defined by vector geometry and are rendered quickly. In the - ``P2D`` and ``P3D`` renderers, the function sets the project to render the font - as a series of small textures. For instance, when using the default renderer, - the actual native version of the font will be employed by the Sketch, improving - drawing quality and performance. With the ``P2D`` and ``P3D`` renderers, the + `P2D` and `P3D` renderers, the function sets the project to render the font as a + series of small textures. For instance, when using the default renderer, the + actual native version of the font will be employed by the Sketch, improving + drawing quality and performance. With the `P2D` and `P3D` renderers, the bitmapped version will be used to improve speed and appearance, but the results are poor when exporting if the Sketch does not include the .otf or .ttf file, and the requested font is not available on the machine running the Sketch. @@ -7200,24 +7218,24 @@ def create_font(self, *args): Dynamically converts a font to the format used by py5 from a .ttf or .otf file inside the Sketch's "data" folder or a font that's installed elsewhere on the computer. If you want to use a font installed on your computer, use the - ``Py5Font.list()`` method to first determine the names for the fonts recognized - by the computer and are compatible with this function. Not all fonts can be used + `Py5Font.list()` method to first determine the names for the fonts recognized by + the computer and are compatible with this function. Not all fonts can be used and some might work with one operating system and not others. When sharing a Sketch with other people or posting it on the web, you may need to include a .ttf or .otf version of your font in the data directory of the Sketch because other people might not have the font installed on their computer. Only fonts that can legally be distributed should be included with a Sketch. - The ``size`` parameter states the font size you want to generate. The ``smooth`` - parameter specifies if the font should be antialiased or not. The ``charset`` + The `size` parameter states the font size you want to generate. The `smooth` + parameter specifies if the font should be antialiased or not. The `charset` parameter is an array of chars that specifies the characters to generate. This function allows py5 to work with the font natively in the default renderer, so the letters are defined by vector geometry and are rendered quickly. In the - ``P2D`` and ``P3D`` renderers, the function sets the project to render the font - as a series of small textures. For instance, when using the default renderer, - the actual native version of the font will be employed by the Sketch, improving - drawing quality and performance. With the ``P2D`` and ``P3D`` renderers, the + `P2D` and `P3D` renderers, the function sets the project to render the font as a + series of small textures. For instance, when using the default renderer, the + actual native version of the font will be employed by the Sketch, improving + drawing quality and performance. With the `P2D` and `P3D` renderers, the bitmapped version will be used to improve speed and appearance, but the results are poor when exporting if the Sketch does not include the .otf or .ttf file, and the requested font is not available on the machine running the Sketch. @@ -7226,7 +7244,7 @@ def create_font(self, *args): @overload def create_graphics(self, w: int, h: int, /) -> Py5Graphics: - """Creates and returns a new ``Py5Graphics`` object. + """Creates and returns a new `Py5Graphics` object. Underlying Processing method: PApplet.createGraphics @@ -7257,46 +7275,44 @@ def create_graphics(self, w: int, h: int, /) -> Py5Graphics: Notes ----- - Creates and returns a new ``Py5Graphics`` object. Use this class if you need to + Creates and returns a new `Py5Graphics` object. Use this class if you need to draw into an off-screen graphics buffer. The first two parameters define the width and height in pixels. The third, optional parameter specifies the - renderer. It can be defined as ``P2D``, ``P3D``, ``PDF``, or ``SVG``. If the - third parameter isn't used, the default renderer is set. The ``PDF`` and ``SVG`` - renderers require the filename parameter. - - It's important to consider the renderer used with ``create_graphics()`` in - relation to the main renderer specified in ``size()``. For example, it's only - possible to use ``P2D`` or ``P3D`` with ``create_graphics()`` when one of them - is defined in ``size()``. ``P2D`` and ``P3D`` use OpenGL for drawing, and when - using an OpenGL renderer it's necessary for the main drawing surface to be - OpenGL-based. If ``P2D`` or ``P3D`` are used as the renderer in ``size()``, then - any of the options can be used with ``create_graphics()``. If the default - renderer is used in ``size()``, then only the default, ``PDF``, or ``SVG`` can - be used with ``create_graphics()``. + renderer. It can be defined as `P2D`, `P3D`, `PDF`, or `SVG`. If the third + parameter isn't used, the default renderer is set. The `PDF` and `SVG` renderers + require the filename parameter. + + It's important to consider the renderer used with `create_graphics()` in + relation to the main renderer specified in `size()`. For example, it's only + possible to use `P2D` or `P3D` with `create_graphics()` when one of them is + defined in `size()`. `P2D` and `P3D` use OpenGL for drawing, and when using an + OpenGL renderer it's necessary for the main drawing surface to be OpenGL-based. + If `P2D` or `P3D` are used as the renderer in `size()`, then any of the options + can be used with `create_graphics()`. If the default renderer is used in + `size()`, then only the default, `PDF`, or `SVG` can be used with + `create_graphics()`. It's important to run all drawing functions between the - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. As the exception to - this rule, ``smooth()`` should be run on the Py5Graphics object before - ``Py5Graphics.begin_draw()``. See the reference for ``smooth()`` for more - detail. + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. As the exception to + this rule, `smooth()` should be run on the Py5Graphics object before + `Py5Graphics.begin_draw()`. See the reference for `smooth()` for more detail. - The ``create_graphics()`` function should almost never be used inside ``draw()`` + The `create_graphics()` function should almost never be used inside `draw()` because of the memory and time needed to set up the graphics. One-time or - occasional use during ``draw()`` might be acceptable, but code that calls - ``create_graphics()`` at 60 frames per second might run out of memory or freeze + occasional use during `draw()` might be acceptable, but code that calls + `create_graphics()` at 60 frames per second might run out of memory or freeze your Sketch. Unlike the main drawing surface which is completely opaque, surfaces created - with ``create_graphics()`` can have transparency. This makes it possible to draw - into a graphics and maintain the alpha channel. By using ``save()`` to write a - ``PNG`` or ``TGA`` file, the transparency of the graphics object will be - honored. + with `create_graphics()` can have transparency. This makes it possible to draw + into a graphics and maintain the alpha channel. By using `save()` to write a + `PNG` or `TGA` file, the transparency of the graphics object will be honored. """ pass @overload def create_graphics(self, w: int, h: int, renderer: str, /) -> Py5Graphics: - """Creates and returns a new ``Py5Graphics`` object. + """Creates and returns a new `Py5Graphics` object. Underlying Processing method: PApplet.createGraphics @@ -7327,47 +7343,45 @@ def create_graphics(self, w: int, h: int, renderer: str, /) -> Py5Graphics: Notes ----- - Creates and returns a new ``Py5Graphics`` object. Use this class if you need to + Creates and returns a new `Py5Graphics` object. Use this class if you need to draw into an off-screen graphics buffer. The first two parameters define the width and height in pixels. The third, optional parameter specifies the - renderer. It can be defined as ``P2D``, ``P3D``, ``PDF``, or ``SVG``. If the - third parameter isn't used, the default renderer is set. The ``PDF`` and ``SVG`` - renderers require the filename parameter. - - It's important to consider the renderer used with ``create_graphics()`` in - relation to the main renderer specified in ``size()``. For example, it's only - possible to use ``P2D`` or ``P3D`` with ``create_graphics()`` when one of them - is defined in ``size()``. ``P2D`` and ``P3D`` use OpenGL for drawing, and when - using an OpenGL renderer it's necessary for the main drawing surface to be - OpenGL-based. If ``P2D`` or ``P3D`` are used as the renderer in ``size()``, then - any of the options can be used with ``create_graphics()``. If the default - renderer is used in ``size()``, then only the default, ``PDF``, or ``SVG`` can - be used with ``create_graphics()``. + renderer. It can be defined as `P2D`, `P3D`, `PDF`, or `SVG`. If the third + parameter isn't used, the default renderer is set. The `PDF` and `SVG` renderers + require the filename parameter. + + It's important to consider the renderer used with `create_graphics()` in + relation to the main renderer specified in `size()`. For example, it's only + possible to use `P2D` or `P3D` with `create_graphics()` when one of them is + defined in `size()`. `P2D` and `P3D` use OpenGL for drawing, and when using an + OpenGL renderer it's necessary for the main drawing surface to be OpenGL-based. + If `P2D` or `P3D` are used as the renderer in `size()`, then any of the options + can be used with `create_graphics()`. If the default renderer is used in + `size()`, then only the default, `PDF`, or `SVG` can be used with + `create_graphics()`. It's important to run all drawing functions between the - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. As the exception to - this rule, ``smooth()`` should be run on the Py5Graphics object before - ``Py5Graphics.begin_draw()``. See the reference for ``smooth()`` for more - detail. + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. As the exception to + this rule, `smooth()` should be run on the Py5Graphics object before + `Py5Graphics.begin_draw()`. See the reference for `smooth()` for more detail. - The ``create_graphics()`` function should almost never be used inside ``draw()`` + The `create_graphics()` function should almost never be used inside `draw()` because of the memory and time needed to set up the graphics. One-time or - occasional use during ``draw()`` might be acceptable, but code that calls - ``create_graphics()`` at 60 frames per second might run out of memory or freeze + occasional use during `draw()` might be acceptable, but code that calls + `create_graphics()` at 60 frames per second might run out of memory or freeze your Sketch. Unlike the main drawing surface which is completely opaque, surfaces created - with ``create_graphics()`` can have transparency. This makes it possible to draw - into a graphics and maintain the alpha channel. By using ``save()`` to write a - ``PNG`` or ``TGA`` file, the transparency of the graphics object will be - honored. + with `create_graphics()` can have transparency. This makes it possible to draw + into a graphics and maintain the alpha channel. By using `save()` to write a + `PNG` or `TGA` file, the transparency of the graphics object will be honored. """ pass @overload def create_graphics(self, w: int, h: int, renderer: str, path: str, /) -> Py5Graphics: - """Creates and returns a new ``Py5Graphics`` object. + """Creates and returns a new `Py5Graphics` object. Underlying Processing method: PApplet.createGraphics @@ -7398,46 +7412,44 @@ def create_graphics(self, w: int, h: int, renderer: str, Notes ----- - Creates and returns a new ``Py5Graphics`` object. Use this class if you need to + Creates and returns a new `Py5Graphics` object. Use this class if you need to draw into an off-screen graphics buffer. The first two parameters define the width and height in pixels. The third, optional parameter specifies the - renderer. It can be defined as ``P2D``, ``P3D``, ``PDF``, or ``SVG``. If the - third parameter isn't used, the default renderer is set. The ``PDF`` and ``SVG`` - renderers require the filename parameter. - - It's important to consider the renderer used with ``create_graphics()`` in - relation to the main renderer specified in ``size()``. For example, it's only - possible to use ``P2D`` or ``P3D`` with ``create_graphics()`` when one of them - is defined in ``size()``. ``P2D`` and ``P3D`` use OpenGL for drawing, and when - using an OpenGL renderer it's necessary for the main drawing surface to be - OpenGL-based. If ``P2D`` or ``P3D`` are used as the renderer in ``size()``, then - any of the options can be used with ``create_graphics()``. If the default - renderer is used in ``size()``, then only the default, ``PDF``, or ``SVG`` can - be used with ``create_graphics()``. + renderer. It can be defined as `P2D`, `P3D`, `PDF`, or `SVG`. If the third + parameter isn't used, the default renderer is set. The `PDF` and `SVG` renderers + require the filename parameter. + + It's important to consider the renderer used with `create_graphics()` in + relation to the main renderer specified in `size()`. For example, it's only + possible to use `P2D` or `P3D` with `create_graphics()` when one of them is + defined in `size()`. `P2D` and `P3D` use OpenGL for drawing, and when using an + OpenGL renderer it's necessary for the main drawing surface to be OpenGL-based. + If `P2D` or `P3D` are used as the renderer in `size()`, then any of the options + can be used with `create_graphics()`. If the default renderer is used in + `size()`, then only the default, `PDF`, or `SVG` can be used with + `create_graphics()`. It's important to run all drawing functions between the - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. As the exception to - this rule, ``smooth()`` should be run on the Py5Graphics object before - ``Py5Graphics.begin_draw()``. See the reference for ``smooth()`` for more - detail. + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. As the exception to + this rule, `smooth()` should be run on the Py5Graphics object before + `Py5Graphics.begin_draw()`. See the reference for `smooth()` for more detail. - The ``create_graphics()`` function should almost never be used inside ``draw()`` + The `create_graphics()` function should almost never be used inside `draw()` because of the memory and time needed to set up the graphics. One-time or - occasional use during ``draw()`` might be acceptable, but code that calls - ``create_graphics()`` at 60 frames per second might run out of memory or freeze + occasional use during `draw()` might be acceptable, but code that calls + `create_graphics()` at 60 frames per second might run out of memory or freeze your Sketch. Unlike the main drawing surface which is completely opaque, surfaces created - with ``create_graphics()`` can have transparency. This makes it possible to draw - into a graphics and maintain the alpha channel. By using ``save()`` to write a - ``PNG`` or ``TGA`` file, the transparency of the graphics object will be - honored. + with `create_graphics()` can have transparency. This makes it possible to draw + into a graphics and maintain the alpha channel. By using `save()` to write a + `PNG` or `TGA` file, the transparency of the graphics object will be honored. """ pass @_return_py5graphics def create_graphics(self, *args): - """Creates and returns a new ``Py5Graphics`` object. + """Creates and returns a new `Py5Graphics` object. Underlying Processing method: PApplet.createGraphics @@ -7468,40 +7480,38 @@ def create_graphics(self, *args): Notes ----- - Creates and returns a new ``Py5Graphics`` object. Use this class if you need to + Creates and returns a new `Py5Graphics` object. Use this class if you need to draw into an off-screen graphics buffer. The first two parameters define the width and height in pixels. The third, optional parameter specifies the - renderer. It can be defined as ``P2D``, ``P3D``, ``PDF``, or ``SVG``. If the - third parameter isn't used, the default renderer is set. The ``PDF`` and ``SVG`` - renderers require the filename parameter. - - It's important to consider the renderer used with ``create_graphics()`` in - relation to the main renderer specified in ``size()``. For example, it's only - possible to use ``P2D`` or ``P3D`` with ``create_graphics()`` when one of them - is defined in ``size()``. ``P2D`` and ``P3D`` use OpenGL for drawing, and when - using an OpenGL renderer it's necessary for the main drawing surface to be - OpenGL-based. If ``P2D`` or ``P3D`` are used as the renderer in ``size()``, then - any of the options can be used with ``create_graphics()``. If the default - renderer is used in ``size()``, then only the default, ``PDF``, or ``SVG`` can - be used with ``create_graphics()``. + renderer. It can be defined as `P2D`, `P3D`, `PDF`, or `SVG`. If the third + parameter isn't used, the default renderer is set. The `PDF` and `SVG` renderers + require the filename parameter. + + It's important to consider the renderer used with `create_graphics()` in + relation to the main renderer specified in `size()`. For example, it's only + possible to use `P2D` or `P3D` with `create_graphics()` when one of them is + defined in `size()`. `P2D` and `P3D` use OpenGL for drawing, and when using an + OpenGL renderer it's necessary for the main drawing surface to be OpenGL-based. + If `P2D` or `P3D` are used as the renderer in `size()`, then any of the options + can be used with `create_graphics()`. If the default renderer is used in + `size()`, then only the default, `PDF`, or `SVG` can be used with + `create_graphics()`. It's important to run all drawing functions between the - ``Py5Graphics.begin_draw()`` and ``Py5Graphics.end_draw()``. As the exception to - this rule, ``smooth()`` should be run on the Py5Graphics object before - ``Py5Graphics.begin_draw()``. See the reference for ``smooth()`` for more - detail. + `Py5Graphics.begin_draw()` and `Py5Graphics.end_draw()`. As the exception to + this rule, `smooth()` should be run on the Py5Graphics object before + `Py5Graphics.begin_draw()`. See the reference for `smooth()` for more detail. - The ``create_graphics()`` function should almost never be used inside ``draw()`` + The `create_graphics()` function should almost never be used inside `draw()` because of the memory and time needed to set up the graphics. One-time or - occasional use during ``draw()`` might be acceptable, but code that calls - ``create_graphics()`` at 60 frames per second might run out of memory or freeze + occasional use during `draw()` might be acceptable, but code that calls + `create_graphics()` at 60 frames per second might run out of memory or freeze your Sketch. Unlike the main drawing surface which is completely opaque, surfaces created - with ``create_graphics()`` can have transparency. This makes it possible to draw - into a graphics and maintain the alpha channel. By using ``save()`` to write a - ``PNG`` or ``TGA`` file, the transparency of the graphics object will be - honored. + with `create_graphics()` can have transparency. This makes it possible to draw + into a graphics and maintain the alpha channel. By using `save()` to write a + `PNG` or `TGA` file, the transparency of the graphics object will be honored. """ return self._instance.createGraphics(*args) @@ -7527,21 +7537,21 @@ def create_image(self, w: int, h: int, format: int, /) -> Py5Image: ----- Creates a new Py5Image (the datatype for storing images). This provides a fresh - buffer of pixels to play with. Set the size of the buffer with the ``w`` and - ``h`` parameters. The ``format`` parameter defines how the pixels are stored. - See the ``Py5Image`` reference for more information. + buffer of pixels to play with. Set the size of the buffer with the `w` and `h` + parameters. The `format` parameter defines how the pixels are stored. See the + `Py5Image` reference for more information. Be sure to include all three parameters, specifying only the width and height (but no format) will produce a strange error. - Advanced users please note that ``create_image()`` should be used instead of the - syntax ``Py5Image()``. + Advanced users please note that `create_image()` should be used instead of the + syntax `Py5Image()`. """ return self._instance.createImage(w, h, format) @overload def create_shape(self) -> Py5Shape: - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PApplet.createShape @@ -7569,36 +7579,35 @@ def create_shape(self) -> Py5Shape: Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``shape()`` function. The basic way to use the + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `shape()` function. The basic way to use the function defines new primitive shapes. One of the following parameters are used - as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, ``TRIANGLE``, - ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for each of these - different shapes are the same as their corresponding functions: ``ellipse()``, - ``rect()``, ``arc()``, ``triangle()``, ``sphere()``, ``box()``, ``quad()``, and - ``line()``. The first example clarifies how this works. - - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``begin_shape()`` and ``end_shape()`` - methods. See the second example for specifics, and the reference for - ``begin_shape()`` for all of its options. - - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. See the fourth example to see how it - works. - - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, `BOX`, + `QUAD`, or `LINE`. The parameters for each of these different shapes are the + same as their corresponding functions: `ellipse()`, `rect()`, `arc()`, + `triangle()`, `sphere()`, `box()`, `quad()`, and `line()`. The first example + clarifies how this works. + + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `begin_shape()` and `end_shape()` methods. See + the second example for specifics, and the reference for `begin_shape()` for all + of its options. + + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. See the fourth example to see how it works. + + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. """ pass @overload def create_shape(self, type: int, /) -> Py5Shape: - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PApplet.createShape @@ -7626,36 +7635,35 @@ def create_shape(self, type: int, /) -> Py5Shape: Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``shape()`` function. The basic way to use the + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `shape()` function. The basic way to use the function defines new primitive shapes. One of the following parameters are used - as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, ``TRIANGLE``, - ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for each of these - different shapes are the same as their corresponding functions: ``ellipse()``, - ``rect()``, ``arc()``, ``triangle()``, ``sphere()``, ``box()``, ``quad()``, and - ``line()``. The first example clarifies how this works. - - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``begin_shape()`` and ``end_shape()`` - methods. See the second example for specifics, and the reference for - ``begin_shape()`` for all of its options. - - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. See the fourth example to see how it - works. - - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, `BOX`, + `QUAD`, or `LINE`. The parameters for each of these different shapes are the + same as their corresponding functions: `ellipse()`, `rect()`, `arc()`, + `triangle()`, `sphere()`, `box()`, `quad()`, and `line()`. The first example + clarifies how this works. + + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `begin_shape()` and `end_shape()` methods. See + the second example for specifics, and the reference for `begin_shape()` for all + of its options. + + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. See the fourth example to see how it works. + + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. """ pass @overload def create_shape(self, kind: int, /, *p: float) -> Py5Shape: - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PApplet.createShape @@ -7683,36 +7691,35 @@ def create_shape(self, kind: int, /, *p: float) -> Py5Shape: Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``shape()`` function. The basic way to use the + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `shape()` function. The basic way to use the function defines new primitive shapes. One of the following parameters are used - as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, ``TRIANGLE``, - ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for each of these - different shapes are the same as their corresponding functions: ``ellipse()``, - ``rect()``, ``arc()``, ``triangle()``, ``sphere()``, ``box()``, ``quad()``, and - ``line()``. The first example clarifies how this works. - - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``begin_shape()`` and ``end_shape()`` - methods. See the second example for specifics, and the reference for - ``begin_shape()`` for all of its options. - - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. See the fourth example to see how it - works. - - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, `BOX`, + `QUAD`, or `LINE`. The parameters for each of these different shapes are the + same as their corresponding functions: `ellipse()`, `rect()`, `arc()`, + `triangle()`, `sphere()`, `box()`, `quad()`, and `line()`. The first example + clarifies how this works. + + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `begin_shape()` and `end_shape()` methods. See + the second example for specifics, and the reference for `begin_shape()` for all + of its options. + + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. See the fourth example to see how it works. + + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. """ pass @_return_py5shape def create_shape(self, *args): - """The ``create_shape()`` function is used to define a new shape. + """The `create_shape()` function is used to define a new shape. Underlying Processing method: PApplet.createShape @@ -7740,30 +7747,29 @@ def create_shape(self, *args): Notes ----- - The ``create_shape()`` function is used to define a new shape. Once created, - this shape can be drawn with the ``shape()`` function. The basic way to use the + The `create_shape()` function is used to define a new shape. Once created, this + shape can be drawn with the `shape()` function. The basic way to use the function defines new primitive shapes. One of the following parameters are used - as the first parameter: ``ELLIPSE``, ``RECT``, ``ARC``, ``TRIANGLE``, - ``SPHERE``, ``BOX``, ``QUAD``, or ``LINE``. The parameters for each of these - different shapes are the same as their corresponding functions: ``ellipse()``, - ``rect()``, ``arc()``, ``triangle()``, ``sphere()``, ``box()``, ``quad()``, and - ``line()``. The first example clarifies how this works. - - Custom, unique shapes can be made by using ``create_shape()`` without a - parameter. After the shape is started, the drawing attributes and geometry can - be set directly to the shape within the ``begin_shape()`` and ``end_shape()`` - methods. See the second example for specifics, and the reference for - ``begin_shape()`` for all of its options. - - The ``create_shape()`` function can also be used to make a complex shape made - of other shapes. This is called a "group" and it's created by using the - parameter ``GROUP`` as the first parameter. See the fourth example to see how it - works. - - After using ``create_shape()``, stroke and fill color can be set by calling - methods like ``Py5Shape.set_fill()`` and ``Py5Shape.set_stroke()``, as seen in - the examples. The complete list of methods and fields for the ``Py5Shape`` class - are in the py5 documentation. + as the first parameter: `ELLIPSE`, `RECT`, `ARC`, `TRIANGLE`, `SPHERE`, `BOX`, + `QUAD`, or `LINE`. The parameters for each of these different shapes are the + same as their corresponding functions: `ellipse()`, `rect()`, `arc()`, + `triangle()`, `sphere()`, `box()`, `quad()`, and `line()`. The first example + clarifies how this works. + + Custom, unique shapes can be made by using `create_shape()` without a parameter. + After the shape is started, the drawing attributes and geometry can be set + directly to the shape within the `begin_shape()` and `end_shape()` methods. See + the second example for specifics, and the reference for `begin_shape()` for all + of its options. + + The `create_shape()` function can also be used to make a complex shape made of + other shapes. This is called a "group" and it's created by using the parameter + `GROUP` as the first parameter. See the fourth example to see how it works. + + After using `create_shape()`, stroke and fill color can be set by calling + methods like `Py5Shape.set_fill()` and `Py5Shape.set_stroke()`, as seen in the + examples. The complete list of methods and fields for the `Py5Shape` class are + in the py5 documentation. """ return self._instance.createShape(*args) @@ -7804,15 +7810,15 @@ def cursor(self) -> None: Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended - size is 16x16 or 32x32 pixels. The values for parameters ``x`` and ``y`` must be + size is 16x16 or 32x32 pixels. The values for parameters `x` and `y` must be less than the dimensions of the image. Setting or hiding the cursor does not generally work with "Present" mode (when running full-screen). - With the ``P2D`` and ``P3D`` renderers, a generic set of cursors are used - because the OpenGL renderer doesn't have access to the default cursor images for - each platform (Processing Issue 3791). + With the `P2D` and `P3D` renderers, a generic set of cursors are used because + the OpenGL renderer doesn't have access to the default cursor images for each + platform (Processing Issue 3791). """ pass @@ -7853,15 +7859,15 @@ def cursor(self, kind: int, /) -> None: Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended - size is 16x16 or 32x32 pixels. The values for parameters ``x`` and ``y`` must be + size is 16x16 or 32x32 pixels. The values for parameters `x` and `y` must be less than the dimensions of the image. Setting or hiding the cursor does not generally work with "Present" mode (when running full-screen). - With the ``P2D`` and ``P3D`` renderers, a generic set of cursors are used - because the OpenGL renderer doesn't have access to the default cursor images for - each platform (Processing Issue 3791). + With the `P2D` and `P3D` renderers, a generic set of cursors are used because + the OpenGL renderer doesn't have access to the default cursor images for each + platform (Processing Issue 3791). """ pass @@ -7902,15 +7908,15 @@ def cursor(self, img: Py5Image, /) -> None: Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended - size is 16x16 or 32x32 pixels. The values for parameters ``x`` and ``y`` must be + size is 16x16 or 32x32 pixels. The values for parameters `x` and `y` must be less than the dimensions of the image. Setting or hiding the cursor does not generally work with "Present" mode (when running full-screen). - With the ``P2D`` and ``P3D`` renderers, a generic set of cursors are used - because the OpenGL renderer doesn't have access to the default cursor images for - each platform (Processing Issue 3791). + With the `P2D` and `P3D` renderers, a generic set of cursors are used because + the OpenGL renderer doesn't have access to the default cursor images for each + platform (Processing Issue 3791). """ pass @@ -7951,19 +7957,19 @@ def cursor(self, img: Py5Image, x: int, y: int, /) -> None: Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended - size is 16x16 or 32x32 pixels. The values for parameters ``x`` and ``y`` must be + size is 16x16 or 32x32 pixels. The values for parameters `x` and `y` must be less than the dimensions of the image. Setting or hiding the cursor does not generally work with "Present" mode (when running full-screen). - With the ``P2D`` and ``P3D`` renderers, a generic set of cursors are used - because the OpenGL renderer doesn't have access to the default cursor images for - each platform (Processing Issue 3791). + With the `P2D` and `P3D` renderers, a generic set of cursors are used because + the OpenGL renderer doesn't have access to the default cursor images for each + platform (Processing Issue 3791). """ pass - @_auto_convert_to_py5image + @_auto_convert_to_py5image(0) def cursor(self, *args): """Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. @@ -8000,15 +8006,15 @@ def cursor(self, *args): Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended - size is 16x16 or 32x32 pixels. The values for parameters ``x`` and ``y`` must be + size is 16x16 or 32x32 pixels. The values for parameters `x` and `y` must be less than the dimensions of the image. Setting or hiding the cursor does not generally work with "Present" mode (when running full-screen). - With the ``P2D`` and ``P3D`` renderers, a generic set of cursors are used - because the OpenGL renderer doesn't have access to the default cursor images for - each platform (Processing Issue 3791). + With the `P2D` and `P3D` renderers, a generic set of cursors are used because + the OpenGL renderer doesn't have access to the default cursor images for each + platform (Processing Issue 3791). """ return self._instance.cursor(*args) @@ -8072,11 +8078,11 @@ def curve(self, x1: float, y1: float, x2: float, y2: float, Draws a curved line on the screen. The first and second parameters specify the beginning control point and the last two parameters specify the ending control point. The middle parameters specify the start and stop of the curve. Longer - curves can be created by putting a series of ``curve()`` functions together or - using ``curve_vertex()``. An additional function called ``curve_tightness()`` - provides control for the visual quality of the curve. The ``curve()`` function - is an implementation of Catmull-Rom splines. Using the 3D version requires - rendering with ``P3D``. + curves can be created by putting a series of `curve()` functions together or + using `curve_vertex()`. An additional function called `curve_tightness()` + provides control for the visual quality of the curve. The `curve()` function is + an implementation of Catmull-Rom splines. Using the 3D version requires + rendering with `P3D`. """ pass @@ -8140,11 +8146,11 @@ def curve(self, x1: float, y1: float, z1: float, x2: float, y2: float, z2: float Draws a curved line on the screen. The first and second parameters specify the beginning control point and the last two parameters specify the ending control point. The middle parameters specify the start and stop of the curve. Longer - curves can be created by putting a series of ``curve()`` functions together or - using ``curve_vertex()``. An additional function called ``curve_tightness()`` - provides control for the visual quality of the curve. The ``curve()`` function - is an implementation of Catmull-Rom splines. Using the 3D version requires - rendering with ``P3D``. + curves can be created by putting a series of `curve()` functions together or + using `curve_vertex()`. An additional function called `curve_tightness()` + provides control for the visual quality of the curve. The `curve()` function is + an implementation of Catmull-Rom splines. Using the 3D version requires + rendering with `P3D`. """ pass @@ -8206,11 +8212,11 @@ def curve(self, *args): Draws a curved line on the screen. The first and second parameters specify the beginning control point and the last two parameters specify the ending control point. The middle parameters specify the start and stop of the curve. Longer - curves can be created by putting a series of ``curve()`` functions together or - using ``curve_vertex()``. An additional function called ``curve_tightness()`` - provides control for the visual quality of the curve. The ``curve()`` function - is an implementation of Catmull-Rom splines. Using the 3D version requires - rendering with ``P3D``. + curves can be created by putting a series of `curve()` functions together or + using `curve_vertex()`. An additional function called `curve_tightness()` + provides control for the visual quality of the curve. The `curve()` function is + an implementation of Catmull-Rom splines. Using the 3D version requires + rendering with `P3D`. """ return self._instance.curve(*args) @@ -8229,14 +8235,14 @@ def curve_detail(self, detail: int, /) -> None: ----- Sets the resolution at which curves display. The default value is 20. This - function is only useful when using the ``P3D`` renderer as the default ``P2D`` + function is only useful when using the `P3D` renderer as the default `P2D` renderer does not use this information. """ return self._instance.curveDetail(detail) def curve_point(self, a: float, b: float, c: float, d: float, t: float, /) -> float: - """Evaluates the curve at point ``t`` for points ``a``, ``b``, ``c``, ``d``. + """Evaluates the curve at point `t` for points `a`, `b`, `c`, `d`. Underlying Processing method: PApplet.curvePoint @@ -8261,12 +8267,11 @@ def curve_point(self, a: float, b: float, c: float, Notes ----- - Evaluates the curve at point ``t`` for points ``a``, ``b``, ``c``, ``d``. The - parameter ``t`` may range from 0 (the start of the curve) and 1 (the end of the - curve). ``a`` and ``d`` are the control points, and ``b`` and ``c`` are points - on the curve. As seen in the example, this can be used once with the ``x`` - coordinates and a second time with the ``y`` coordinates to get the location of - a curve at ``t``. + Evaluates the curve at point `t` for points `a`, `b`, `c`, `d`. The parameter + `t` may range from 0 (the start of the curve) and 1 (the end of the curve). `a` + and `d` are the control points, and `b` and `c` are points on the curve. As seen + in the example, this can be used once with the `x` coordinates and a second time + with the `y` coordinates to get the location of a curve at `t`. """ return self._instance.curvePoint(a, b, c, d, t) @@ -8303,7 +8308,7 @@ def curve_tangent(self, a: float, b: float, c: float, return self._instance.curveTangent(a, b, c, d, t) def curve_tightness(self, tightness: float, /) -> None: - """Modifies the quality of forms created with ``curve()`` and ``curve_vertex()``. + """Modifies the quality of forms created with `curve()` and `curve_vertex()`. Underlying Processing method: PApplet.curveTightness @@ -8316,13 +8321,13 @@ def curve_tightness(self, tightness: float, /) -> None: Notes ----- - Modifies the quality of forms created with ``curve()`` and ``curve_vertex()``. - The parameter ``tightness`` determines how the curve fits to the vertex points. - The value 0.0 is the default value for ``tightness`` (this value defines the - curves to be Catmull-Rom splines) and the value 1.0 connects all the points with - straight lines. Values within the range -5.0 and 5.0 will deform the curves but - will leave them recognizable and as values increase in magnitude, they will - continue to deform. + Modifies the quality of forms created with `curve()` and `curve_vertex()`. The + parameter `tightness` determines how the curve fits to the vertex points. The + value 0.0 is the default value for `tightness` (this value defines the curves to + be Catmull-Rom splines) and the value 1.0 connects all the points with straight + lines. Values within the range -5.0 and 5.0 will deform the curves but will + leave them recognizable and as values increase in magnitude, they will continue + to deform. """ return self._instance.curveTightness(tightness) @@ -8356,14 +8361,14 @@ def curve_vertex(self, x: float, y: float, /) -> None: ----- Specifies vertex coordinates for curves. This method may only be used between - ``begin_shape()`` and ``end_shape()`` and only when there is no ``MODE`` - parameter specified to ``begin_shape()``. The first and last points in a series - of ``curve_vertex()`` lines will be used to guide the beginning and end of the - curve. A minimum of four points is required to draw a tiny curve between the - second and third points. Adding a fifth point with ``curve_vertex()`` will draw - the curve between the second, third, and fourth points. The ``curve_vertex()`` - method is an implementation of Catmull-Rom splines. Using the 3D version - requires rendering with ``P3D``. + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. The first and last points in a series of + `curve_vertex()` lines will be used to guide the beginning and end of the curve. + A minimum of four points is required to draw a tiny curve between the second and + third points. Adding a fifth point with `curve_vertex()` will draw the curve + between the second, third, and fourth points. The `curve_vertex()` method is an + implementation of Catmull-Rom splines. Using the 3D version requires rendering + with `P3D`. """ pass @@ -8397,14 +8402,14 @@ def curve_vertex(self, x: float, y: float, z: float, /) -> None: ----- Specifies vertex coordinates for curves. This method may only be used between - ``begin_shape()`` and ``end_shape()`` and only when there is no ``MODE`` - parameter specified to ``begin_shape()``. The first and last points in a series - of ``curve_vertex()`` lines will be used to guide the beginning and end of the - curve. A minimum of four points is required to draw a tiny curve between the - second and third points. Adding a fifth point with ``curve_vertex()`` will draw - the curve between the second, third, and fourth points. The ``curve_vertex()`` - method is an implementation of Catmull-Rom splines. Using the 3D version - requires rendering with ``P3D``. + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. The first and last points in a series of + `curve_vertex()` lines will be used to guide the beginning and end of the curve. + A minimum of four points is required to draw a tiny curve between the second and + third points. Adding a fifth point with `curve_vertex()` will draw the curve + between the second, third, and fourth points. The `curve_vertex()` method is an + implementation of Catmull-Rom splines. Using the 3D version requires rendering + with `P3D`. """ pass @@ -8437,17 +8442,18 @@ def curve_vertex(self, *args): ----- Specifies vertex coordinates for curves. This method may only be used between - ``begin_shape()`` and ``end_shape()`` and only when there is no ``MODE`` - parameter specified to ``begin_shape()``. The first and last points in a series - of ``curve_vertex()`` lines will be used to guide the beginning and end of the - curve. A minimum of four points is required to draw a tiny curve between the - second and third points. Adding a fifth point with ``curve_vertex()`` will draw - the curve between the second, third, and fourth points. The ``curve_vertex()`` - method is an implementation of Catmull-Rom splines. Using the 3D version - requires rendering with ``P3D``. + `begin_shape()` and `end_shape()` and only when there is no `MODE` parameter + specified to `begin_shape()`. The first and last points in a series of + `curve_vertex()` lines will be used to guide the beginning and end of the curve. + A minimum of four points is required to draw a tiny curve between the second and + third points. Adding a fifth point with `curve_vertex()` will draw the curve + between the second, third, and fourth points. The `curve_vertex()` method is an + implementation of Catmull-Rom splines. Using the 3D version requires rendering + with `P3D`. """ return self._instance.curveVertex(*args) + @_generator_to_list def curve_vertices(self, coordinates: npt.NDArray[np.floating], /) -> None: """Create a collection of curve vertices. @@ -8463,13 +8469,12 @@ def curve_vertices(self, coordinates: npt.NDArray[np.floating], /) -> None: ----- Create a collection of curve vertices. The purpose of this method is to provide - an alternative to repeatedly calling ``curve_vertex()`` in a loop. For a large - number of curve vertices, the performance of ``curve_vertices()`` will be much + an alternative to repeatedly calling `curve_vertex()` in a loop. For a large + number of curve vertices, the performance of `curve_vertices()` will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each - curve vertex. There should be two or three columns for 2D or 3D points, - respectively. + The `coordinates` parameter should be a numpy array with one row for each curve + vertex. There should be two or three columns for 2D or 3D points, respectively. """ return self._instance.curveVertices(coordinates) @@ -8482,7 +8487,7 @@ def day(cls) -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``day()`` function returns + Py5 communicates with the clock on your computer. The `day()` function returns the current day as a value from 1 - 31. """ return cls._cls.day() @@ -8520,13 +8525,13 @@ def directional_light(self, v1: float, v2: float, v3: float, Adds a directional light. Directional light comes from one direction: it is stronger when hitting a surface squarely, and weaker if it hits at a gentle angle. After hitting a surface, directional light scatters in all directions. - Lights need to be included in the ``draw()`` to remain persistent in a looping - program. Placing them in the ``setup()`` of a looping program will cause them to - only have an effect the first time through the loop. The ``v1``, ``v2``, and - ``v3`` parameters are interpreted as either ``RGB`` or ``HSB`` values, depending - on the current color mode. The ``nx``, ``ny``, and ``nz`` parameters specify the - direction the light is facing. For example, setting ``ny`` to -1 will cause the - geometry to be lit from below (since the light would be facing directly upward). + Lights need to be included in the `draw()` to remain persistent in a looping + program. Placing them in the `setup()` of a looping program will cause them to + only have an effect the first time through the loop. The `v1`, `v2`, and `v3` + parameters are interpreted as either `RGB` or `HSB` values, depending on the + current color mode. The `nx`, `ny`, and `nz` parameters specify the direction + the light is facing. For example, setting `ny` to -1 will cause the geometry to + be lit from below (since the light would be facing directly upward). """ return self._instance.directionalLight(v1, v2, v3, nx, ny, nz) @@ -8651,13 +8656,13 @@ def ellipse(self, a: float, b: float, c: float, d: float, /) -> None: Draws an ellipse (oval) to the screen. An ellipse with equal width and height is a circle. By default, the first two parameters set the location, and the third and fourth parameters set the shape's width and height. The origin may be - changed with the ``ellipse_mode()`` function. + changed with the `ellipse_mode()` function. """ return self._instance.ellipse(a, b, c, d) def ellipse_mode(self, mode: int, /) -> None: """Modifies the location from which ellipses are drawn by changing the way in which - parameters given to ``ellipse()`` are intepreted. + parameters given to `ellipse()` are intepreted. Underlying Processing method: PApplet.ellipseMode @@ -8671,22 +8676,22 @@ def ellipse_mode(self, mode: int, /) -> None: ----- Modifies the location from which ellipses are drawn by changing the way in which - parameters given to ``ellipse()`` are intepreted. + parameters given to `ellipse()` are intepreted. - The default mode is ``ellipse_mode(CENTER)``, which interprets the first two - parameters of ``ellipse()`` as the shape's center point, while the third and + The default mode is `ellipse_mode(CENTER)`, which interprets the first two + parameters of `ellipse()` as the shape's center point, while the third and fourth parameters are its width and height. - ``ellipse_mode(RADIUS)`` also uses the first two parameters of ``ellipse()`` as - the shape's center point, but uses the third and fourth parameters to specify - half of the shapes's width and height. + `ellipse_mode(RADIUS)` also uses the first two parameters of `ellipse()` as the + shape's center point, but uses the third and fourth parameters to specify half + of the shapes's width and height. - ``ellipse_mode(CORNER)`` interprets the first two parameters of ``ellipse()`` as - the upper-left corner of the shape, while the third and fourth parameters are - its width and height. + `ellipse_mode(CORNER)` interprets the first two parameters of `ellipse()` as the + upper-left corner of the shape, while the third and fourth parameters are its + width and height. - ``ellipse_mode(CORNERS)`` interprets the first two parameters of ``ellipse()`` - as the location of one corner of the ellipse's bounding box, and the third and + `ellipse_mode(CORNERS)` interprets the first two parameters of `ellipse()` as + the location of one corner of the ellipse's bounding box, and the third and fourth parameters as the location of the opposite corner. The parameter must be written in ALL CAPS because Python is a case-sensitive @@ -8732,8 +8737,8 @@ def emissive(self, gray: float, /) -> None: ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``ambient()``, ``specular()``, and - ``shininess()`` to set the material properties of shapes. + screen. Use in combination with `ambient()`, `specular()`, and `shininess()` to + set the material properties of shapes. """ pass @@ -8775,8 +8780,8 @@ def emissive(self, v1: float, v2: float, v3: float, /) -> None: ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``ambient()``, ``specular()``, and - ``shininess()`` to set the material properties of shapes. + screen. Use in combination with `ambient()`, `specular()`, and `shininess()` to + set the material properties of shapes. """ pass @@ -8818,8 +8823,8 @@ def emissive(self, rgb: int, /) -> None: ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``ambient()``, ``specular()``, and - ``shininess()`` to set the material properties of shapes. + screen. Use in combination with `ambient()`, `specular()`, and `shininess()` to + set the material properties of shapes. """ pass @@ -8861,79 +8866,78 @@ def emissive(self, *args): ----- Sets the emissive color of the material used for drawing shapes drawn to the - screen. Use in combination with ``ambient()``, ``specular()``, and - ``shininess()`` to set the material properties of shapes. + screen. Use in combination with `ambient()`, `specular()`, and `shininess()` to + set the material properties of shapes. """ return self._instance.emissive(*args) def end_camera(self) -> None: - """The ``begin_camera()`` and ``end_camera()`` methods enable advanced - customization of the camera space. + """The `begin_camera()` and `end_camera()` methods enable advanced customization of + the camera space. Underlying Processing method: PApplet.endCamera Notes ----- - The ``begin_camera()`` and ``end_camera()`` methods enable advanced - customization of the camera space. Please see the reference for - ``begin_camera()`` for a description of how the methods are used. + The `begin_camera()` and `end_camera()` methods enable advanced customization of + the camera space. Please see the reference for `begin_camera()` for a + description of how the methods are used. """ return self._instance.endCamera() def end_contour(self) -> None: - """Use the ``begin_contour()`` and ``end_contour()`` methods to create negative - shapes within shapes such as the center of the letter 'O'. + """Use the `begin_contour()` and `end_contour()` methods to create negative shapes + within shapes such as the center of the letter 'O'. Underlying Processing method: PApplet.endContour Notes ----- - Use the ``begin_contour()`` and ``end_contour()`` methods to create negative - shapes within shapes such as the center of the letter 'O'. The - ``begin_contour()`` method begins recording vertices for the shape and - ``end_contour()`` stops recording. The vertices that define a negative shape - must "wind" in the opposite direction from the exterior shape. First draw - vertices for the exterior shape in clockwise order, then for internal shapes, - draw vertices counterclockwise. + Use the `begin_contour()` and `end_contour()` methods to create negative shapes + within shapes such as the center of the letter 'O'. The `begin_contour()` method + begins recording vertices for the shape and `end_contour()` stops recording. The + vertices that define a negative shape must "wind" in the opposite direction from + the exterior shape. First draw vertices for the exterior shape in clockwise + order, then for internal shapes, draw vertices counterclockwise. - These methods can only be used within a ``begin_shape()`` & ``end_shape()`` pair - and transformations such as ``translate()``, ``rotate()``, and ``scale()`` do - not work within a ``begin_contour()`` & ``end_contour()`` pair. It is also not - possible to use other shapes, such as ``ellipse()`` or ``rect()`` within. + These methods can only be used within a `begin_shape()` & `end_shape()` pair and + transformations such as `translate()`, `rotate()`, and `scale()` do not work + within a `begin_contour()` & `end_contour()` pair. It is also not possible to + use other shapes, such as `ellipse()` or `rect()` within. """ return self._instance.endContour() def end_raw(self) -> None: - """Complement to ``begin_raw()``; they must always be used together. + """Complement to `begin_raw()`; they must always be used together. Underlying Processing method: PApplet.endRaw Notes ----- - Complement to ``begin_raw()``; they must always be used together. See the - ``begin_raw()`` reference for details. + Complement to `begin_raw()`; they must always be used together. See the + `begin_raw()` reference for details. """ return self._instance.endRaw() def end_record(self) -> None: - """Stops the recording process started by ``begin_record()`` and closes the file. + """Stops the recording process started by `begin_record()` and closes the file. Underlying Processing method: PApplet.endRecord Notes ----- - Stops the recording process started by ``begin_record()`` and closes the file. + Stops the recording process started by `begin_record()` and closes the file. """ return self._instance.endRecord() @overload def end_shape(self) -> None: - """The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. + """The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. Underlying Processing method: PApplet.endShape @@ -8954,18 +8958,18 @@ def end_shape(self) -> None: Notes ----- - The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. When ``end_shape()`` is called, all of image - data defined since the previous call to ``begin_shape()`` is written into the - image buffer. The constant ``CLOSE`` as the value for the ``MODE`` parameter to - close the shape (to connect the beginning and the end). + The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. When `end_shape()` is called, all of image data + defined since the previous call to `begin_shape()` is written into the image + buffer. The constant `CLOSE` as the value for the `MODE` parameter to close the + shape (to connect the beginning and the end). """ pass @overload def end_shape(self, mode: int, /) -> None: - """The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. + """The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. Underlying Processing method: PApplet.endShape @@ -8986,17 +8990,17 @@ def end_shape(self, mode: int, /) -> None: Notes ----- - The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. When ``end_shape()`` is called, all of image - data defined since the previous call to ``begin_shape()`` is written into the - image buffer. The constant ``CLOSE`` as the value for the ``MODE`` parameter to - close the shape (to connect the beginning and the end). + The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. When `end_shape()` is called, all of image data + defined since the previous call to `begin_shape()` is written into the image + buffer. The constant `CLOSE` as the value for the `MODE` parameter to close the + shape (to connect the beginning and the end). """ pass def end_shape(self, *args): - """The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. + """The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. Underlying Processing method: PApplet.endShape @@ -9017,11 +9021,11 @@ def end_shape(self, *args): Notes ----- - The ``end_shape()`` function is the companion to ``begin_shape()`` and may only - be called after ``begin_shape()``. When ``end_shape()`` is called, all of image - data defined since the previous call to ``begin_shape()`` is written into the - image buffer. The constant ``CLOSE`` as the value for the ``MODE`` parameter to - close the shape (to connect the beginning and the end). + The `end_shape()` function is the companion to `begin_shape()` and may only be + called after `begin_shape()`. When `end_shape()` is called, all of image data + defined since the previous call to `begin_shape()` is written into the image + buffer. The constant `CLOSE` as the value for the `MODE` parameter to close the + shape (to connect the beginning and the end). """ return self._instance.endShape(*args) @@ -9033,17 +9037,17 @@ def exit_sketch(self) -> None: Notes ----- - Quits/stops/exits the program. Programs without a ``draw()`` function stop - automatically after the last line has run, but programs with ``draw()`` run - continuously until the program is manually stopped or ``exit_sketch()`` is run. + Quits/stops/exits the program. Programs without a `draw()` function stop + automatically after the last line has run, but programs with `draw()` run + continuously until the program is manually stopped or `exit_sketch()` is run. - Rather than terminating immediately, ``exit_sketch()`` will cause the Sketch to - exit after ``draw()`` has completed (or after ``setup()`` completes if called - during the ``setup()`` function). + Rather than terminating immediately, `exit_sketch()` will cause the Sketch to + exit after `draw()` has completed (or after `setup()` completes if called during + the `setup()` function). - For Python programmers, this is *not* the same as ``sys.exit()``. Further, - ``sys.exit()`` should not be used because closing out an application while - ``draw()`` is running may cause a crash (particularly with ``P3D``). + For Python programmers, this is *not* the same as `sys.exit()`. Further, + `sys.exit()` should not be used because closing out an application while + `draw()` is running may cause a crash (particularly with `P3D`). """ return self._instance.exit() @@ -9089,32 +9093,30 @@ def fill(self, gray: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -9160,32 +9162,30 @@ def fill(self, gray: float, alpha: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -9231,32 +9231,30 @@ def fill(self, v1: float, v2: float, v3: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -9302,32 +9300,30 @@ def fill(self, v1: float, v2: float, v3: float, alpha: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -9373,32 +9369,30 @@ def fill(self, rgb: int, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -9444,32 +9438,30 @@ def fill(self, rgb: int, alpha: float, /) -> None: Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ pass @@ -9515,32 +9507,30 @@ def fill(self, *args): Notes ----- - Sets the color used to fill shapes. For example, if you run ``fill(204, 102, - 0)``, all subsequent shapes will be filled with orange. This color is either - specified in terms of the ``RGB`` or ``HSB`` color depending on the current - ``color_mode()``. The default color space is ``RGB``, with each value in the - range from 0 to 255. + Sets the color used to fill shapes. For example, if you run `fill(204, 102, 0)`, + all subsequent shapes will be filled with orange. This color is either specified + in terms of the `RGB` or `HSB` color depending on the current `color_mode()`. + The default color space is `RGB`, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the "gray" parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - To change the color of an image or a texture, use ``tint()``. + To change the color of an image or a texture, use `tint()`. """ return self._instance.fill(*args) @@ -9575,8 +9565,8 @@ def apply_filter(self, kind: int, /) -> None: ----- Filters the display window using a preset filter or with a custom shader. Using - a shader with ``apply_filter()`` is much faster than without. Shaders require - the ``P2D`` or ``P3D`` renderer in ``size()``. + a shader with `apply_filter()` is much faster than without. Shaders require the + `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -9629,8 +9619,8 @@ def apply_filter(self, kind: int, param: float, /) -> None: ----- Filters the display window using a preset filter or with a custom shader. Using - a shader with ``apply_filter()`` is much faster than without. Shaders require - the ``P2D`` or ``P3D`` renderer in ``size()``. + a shader with `apply_filter()` is much faster than without. Shaders require the + `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -9683,8 +9673,8 @@ def apply_filter(self, shader: Py5Shader, /) -> None: ----- Filters the display window using a preset filter or with a custom shader. Using - a shader with ``apply_filter()`` is much faster than without. Shaders require - the ``P2D`` or ``P3D`` renderer in ``size()``. + a shader with `apply_filter()` is much faster than without. Shaders require the + `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -9736,8 +9726,8 @@ def apply_filter(self, *args): ----- Filters the display window using a preset filter or with a custom shader. Using - a shader with ``apply_filter()`` is much faster than without. Shaders require - the ``P2D`` or ``P3D`` renderer in ``size()``. + a shader with `apply_filter()` is much faster than without. Shaders require the + `P2D` or `P3D` renderer in `size()`. The presets options are: @@ -9788,10 +9778,10 @@ def frame_rate(self, fps: float, /) -> None: ----- Specifies the number of frames to be displayed every second. For example, the - function call ``frame_rate(30)`` will attempt to refresh 30 times a second. If - the processor is not fast enough to maintain the specified rate, the frame rate - will not be achieved. Setting the frame rate within ``setup()`` is recommended. - The default rate is 60 frames per second. + function call `frame_rate(30)` will attempt to refresh 30 times a second. If the + processor is not fast enough to maintain the specified rate, the frame rate will + not be achieved. Setting the frame rate within `setup()` is recommended. The + default rate is 60 frames per second. """ return self._instance.frameRate(fps) @@ -9835,7 +9825,7 @@ def frustum(self, left: float, right: float, bottom: float, Setting the frustum has the effect of changing the *perspective* with which the scene is rendered. This can be achieved more simply in many cases by using - ``perspective()``. + `perspective()`. Note that the near value must be greater than zero (as the point of the frustum "pyramid" cannot converge "behind" the viewer). Similarly, the far value must @@ -9876,26 +9866,26 @@ def full_screen(self) -> None: ----- Open a Sketch using the full size of the computer's display. This is intended to - be called from the ``settings()`` function. The ``size()`` and ``full_screen()`` + be called from the `settings()` function. The `size()` and `full_screen()` functions cannot both be used in the same program. When programming in module mode and imported mode, py5 will allow calls to - ``full_screen()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``full_screen()``, or calls - to ``size()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. - - When ``full_screen()`` is used without a parameter on a computer with multiple + `full_screen()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `full_screen()`, or calls to + `size()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + When `full_screen()` is used without a parameter on a computer with multiple monitors, it will (probably) draw the Sketch to the primary display. When it is used with a single parameter, this number defines the screen to display to program on (e.g. 1, 2, 3...). When used with two parameters, the first defines - the renderer to use (e.g. P2D) and the second defines the screen. The ``SPAN`` + the renderer to use (e.g. P2D) and the second defines the screen. The `SPAN` parameter can be used in place of a screen number to draw the Sketch as a full- screen window across all of the attached displays if there are more than one. """ @@ -9930,26 +9920,26 @@ def full_screen(self, display: int, /) -> None: ----- Open a Sketch using the full size of the computer's display. This is intended to - be called from the ``settings()`` function. The ``size()`` and ``full_screen()`` + be called from the `settings()` function. The `size()` and `full_screen()` functions cannot both be used in the same program. When programming in module mode and imported mode, py5 will allow calls to - ``full_screen()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``full_screen()``, or calls - to ``size()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. - - When ``full_screen()`` is used without a parameter on a computer with multiple + `full_screen()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `full_screen()`, or calls to + `size()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + When `full_screen()` is used without a parameter on a computer with multiple monitors, it will (probably) draw the Sketch to the primary display. When it is used with a single parameter, this number defines the screen to display to program on (e.g. 1, 2, 3...). When used with two parameters, the first defines - the renderer to use (e.g. P2D) and the second defines the screen. The ``SPAN`` + the renderer to use (e.g. P2D) and the second defines the screen. The `SPAN` parameter can be used in place of a screen number to draw the Sketch as a full- screen window across all of the attached displays if there are more than one. """ @@ -9984,26 +9974,26 @@ def full_screen(self, renderer: str, /) -> None: ----- Open a Sketch using the full size of the computer's display. This is intended to - be called from the ``settings()`` function. The ``size()`` and ``full_screen()`` + be called from the `settings()` function. The `size()` and `full_screen()` functions cannot both be used in the same program. When programming in module mode and imported mode, py5 will allow calls to - ``full_screen()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``full_screen()``, or calls - to ``size()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. - - When ``full_screen()`` is used without a parameter on a computer with multiple + `full_screen()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `full_screen()`, or calls to + `size()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + When `full_screen()` is used without a parameter on a computer with multiple monitors, it will (probably) draw the Sketch to the primary display. When it is used with a single parameter, this number defines the screen to display to program on (e.g. 1, 2, 3...). When used with two parameters, the first defines - the renderer to use (e.g. P2D) and the second defines the screen. The ``SPAN`` + the renderer to use (e.g. P2D) and the second defines the screen. The `SPAN` parameter can be used in place of a screen number to draw the Sketch as a full- screen window across all of the attached displays if there are more than one. """ @@ -10038,26 +10028,26 @@ def full_screen(self, renderer: str, display: int, /) -> None: ----- Open a Sketch using the full size of the computer's display. This is intended to - be called from the ``settings()`` function. The ``size()`` and ``full_screen()`` + be called from the `settings()` function. The `size()` and `full_screen()` functions cannot both be used in the same program. When programming in module mode and imported mode, py5 will allow calls to - ``full_screen()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``full_screen()``, or calls - to ``size()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. - - When ``full_screen()`` is used without a parameter on a computer with multiple + `full_screen()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `full_screen()`, or calls to + `size()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + When `full_screen()` is used without a parameter on a computer with multiple monitors, it will (probably) draw the Sketch to the primary display. When it is used with a single parameter, this number defines the screen to display to program on (e.g. 1, 2, 3...). When used with two parameters, the first defines - the renderer to use (e.g. P2D) and the second defines the screen. The ``SPAN`` + the renderer to use (e.g. P2D) and the second defines the screen. The `SPAN` parameter can be used in place of a screen number to draw the Sketch as a full- screen window across all of the attached displays if there are more than one. """ @@ -10092,33 +10082,33 @@ def full_screen(self, *args): ----- Open a Sketch using the full size of the computer's display. This is intended to - be called from the ``settings()`` function. The ``size()`` and ``full_screen()`` + be called from the `settings()` function. The `size()` and `full_screen()` functions cannot both be used in the same program. When programming in module mode and imported mode, py5 will allow calls to - ``full_screen()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``full_screen()``, or calls - to ``size()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. - - When ``full_screen()`` is used without a parameter on a computer with multiple + `full_screen()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `full_screen()`, or calls to + `size()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + When `full_screen()` is used without a parameter on a computer with multiple monitors, it will (probably) draw the Sketch to the primary display. When it is used with a single parameter, this number defines the screen to display to program on (e.g. 1, 2, 3...). When used with two parameters, the first defines - the renderer to use (e.g. P2D) and the second defines the screen. The ``SPAN`` + the renderer to use (e.g. P2D) and the second defines the screen. The `SPAN` parameter can be used in place of a screen number to draw the Sketch as a full- screen window across all of the attached displays if there are more than one. """ return self._instance.fullScreen(*args) @overload - def get(self) -> Py5Image: + def get_pixels(self) -> Py5Image: """Reads the color of any pixel or grabs a section of the drawing surface. Underlying Processing method: PApplet.get @@ -10128,9 +10118,9 @@ def get(self) -> Py5Image: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -10151,32 +10141,32 @@ def get(self) -> Py5Image: ----- Reads the color of any pixel or grabs a section of the drawing surface. If no - parameters are specified, the entire drawing surface is returned. Use the ``x`` - and ``y`` parameters to get the value of one pixel. Get a section of the display - window by specifying additional ``w`` and ``h`` parameters. When getting an - image, the ``x`` and ``y`` parameters define the coordinates for the upper-left - corner of the returned image, regardless of the current ``image_mode()``. + parameters are specified, the entire drawing surface is returned. Use the `x` + and `y` parameters to get the value of one pixel. Get a section of the display + window by specifying additional `w` and `h` parameters. When getting an image, + the `x` and `y` parameters define the coordinates for the upper-left corner of + the returned image, regardless of the current `image_mode()`. If the pixel requested is outside of the image window, black is returned. The numbers returned are scaled according to the current color ranges, but only - ``RGB`` values are returned by this function. For example, even though you may - have drawn a shape with ``color_mode(HSB)``, the numbers returned will be in - ``RGB`` format. + `RGB` values are returned by this function. For example, even though you may + have drawn a shape with `color_mode(HSB)`, the numbers returned will be in `RGB` + format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``pixels[]`` or ``np_pixels[]``. The - equivalent statement to ``get(x, y)`` using ``pixels[]`` is - ``pixels[y*width+x]``. Using ``np_pixels[]`` it is ``np_pixels[y, x]``. See the - reference for ``pixels[]`` and ``np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `pixels[]` or `np_pixels[]`. The + equivalent statement to `get_pixels(x, y)` using `pixels[]` is + `pixels[y*width+x]`. Using `np_pixels[]` it is `np_pixels[y, x]`. See the + reference for `pixels[]` and `np_pixels[]` for more information. """ pass @overload - def get(self, x: int, y: int, /) -> int: + def get_pixels(self, x: int, y: int, /) -> int: """Reads the color of any pixel or grabs a section of the drawing surface. Underlying Processing method: PApplet.get @@ -10186,9 +10176,9 @@ def get(self, x: int, y: int, /) -> int: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -10209,32 +10199,32 @@ def get(self, x: int, y: int, /) -> int: ----- Reads the color of any pixel or grabs a section of the drawing surface. If no - parameters are specified, the entire drawing surface is returned. Use the ``x`` - and ``y`` parameters to get the value of one pixel. Get a section of the display - window by specifying additional ``w`` and ``h`` parameters. When getting an - image, the ``x`` and ``y`` parameters define the coordinates for the upper-left - corner of the returned image, regardless of the current ``image_mode()``. + parameters are specified, the entire drawing surface is returned. Use the `x` + and `y` parameters to get the value of one pixel. Get a section of the display + window by specifying additional `w` and `h` parameters. When getting an image, + the `x` and `y` parameters define the coordinates for the upper-left corner of + the returned image, regardless of the current `image_mode()`. If the pixel requested is outside of the image window, black is returned. The numbers returned are scaled according to the current color ranges, but only - ``RGB`` values are returned by this function. For example, even though you may - have drawn a shape with ``color_mode(HSB)``, the numbers returned will be in - ``RGB`` format. + `RGB` values are returned by this function. For example, even though you may + have drawn a shape with `color_mode(HSB)`, the numbers returned will be in `RGB` + format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``pixels[]`` or ``np_pixels[]``. The - equivalent statement to ``get(x, y)`` using ``pixels[]`` is - ``pixels[y*width+x]``. Using ``np_pixels[]`` it is ``np_pixels[y, x]``. See the - reference for ``pixels[]`` and ``np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `pixels[]` or `np_pixels[]`. The + equivalent statement to `get_pixels(x, y)` using `pixels[]` is + `pixels[y*width+x]`. Using `np_pixels[]` it is `np_pixels[y, x]`. See the + reference for `pixels[]` and `np_pixels[]` for more information. """ pass @overload - def get(self, x: int, y: int, w: int, h: int, /) -> Py5Image: + def get_pixels(self, x: int, y: int, w: int, h: int, /) -> Py5Image: """Reads the color of any pixel or grabs a section of the drawing surface. Underlying Processing method: PApplet.get @@ -10244,9 +10234,9 @@ def get(self, x: int, y: int, w: int, h: int, /) -> Py5Image: You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -10267,32 +10257,32 @@ def get(self, x: int, y: int, w: int, h: int, /) -> Py5Image: ----- Reads the color of any pixel or grabs a section of the drawing surface. If no - parameters are specified, the entire drawing surface is returned. Use the ``x`` - and ``y`` parameters to get the value of one pixel. Get a section of the display - window by specifying additional ``w`` and ``h`` parameters. When getting an - image, the ``x`` and ``y`` parameters define the coordinates for the upper-left - corner of the returned image, regardless of the current ``image_mode()``. + parameters are specified, the entire drawing surface is returned. Use the `x` + and `y` parameters to get the value of one pixel. Get a section of the display + window by specifying additional `w` and `h` parameters. When getting an image, + the `x` and `y` parameters define the coordinates for the upper-left corner of + the returned image, regardless of the current `image_mode()`. If the pixel requested is outside of the image window, black is returned. The numbers returned are scaled according to the current color ranges, but only - ``RGB`` values are returned by this function. For example, even though you may - have drawn a shape with ``color_mode(HSB)``, the numbers returned will be in - ``RGB`` format. + `RGB` values are returned by this function. For example, even though you may + have drawn a shape with `color_mode(HSB)`, the numbers returned will be in `RGB` + format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``pixels[]`` or ``np_pixels[]``. The - equivalent statement to ``get(x, y)`` using ``pixels[]`` is - ``pixels[y*width+x]``. Using ``np_pixels[]`` it is ``np_pixels[y, x]``. See the - reference for ``pixels[]`` and ``np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `pixels[]` or `np_pixels[]`. The + equivalent statement to `get_pixels(x, y)` using `pixels[]` is + `pixels[y*width+x]`. Using `np_pixels[]` it is `np_pixels[y, x]`. See the + reference for `pixels[]` and `np_pixels[]` for more information. """ pass @_return_py5image - def get(self, *args): + def get_pixels(self, *args): """Reads the color of any pixel or grabs a section of the drawing surface. Underlying Processing method: PApplet.get @@ -10302,9 +10292,9 @@ def get(self, *args): You can use any of the following signatures: - * get() -> Py5Image - * get(x: int, y: int, /) -> int - * get(x: int, y: int, w: int, h: int, /) -> Py5Image + * get_pixels() -> Py5Image + * get_pixels(x: int, y: int, /) -> int + * get_pixels(x: int, y: int, w: int, h: int, /) -> Py5Image Parameters ---------- @@ -10325,27 +10315,27 @@ def get(self, *args): ----- Reads the color of any pixel or grabs a section of the drawing surface. If no - parameters are specified, the entire drawing surface is returned. Use the ``x`` - and ``y`` parameters to get the value of one pixel. Get a section of the display - window by specifying additional ``w`` and ``h`` parameters. When getting an - image, the ``x`` and ``y`` parameters define the coordinates for the upper-left - corner of the returned image, regardless of the current ``image_mode()``. + parameters are specified, the entire drawing surface is returned. Use the `x` + and `y` parameters to get the value of one pixel. Get a section of the display + window by specifying additional `w` and `h` parameters. When getting an image, + the `x` and `y` parameters define the coordinates for the upper-left corner of + the returned image, regardless of the current `image_mode()`. If the pixel requested is outside of the image window, black is returned. The numbers returned are scaled according to the current color ranges, but only - ``RGB`` values are returned by this function. For example, even though you may - have drawn a shape with ``color_mode(HSB)``, the numbers returned will be in - ``RGB`` format. + `RGB` values are returned by this function. For example, even though you may + have drawn a shape with `color_mode(HSB)`, the numbers returned will be in `RGB` + format. - If a width and a height are specified, ``get(x, y, w, h)`` returns a Py5Image - corresponding to the part of the original Py5Image where the top left pixel is - at the ``(x, y)`` position with a width of ``w`` a height of ``h``. + If a width and a height are specified, `get_pixels(x, y, w, h)` returns a + Py5Image corresponding to the part of the original Py5Image where the top left + pixel is at the `(x, y)` position with a width of `w` a height of `h`. - Getting the color of a single pixel with ``get(x, y)`` is easy, but not as fast - as grabbing the data directly from ``pixels[]`` or ``np_pixels[]``. The - equivalent statement to ``get(x, y)`` using ``pixels[]`` is - ``pixels[y*width+x]``. Using ``np_pixels[]`` it is ``np_pixels[y, x]``. See the - reference for ``pixels[]`` and ``np_pixels[]`` for more information. + Getting the color of a single pixel with `get_pixels(x, y)` is easy, but not as + fast as grabbing the data directly from `pixels[]` or `np_pixels[]`. The + equivalent statement to `get_pixels(x, y)` using `pixels[]` is + `pixels[y*width+x]`. Using `np_pixels[]` it is `np_pixels[y, x]`. See the + reference for `pixels[]` and `np_pixels[]` for more information. """ return self._instance.get(*args) @@ -10360,27 +10350,26 @@ def get_frame_rate(self) -> float: Get the running Sketch's current frame rate. This is measured in frames per second (fps) and uses an exponential moving average. The returned value will not be accurate until after the Sketch has run for a few seconds. You can set the - target frame rate with ``frame_rate()``. + target frame rate with `frame_rate()`. - This method provides the same information as Processing's ``frameRate`` - variable. Python can't have a variable and a method with the same name, so a new - method was created to provide access to that variable. + This method provides the same information as Processing's `frameRate` variable. + Python can't have a variable and a method with the same name, so a new method + was created to provide access to that variable. """ return self._instance.getFrameRate() @_return_py5graphics def get_graphics(self) -> Py5Graphics: - """Get the ``Py5Graphics`` object used by the Sketch. + """Get the `Py5Graphics` object used by the Sketch. Underlying Processing method: PApplet.getGraphics Notes ----- - Get the ``Py5Graphics`` object used by the Sketch. Internally, all of - Processing's drawing functionality comes from interaction with PGraphics - objects, and this will provide direct access to the PGraphics object used by the - Sketch. + Get the `Py5Graphics` object used by the Sketch. Internally, all of Processing's + drawing functionality comes from interaction with PGraphics objects, and this + will provide direct access to the PGraphics object used by the Sketch. """ return self._instance.getGraphics() @@ -10407,7 +10396,7 @@ def get_matrix(self) -> npt.NDArray[np.floating]: Notes ----- - Get the current matrix as a numpy array. Use the ``target`` parameter to put the + Get the current matrix as a numpy array. Use the `target` parameter to put the matrix data in a properly sized and typed numpy array. """ pass @@ -10436,7 +10425,7 @@ def get_matrix( Notes ----- - Get the current matrix as a numpy array. Use the ``target`` parameter to put the + Get the current matrix as a numpy array. Use the `target` parameter to put the matrix data in a properly sized and typed numpy array. """ pass @@ -10464,27 +10453,27 @@ def get_matrix(self, *args): Notes ----- - Get the current matrix as a numpy array. Use the ``target`` parameter to put the + Get the current matrix as a numpy array. Use the `target` parameter to put the matrix data in a properly sized and typed numpy array. """ return self._instance.getMatrix(*args) @_return_py5surface def get_surface(self) -> Py5Surface: - """Get the ``Py5Surface`` object used for the Sketch. + """Get the `Py5Surface` object used for the Sketch. Underlying Processing method: PApplet.getSurface Notes ----- - Get the ``Py5Surface`` object used for the Sketch. + Get the `Py5Surface` object used for the Sketch. """ return self._instance.getSurface() @_convert_hex_color() def green(self, rgb: int, /) -> float: - """Extracts the green value from a color, scaled to match current ``color_mode()``. + """Extracts the green value from a color, scaled to match current `color_mode()`. Underlying Processing method: PApplet.green @@ -10497,14 +10486,14 @@ def green(self, rgb: int, /) -> float: Notes ----- - Extracts the green value from a color, scaled to match current ``color_mode()``. + Extracts the green value from a color, scaled to match current `color_mode()`. - The ``green()`` function is easy to use and understand, but it is slower than a - technique called bit shifting. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``green()`` but with greater speed by using the - right shift operator (``>>``) with a bit mask. For example, ``green(c)`` and ``c - >> 8 & 0xFF`` both extract the green value from a color variable ``c`` but the - later is faster. + The `green()` function is easy to use and understand, but it is slower than a + technique called bit shifting. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `green()` but with greater speed by using the right + shift operator (`>>`) with a bit mask. For example, `green(c)` and `c >> 8 & + 0xFF` both extract the green value from a color variable `c` but the later is + faster. """ return self._instance.green(rgb) @@ -10527,67 +10516,66 @@ def hint(self, which: int, /) -> None: graphics are drawn. In the course of developing Processing, the developers had to make hard decisions about tradeoffs between performance and visual quality. They put significant effort into determining what makes most sense for the - largest number of users, and then use functions like ``hint()`` to allow people - to tune the settings for their particular Sketch. Implementing a ``hint()`` is a - last resort that's used when a more elegant solution cannot be found. Some - options might graduate to standard features instead of hints over time, or be - added and removed between (major) releases. + largest number of users, and then use functions like `hint()` to allow people to + tune the settings for their particular Sketch. Implementing a `hint()` is a last + resort that's used when a more elegant solution cannot be found. Some options + might graduate to standard features instead of hints over time, or be added and + removed between (major) releases. Hints used by the Default Renderer ---------------------------------- - * ``ENABLE_STROKE_PURE``: Fixes a problem with shapes that have a stroke and are - rendered using small steps (for instance, using ``vertex()`` with points that - are close to one another), or are drawn at small sizes. + * `ENABLE_STROKE_PURE`: Fixes a problem with shapes that have a stroke and are + rendered using small steps (for instance, using `vertex()` with points that are + close to one another), or are drawn at small sizes. - Hints for use with ``P2D`` and ``P3D`` + Hints for use with `P2D` and `P3D` -------------------------------------- - * ``DISABLE_OPENGL_ERRORS``: Speeds up the ``P3D`` renderer setting by not - checking for errors while running. - * ``DISABLE_TEXTURE_MIPMAPS``: Disable generation of texture mipmaps in ``P2D`` - or ``P3D``. This results in lower quality - but faster - rendering of texture - images when they appear smaller than their native resolutions (the mipmaps are - scaled-down versions of a texture that make it look better when drawing it at a - small size). However, the difference in performance is fairly minor on recent - desktop video cards. + * `DISABLE_OPENGL_ERRORS`: Speeds up the `P3D` renderer setting by not checking + for errors while running. + * `DISABLE_TEXTURE_MIPMAPS`: Disable generation of texture mipmaps in `P2D` or + `P3D`. This results in lower quality - but faster - rendering of texture images + when they appear smaller than their native resolutions (the mipmaps are scaled- + down versions of a texture that make it look better when drawing it at a small + size). However, the difference in performance is fairly minor on recent desktop + video cards. - Hints for use with ``P3D`` only + Hints for use with `P3D` only ------------------------------- - * ``DISABLE_DEPTH_MASK``: Disables writing into the depth buffer. This means - that a shape drawn with this hint can be hidden by another shape drawn later, + * `DISABLE_DEPTH_MASK`: Disables writing into the depth buffer. This means that + a shape drawn with this hint can be hidden by another shape drawn later, irrespective of their distances to the camera. Note that this is different from disabling the depth test. The depth test is still applied, as long as the - ``DISABLE_DEPTH_TEST`` hint is not called, but the depth values of the objects - are not recorded. This is useful when drawing a semi-transparent 3D object - without depth sorting, in order to avoid visual glitches due the faces of the - object being at different distances from the camera, but still having the object + `DISABLE_DEPTH_TEST` hint is not called, but the depth values of the objects are + not recorded. This is useful when drawing a semi-transparent 3D object without + depth sorting, in order to avoid visual glitches due the faces of the object + being at different distances from the camera, but still having the object properly occluded by the rest of the objects in the scene. - * ``ENABLE_DEPTH_SORT``: Enable primitive z-sorting of triangles and lines in - ``P3D``. This can slow performance considerably, and the algorithm is not yet + * `ENABLE_DEPTH_SORT`: Enable primitive z-sorting of triangles and lines in + `P3D`. This can slow performance considerably, and the algorithm is not yet perfect. - * ``DISABLE_DEPTH_TEST``: Disable the zbuffer, allowing you to draw on top of + * `DISABLE_DEPTH_TEST`: Disable the zbuffer, allowing you to draw on top of everything at will. When depth testing is disabled, items will be drawn to the screen sequentially, like a painting. This hint is most often used to draw in 3D, then draw in 2D on top of it (for instance, to draw GUI controls in 2D on top of a 3D interface). When called, this will also clear the depth buffer. - Restore the default with ``hint(ENABLE_DEPTH_TEST)``, but note that with the - depth buffer cleared, any 3D drawing that happens later in will ignore existing - shapes on the screen. - * ``DISABLE_OPTIMIZED_STROKE``: Forces the ``P3D`` renderer to draw each shape + Restore the default with `hint(ENABLE_DEPTH_TEST)`, but note that with the depth + buffer cleared, any 3D drawing that happens later in will ignore existing shapes + on the screen. + * `DISABLE_OPTIMIZED_STROKE`: Forces the `P3D` renderer to draw each shape (including its strokes) separately, instead of batching them into larger groups for better performance. One consequence of this is that 2D items drawn with - ``P3D`` are correctly stacked on the screen, depending on the order in which - they were drawn. Otherwise, glitches such as the stroke lines being drawn on top - of the interior of all the shapes will occur. However, this hint can make - rendering substantially slower, so it is recommended to use it only when drawing - a small amount of shapes. For drawing two-dimensional scenes, use the ``P2D`` - renderer instead, which doesn't need the hint to properly stack shapes and their - strokes. - * ``ENABLE_STROKE_PERSPECTIVE``: Enables stroke geometry (lines and points) to - be affected by the perspective, meaning that they will look smaller as they move + `P3D` are correctly stacked on the screen, depending on the order in which they + were drawn. Otherwise, glitches such as the stroke lines being drawn on top of + the interior of all the shapes will occur. However, this hint can make rendering + substantially slower, so it is recommended to use it only when drawing a small + amount of shapes. For drawing two-dimensional scenes, use the `P2D` renderer + instead, which doesn't need the hint to properly stack shapes and their strokes. + * `ENABLE_STROKE_PERSPECTIVE`: Enables stroke geometry (lines and points) to be + affected by the perspective, meaning that they will look smaller as they move away from the camera. """ return self._instance.hint(which) @@ -10601,8 +10589,8 @@ def hour(cls) -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``hour()`` function - returns the current hour as a value from 0 - 23. + Py5 communicates with the clock on your computer. The `hour()` function returns + the current hour as a value from 0 - 23. """ return cls._cls.hour() @@ -10627,7 +10615,7 @@ def hue(self, rgb: int, /) -> float: @overload def image(self, img: Py5Image, a: float, b: float, /) -> None: - """The ``image()`` function draws an image to the display window. + """The `image()` function draws an image to the display window. Underlying Processing method: PApplet.image @@ -10673,29 +10661,29 @@ def image(self, img: Py5Image, a: float, b: float, /) -> None: Notes ----- - The ``image()`` function draws an image to the display window. Images must be in + The `image()` function draws an image to the display window. Images must be in the Sketch's "data" directory to load correctly. Py5 currently works with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``image_mode()`` function can be used to change the way - these parameters draw the image. + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `image_mode()` function can be used to change the way these + parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `texture_mode()` setting. - The color of an image may be modified with the ``tint()`` function. This - function will maintain transparency for GIF and PNG images. + The color of an image may be modified with the `tint()` function. This function + will maintain transparency for GIF and PNG images. """ pass @overload def image(self, img: Py5Image, a: float, b: float, c: float, d: float, /) -> None: - """The ``image()`` function draws an image to the display window. + """The `image()` function draws an image to the display window. Underlying Processing method: PApplet.image @@ -10741,29 +10729,29 @@ def image(self, img: Py5Image, a: float, b: float, Notes ----- - The ``image()`` function draws an image to the display window. Images must be in + The `image()` function draws an image to the display window. Images must be in the Sketch's "data" directory to load correctly. Py5 currently works with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``image_mode()`` function can be used to change the way - these parameters draw the image. + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `image_mode()` function can be used to change the way these + parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `texture_mode()` setting. - The color of an image may be modified with the ``tint()`` function. This - function will maintain transparency for GIF and PNG images. + The color of an image may be modified with the `tint()` function. This function + will maintain transparency for GIF and PNG images. """ pass @overload def image(self, img: Py5Image, a: float, b: float, c: float, d: float, u1: int, v1: int, u2: int, v2: int, /) -> None: - """The ``image()`` function draws an image to the display window. + """The `image()` function draws an image to the display window. Underlying Processing method: PApplet.image @@ -10809,28 +10797,28 @@ def image(self, img: Py5Image, a: float, b: float, c: float, Notes ----- - The ``image()`` function draws an image to the display window. Images must be in + The `image()` function draws an image to the display window. Images must be in the Sketch's "data" directory to load correctly. Py5 currently works with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``image_mode()`` function can be used to change the way - these parameters draw the image. + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `image_mode()` function can be used to change the way these + parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `texture_mode()` setting. - The color of an image may be modified with the ``tint()`` function. This - function will maintain transparency for GIF and PNG images. + The color of an image may be modified with the `tint()` function. This function + will maintain transparency for GIF and PNG images. """ pass - @_auto_convert_to_py5image + @_auto_convert_to_py5image(0) def image(self, *args): - """The ``image()`` function draws an image to the display window. + """The `image()` function draws an image to the display window. Underlying Processing method: PApplet.image @@ -10876,28 +10864,28 @@ def image(self, *args): Notes ----- - The ``image()`` function draws an image to the display window. Images must be in + The `image()` function draws an image to the display window. Images must be in the Sketch's "data" directory to load correctly. Py5 currently works with GIF, JPEG, and PNG images. - The ``img`` parameter specifies the image to display and by default the ``a`` - and ``b`` parameters define the location of its upper-left corner. The image is - displayed at its original size unless the ``c`` and ``d`` parameters specify a - different size. The ``image_mode()`` function can be used to change the way - these parameters draw the image. + The `img` parameter specifies the image to display and by default the `a` and + `b` parameters define the location of its upper-left corner. The image is + displayed at its original size unless the `c` and `d` parameters specify a + different size. The `image_mode()` function can be used to change the way these + parameters draw the image. - Use the ``u1``, ``u2``, ``v1``, and ``v2`` parameters to use only a subset of - the image. These values are always specified in image space location, regardless - of the current ``texture_mode()`` setting. + Use the `u1`, `u2`, `v1`, and `v2` parameters to use only a subset of the image. + These values are always specified in image space location, regardless of the + current `texture_mode()` setting. - The color of an image may be modified with the ``tint()`` function. This - function will maintain transparency for GIF and PNG images. + The color of an image may be modified with the `tint()` function. This function + will maintain transparency for GIF and PNG images. """ return self._instance.image(*args) def image_mode(self, mode: int, /) -> None: """Modifies the location from which images are drawn by changing the way in which - parameters given to ``image()`` are intepreted. + parameters given to `image()` are intepreted. Underlying Processing method: PApplet.imageMode @@ -10911,20 +10899,19 @@ def image_mode(self, mode: int, /) -> None: ----- Modifies the location from which images are drawn by changing the way in which - parameters given to ``image()`` are intepreted. + parameters given to `image()` are intepreted. - The default mode is ``image_mode(CORNER)``, which interprets the second and - third parameters of ``image()`` as the upper-left corner of the image. If two - additional parameters are specified, they are used to set the image's width and - height. + The default mode is `image_mode(CORNER)`, which interprets the second and third + parameters of `image()` as the upper-left corner of the image. If two additional + parameters are specified, they are used to set the image's width and height. - ``image_mode(CORNERS)`` interprets the second and third parameters of - ``image()`` as the location of one corner, and the fourth and fifth parameters - as the opposite corner. + `image_mode(CORNERS)` interprets the second and third parameters of `image()` as + the location of one corner, and the fourth and fifth parameters as the opposite + corner. - ``image_mode(CENTER)`` interprets the second and third parameters of ``image()`` - as the image's center point. If two additional parameters are specified, they - are used to set the image's width and height. + `image_mode(CENTER)` interprets the second and third parameters of `image()` as + the image's center point. If two additional parameters are specified, they are + used to set the image's width and height. The parameter must be written in ALL CAPS because Python is a case-sensitive language. @@ -10963,13 +10950,13 @@ def lerp_color(self, c1: int, c2: int, amt: float, /) -> int: Notes ----- - Calculates a color between two colors at a specific increment. The ``amt`` + Calculates a color between two colors at a specific increment. The `amt` parameter is the amount to interpolate between the two values where 0.0 is equal to the first point, 0.1 is very near the first point, 0.5 is halfway in between, etc. An amount below 0 will be treated as 0. Likewise, amounts above 1 will be capped - at 1. This is different from the behavior of ``lerp()``, but necessary because + at 1. This is different from the behavior of `lerp()`, but necessary because otherwise numbers outside the range will produce strange and unexpected colors. """ pass @@ -11006,13 +10993,13 @@ def lerp_color(self, c1: int, c2: int, amt: float, mode: int, /) -> int: Notes ----- - Calculates a color between two colors at a specific increment. The ``amt`` + Calculates a color between two colors at a specific increment. The `amt` parameter is the amount to interpolate between the two values where 0.0 is equal to the first point, 0.1 is very near the first point, 0.5 is halfway in between, etc. An amount below 0 will be treated as 0. Likewise, amounts above 1 will be capped - at 1. This is different from the behavior of ``lerp()``, but necessary because + at 1. This is different from the behavior of `lerp()`, but necessary because otherwise numbers outside the range will produce strange and unexpected colors. """ pass @@ -11049,13 +11036,13 @@ def lerp_color(self, *args): Notes ----- - Calculates a color between two colors at a specific increment. The ``amt`` + Calculates a color between two colors at a specific increment. The `amt` parameter is the amount to interpolate between the two values where 0.0 is equal to the first point, 0.1 is very near the first point, 0.5 is halfway in between, etc. An amount below 0 will be treated as 0. Likewise, amounts above 1 will be capped - at 1. This is different from the behavior of ``lerp()``, but necessary because + at 1. This is different from the behavior of `lerp()`, but necessary because otherwise numbers outside the range will produce strange and unexpected colors. """ return self._instance.lerpColor(*args) @@ -11082,11 +11069,11 @@ def light_falloff(self, constant: float, linear: float, ----- Sets the falloff rates for point lights, spot lights, and ambient lights. Like - ``fill()``, it affects only the elements which are created after it in the code. - The default value is ``light_falloff(1.0, 0.0, 0.0)``, and the parameters are - used to calculate the falloff with the equation ``falloff = 1 / (CONSTANT + d * - ``LINEAR`` + (d*d) * QUADRATIC)``, where ``d`` is the distance from light - position to vertex position. + `fill()`, it affects only the elements which are created after it in the code. + The default value is `light_falloff(1.0, 0.0, 0.0)`, and the parameters are used + to calculate the falloff with the equation `falloff = 1 / (CONSTANT + d * + `LINEAR` + (d*d) * QUADRATIC)`, where `d` is the distance from light position to + vertex position. Thinking about an ambient light with a falloff can be tricky. If you want a region of your scene to be lit ambiently with one color and another region to be @@ -11116,12 +11103,12 @@ def light_specular(self, v1: float, v2: float, v3: float, /) -> None: Notes ----- - Sets the specular color for lights. Like ``fill()``, it affects only the - elements which are created after it in the code. Specular refers to light which - bounces off a surface in a preferred direction (rather than bouncing in all - directions like a diffuse light) and is used for creating highlights. The - specular quality of a light interacts with the specular material qualities set - through the ``specular()`` and ``shininess()`` functions. + Sets the specular color for lights. Like `fill()`, it affects only the elements + which are created after it in the code. Specular refers to light which bounces + off a surface in a preferred direction (rather than bouncing in all directions + like a diffuse light) and is used for creating highlights. The specular quality + of a light interacts with the specular material qualities set through the + `specular()` and `shininess()` functions. """ return self._instance.lightSpecular(v1, v2, v3) @@ -11134,11 +11121,11 @@ def lights(self) -> None: ----- Sets the default ambient light, directional light, falloff, and specular values. - The defaults are ``ambientLight(128, 128, 128)`` and ``directionalLight(128, - 128, 128, 0, 0, -1)``, ``lightFalloff(1, 0, 0)``, and ``lightSpecular(0, 0, - 0)``. Lights need to be included in the ``draw()`` to remain persistent in a - looping program. Placing them in the ``setup()`` of a looping program will cause - them to only have an effect the first time through the loop. + The defaults are `ambientLight(128, 128, 128)` and `directionalLight(128, 128, + 128, 0, 0, -1)`, `lightFalloff(1, 0, 0)`, and `lightSpecular(0, 0, 0)`. Lights + need to be included in the `draw()` to remain persistent in a looping program. + Placing them in the `setup()` of a looping program will cause them to only have + an effect the first time through the loop. """ return self._instance.lights() @@ -11181,13 +11168,13 @@ def line(self, x1: float, y1: float, x2: float, y2: float, /) -> None: ----- Draws a line (a direct path between two points) to the screen. The version of - ``line()`` with four parameters draws the line in 2D. To color a line, use the - ``stroke()`` function. A line cannot be filled, therefore the ``fill()`` - function will not affect the color of a line. 2D lines are drawn with a width of - one pixel by default, but this can be changed with the ``stroke_weight()`` - function. The version with six parameters allows the line to be placed anywhere - within XYZ space. Drawing this shape in 3D with the ``z`` parameter requires the - ``P3D`` parameter in combination with ``size()`` as shown in the third example. + `line()` with four parameters draws the line in 2D. To color a line, use the + `stroke()` function. A line cannot be filled, therefore the `fill()` function + will not affect the color of a line. 2D lines are drawn with a width of one + pixel by default, but this can be changed with the `stroke_weight()` function. + The version with six parameters allows the line to be placed anywhere within XYZ + space. Drawing this shape in 3D with the `z` parameter requires the `P3D` + parameter in combination with `size()` as shown in the third example. """ pass @@ -11231,13 +11218,13 @@ def line(self, x1: float, y1: float, z1: float, ----- Draws a line (a direct path between two points) to the screen. The version of - ``line()`` with four parameters draws the line in 2D. To color a line, use the - ``stroke()`` function. A line cannot be filled, therefore the ``fill()`` - function will not affect the color of a line. 2D lines are drawn with a width of - one pixel by default, but this can be changed with the ``stroke_weight()`` - function. The version with six parameters allows the line to be placed anywhere - within XYZ space. Drawing this shape in 3D with the ``z`` parameter requires the - ``P3D`` parameter in combination with ``size()`` as shown in the third example. + `line()` with four parameters draws the line in 2D. To color a line, use the + `stroke()` function. A line cannot be filled, therefore the `fill()` function + will not affect the color of a line. 2D lines are drawn with a width of one + pixel by default, but this can be changed with the `stroke_weight()` function. + The version with six parameters allows the line to be placed anywhere within XYZ + space. Drawing this shape in 3D with the `z` parameter requires the `P3D` + parameter in combination with `size()` as shown in the third example. """ pass @@ -11279,16 +11266,17 @@ def line(self, *args): ----- Draws a line (a direct path between two points) to the screen. The version of - ``line()`` with four parameters draws the line in 2D. To color a line, use the - ``stroke()`` function. A line cannot be filled, therefore the ``fill()`` - function will not affect the color of a line. 2D lines are drawn with a width of - one pixel by default, but this can be changed with the ``stroke_weight()`` - function. The version with six parameters allows the line to be placed anywhere - within XYZ space. Drawing this shape in 3D with the ``z`` parameter requires the - ``P3D`` parameter in combination with ``size()`` as shown in the third example. + `line()` with four parameters draws the line in 2D. To color a line, use the + `stroke()` function. A line cannot be filled, therefore the `fill()` function + will not affect the color of a line. 2D lines are drawn with a width of one + pixel by default, but this can be changed with the `stroke_weight()` function. + The version with six parameters allows the line to be placed anywhere within XYZ + space. Drawing this shape in 3D with the `z` parameter requires the `P3D` + parameter in combination with `size()` as shown in the third example. """ return self._instance.line(*args) + @_generator_to_list def lines(self, coordinates: npt.NDArray[np.floating], /) -> None: """Draw a collection of lines to the screen. @@ -11304,19 +11292,19 @@ def lines(self, coordinates: npt.NDArray[np.floating], /) -> None: ----- Draw a collection of lines to the screen. The purpose of this method is to - provide an alternative to repeatedly calling ``line()`` in a loop. For a large - number of lines, the performance of ``lines()`` will be much faster. + provide an alternative to repeatedly calling `line()` in a loop. For a large + number of lines, the performance of `lines()` will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each - line. The first few columns are for the first point of each line and the next - few columns are for the second point of each line. There will be four or six - columns for 2D or 3D points, respectively. + The `coordinates` parameter should be a numpy array with one row for each line. + The first few columns are for the first point of each line and the next few + columns are for the second point of each line. There will be four or six columns + for 2D or 3D points, respectively. """ return self._instance.lines(coordinates) @_load_py5font def load_font(self, filename: str, /) -> Py5Font: - """Loads a .vlw formatted font into a ``Py5Font`` object. + """Loads a .vlw formatted font into a `Py5Font` object. Underlying Processing method: PApplet.loadFont @@ -11329,20 +11317,20 @@ def load_font(self, filename: str, /) -> Py5Font: Notes ----- - Loads a .vlw formatted font into a ``Py5Font`` object. Create a .vlw font with - the ``create_font_file()`` function. This tool creates a texture for each - alphanumeric character and then adds them as a .vlw file to the current Sketch's - data folder. Because the letters are defined as textures (and not vector data) - the size at which the fonts are created must be considered in relation to the - size at which they are drawn. For example, load a 32pt font if the Sketch - displays the font at 32 pixels or smaller. Conversely, if a 12pt font is loaded - and displayed at 48pts, the letters will be distorted because the program will - be stretching a small graphic to a large size. + Loads a .vlw formatted font into a `Py5Font` object. Create a .vlw font with the + `create_font_file()` function. This tool creates a texture for each alphanumeric + character and then adds them as a .vlw file to the current Sketch's data folder. + Because the letters are defined as textures (and not vector data) the size at + which the fonts are created must be considered in relation to the size at which + they are drawn. For example, load a 32pt font if the Sketch displays the font at + 32 pixels or smaller. Conversely, if a 12pt font is loaded and displayed at + 48pts, the letters will be distorted because the program will be stretching a + small graphic to a large size. - Like ``load_image()`` and other functions that load data, the ``load_font()`` - function should not be used inside ``draw()``, because it will slow down the + Like `load_image()` and other functions that load data, the `load_font()` + function should not be used inside `draw()`, because it will slow down the Sketch considerably, as the font will be re-loaded from the disk (or network) on - each frame. It's recommended to load files inside ``setup()``. + each frame. It's recommended to load files inside `setup()`. To load correctly, fonts must be located in the "data" folder of the current Sketch. Alternatively, the file maybe be loaded from anywhere on the local @@ -11350,36 +11338,36 @@ def load_font(self, filename: str, /) -> Py5Font: or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. - Use ``create_font()`` (instead of ``load_font()``) to enable vector data to be - used with the default renderer setting. This can be helpful when many font sizes - are needed, or when using any renderer based on the default renderer, such as - the ``PDF`` renderer. + Use `create_font()` (instead of `load_font()`) to enable vector data to be used + with the default renderer setting. This can be helpful when many font sizes are + needed, or when using any renderer based on the default renderer, such as the + `PDF` renderer. """ return self._instance.loadFont(filename) def load_pixels(self) -> None: - """Loads the pixel data of the current display window into the ``pixels[]`` array. + """Loads the pixel data of the current display window into the `pixels[]` array. Underlying Processing method: PApplet.loadPixels Notes ----- - Loads the pixel data of the current display window into the ``pixels[]`` array. + Loads the pixel data of the current display window into the `pixels[]` array. This function must always be called before reading from or writing to - ``pixels[]``. Subsequent changes to the display window will not be reflected in - ``pixels[]`` until ``load_pixels()`` is called again. + `pixels[]`. Subsequent changes to the display window will not be reflected in + `pixels[]` until `load_pixels()` is called again. """ return self._instance.loadPixels() @overload def load_shader(self, frag_filename: str, /) -> Py5Shader: - """Loads a shader into a ``Py5Shader`` object. + """Loads a shader into a `Py5Shader` object. Underlying Processing method: PApplet.loadShader @@ -11403,26 +11391,26 @@ def load_shader(self, frag_filename: str, /) -> Py5Shader: Notes ----- - Loads a shader into a ``Py5Shader`` object. The shader file must be located in - the Sketch's "data" directory to load correctly. Shaders are compatible with the - ``P2D`` and ``P3D`` renderers, but not with the default renderer. + Loads a shader into a `Py5Shader` object. The shader file must be located in the + Sketch's "data" directory to load correctly. Shaders are compatible with the + `P2D` and `P3D` renderers, but not with the default renderer. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. """ pass @overload def load_shader(self, frag_filename: str, vert_filename: str, /) -> Py5Shader: - """Loads a shader into a ``Py5Shader`` object. + """Loads a shader into a `Py5Shader` object. Underlying Processing method: PApplet.loadShader @@ -11446,25 +11434,25 @@ def load_shader(self, frag_filename: str, Notes ----- - Loads a shader into a ``Py5Shader`` object. The shader file must be located in - the Sketch's "data" directory to load correctly. Shaders are compatible with the - ``P2D`` and ``P3D`` renderers, but not with the default renderer. + Loads a shader into a `Py5Shader` object. The shader file must be located in the + Sketch's "data" directory to load correctly. Shaders are compatible with the + `P2D` and `P3D` renderers, but not with the default renderer. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. """ pass @_load_py5shader def load_shader(self, *args): - """Loads a shader into a ``Py5Shader`` object. + """Loads a shader into a `Py5Shader` object. Underlying Processing method: PApplet.loadShader @@ -11488,25 +11476,25 @@ def load_shader(self, *args): Notes ----- - Loads a shader into a ``Py5Shader`` object. The shader file must be located in - the Sketch's "data" directory to load correctly. Shaders are compatible with the - ``P2D`` and ``P3D`` renderers, but not with the default renderer. + Loads a shader into a `Py5Shader` object. The shader file must be located in the + Sketch's "data" directory to load correctly. Shaders are compatible with the + `P2D` and `P3D` renderers, but not with the default renderer. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause an error if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause an error if your code does not + check whether the value returned is `None`. """ return self._instance.loadShader(*args) @overload def load_shape(self, filename: str, /) -> Py5Shape: - """Loads geometry into a variable of type ``Py5Shape``. + """Loads geometry into a variable of type `Py5Shape`. Underlying Processing method: PApplet.loadShape @@ -11530,27 +11518,26 @@ def load_shape(self, filename: str, /) -> Py5Shape: Notes ----- - Loads geometry into a variable of type ``Py5Shape``. SVG and OBJ files may be + Loads geometry into a variable of type `Py5Shape`. SVG and OBJ files may be loaded. To load correctly, the file must be located in the data directory of the - current Sketch. In most cases, ``load_shape()`` should be used inside - ``setup()`` because loading shapes inside ``draw()`` will reduce the speed of a - Sketch. + current Sketch. In most cases, `load_shape()` should be used inside `setup()` + because loading shapes inside `draw()` will reduce the speed of a Sketch. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause errors if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause errors if your code does not + check whether the value returned is `None`. """ pass @overload def load_shape(self, filename: str, options: str, /) -> Py5Shape: - """Loads geometry into a variable of type ``Py5Shape``. + """Loads geometry into a variable of type `Py5Shape`. Underlying Processing method: PApplet.loadShape @@ -11574,27 +11561,26 @@ def load_shape(self, filename: str, options: str, /) -> Py5Shape: Notes ----- - Loads geometry into a variable of type ``Py5Shape``. SVG and OBJ files may be + Loads geometry into a variable of type `Py5Shape`. SVG and OBJ files may be loaded. To load correctly, the file must be located in the data directory of the - current Sketch. In most cases, ``load_shape()`` should be used inside - ``setup()`` because loading shapes inside ``draw()`` will reduce the speed of a - Sketch. + current Sketch. In most cases, `load_shape()` should be used inside `setup()` + because loading shapes inside `draw()` will reduce the speed of a Sketch. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause errors if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause errors if your code does not + check whether the value returned is `None`. """ pass @_load_py5shape def load_shape(self, *args): - """Loads geometry into a variable of type ``Py5Shape``. + """Loads geometry into a variable of type `Py5Shape`. Underlying Processing method: PApplet.loadShape @@ -11618,26 +11604,25 @@ def load_shape(self, *args): Notes ----- - Loads geometry into a variable of type ``Py5Shape``. SVG and OBJ files may be + Loads geometry into a variable of type `Py5Shape`. SVG and OBJ files may be loaded. To load correctly, the file must be located in the data directory of the - current Sketch. In most cases, ``load_shape()`` should be used inside - ``setup()`` because loading shapes inside ``draw()`` will reduce the speed of a - Sketch. + current Sketch. In most cases, `load_shape()` should be used inside `setup()` + because loading shapes inside `draw()` will reduce the speed of a Sketch. Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. - If the file is not available or an error occurs, ``None`` will be returned and - an error message will be printed to the console. The error message does not halt - the program, however the ``None`` value may cause errors if your code does not - check whether the value returned is ``None``. + If the file is not available or an error occurs, `None` will be returned and an + error message will be printed to the console. The error message does not halt + the program, however the `None` value may cause errors if your code does not + check whether the value returned is `None`. """ return self._instance.loadShape(*args) def loop(self) -> None: - """By default, py5 loops through ``draw()`` continuously, executing the code within + """By default, py5 loops through `draw()` continuously, executing the code within it. Underlying Processing method: PApplet.loop @@ -11645,9 +11630,9 @@ def loop(self) -> None: Notes ----- - By default, py5 loops through ``draw()`` continuously, executing the code within - it. However, the ``draw()`` loop may be stopped by calling ``no_loop()``. In - that case, the ``draw()`` loop can be resumed with ``loop()``. + By default, py5 loops through `draw()` continuously, executing the code within + it. However, the `draw()` loop may be stopped by calling `no_loop()`. In that + case, the `draw()` loop can be resumed with `loop()`. """ return self._instance.loop() @@ -11675,7 +11660,7 @@ def minute(cls) -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``minute()`` function + Py5 communicates with the clock on your computer. The `minute()` function returns the current minute as a value from 0 - 59. """ return cls._cls.minute() @@ -11706,11 +11691,11 @@ def model_x(self, x: float, y: float, z: float, /) -> float: space relative to the location of the original point once the transformations are no longer in use. - In the example, the ``model_x()``, ``model_y()``, and ``model_z()`` functions - record the location of a box in space after being placed using a series of - translate and rotate commands. After ``pop_matrix()`` is called, those - transformations no longer apply, but the (x, y, z) coordinate returned by the - model functions is used to place another box in the same location. + In the example, the `model_x()`, `model_y()`, and `model_z()` functions record + the location of a box in space after being placed using a series of translate + and rotate commands. After `pop_matrix()` is called, those transformations no + longer apply, but the (x, y, z) coordinate returned by the model functions is + used to place another box in the same location. """ return self._instance.modelX(x, y, z) @@ -11740,11 +11725,11 @@ def model_y(self, x: float, y: float, z: float, /) -> float: space relative to the location of the original point once the transformations are no longer in use. - In the example, the ``model_x()``, ``model_y()``, and ``model_z()`` functions - record the location of a box in space after being placed using a series of - translate and rotate commands. After ``pop_matrix()`` is called, those - transformations no longer apply, but the (x, y, z) coordinate returned by the - model functions is used to place another box in the same location. + In the example, the `model_x()`, `model_y()`, and `model_z()` functions record + the location of a box in space after being placed using a series of translate + and rotate commands. After `pop_matrix()` is called, those transformations no + longer apply, but the (x, y, z) coordinate returned by the model functions is + used to place another box in the same location. """ return self._instance.modelY(x, y, z) @@ -11774,11 +11759,11 @@ def model_z(self, x: float, y: float, z: float, /) -> float: space relative to the location of the original point once the transformations are no longer in use. - In the example, the ``model_x()``, ``model_y()``, and ``model_z()`` functions - record the location of a box in space after being placed using a series of - translate and rotate commands. After ``pop_matrix()`` is called, those - transformations no longer apply, but the (x, y, z) coordinate returned by the - model functions is used to place another box in the same location. + In the example, the `model_x()`, `model_y()`, and `model_z()` functions record + the location of a box in space after being placed using a series of translate + and rotate commands. After `pop_matrix()` is called, those transformations no + longer apply, but the (x, y, z) coordinate returned by the model functions is + used to place another box in the same location. """ return self._instance.modelZ(x, y, z) @@ -11791,20 +11776,20 @@ def month(cls) -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``month()`` function - returns the current month as a value from 1 - 12. + Py5 communicates with the clock on your computer. The `month()` function returns + the current month as a value from 1 - 12. """ return cls._cls.month() def no_clip(self) -> None: - """Disables the clipping previously started by the ``clip()`` function. + """Disables the clipping previously started by the `clip()` function. Underlying Processing method: PApplet.noClip Notes ----- - Disables the clipping previously started by the ``clip()`` function. + Disables the clipping previously started by the `clip()` function. """ return self._instance.noClip() @@ -11829,7 +11814,7 @@ def no_fill(self) -> None: Notes ----- - Disables filling geometry. If both ``no_stroke()`` and ``no_fill()`` are called, + Disables filling geometry. If both `no_stroke()` and `no_fill()` are called, nothing will be drawn to the screen. """ return self._instance.noFill() @@ -11843,34 +11828,34 @@ def no_lights(self) -> None: ----- Disable all lighting. Lighting is turned off by default and enabled with the - ``lights()`` function. This function can be used to disable lighting so that 2D + `lights()` function. This function can be used to disable lighting so that 2D geometry (which does not require lighting) can be drawn after a set of lighted 3D geometry. """ return self._instance.noLights() def no_loop(self) -> None: - """Stops py5 from continuously executing the code within ``draw()``. + """Stops py5 from continuously executing the code within `draw()`. Underlying Processing method: PApplet.noLoop Notes ----- - Stops py5 from continuously executing the code within ``draw()``. If ``loop()`` - is called, the code in ``draw()`` begins to run continuously again. If using - ``no_loop()`` in ``setup()``, it should be the last line inside the block. + Stops py5 from continuously executing the code within `draw()`. If `loop()` is + called, the code in `draw()` begins to run continuously again. If using + `no_loop()` in `setup()`, it should be the last line inside the block. - When ``no_loop()`` is used, it's not possible to manipulate or access the screen - inside event handling functions such as ``mouse_pressed()`` or - ``key_pressed()``. Instead, use those functions to call ``redraw()`` or - ``loop()``, which will run ``draw()``, which can update the screen properly. - This means that when ``no_loop()`` has been called, no drawing can happen, and - functions like ``save_frame()`` or ``load_pixels()`` may not be used. + When `no_loop()` is used, it's not possible to manipulate or access the screen + inside event handling functions such as `mouse_pressed()` or `key_pressed()`. + Instead, use those functions to call `redraw()` or `loop()`, which will run + `draw()`, which can update the screen properly. This means that when `no_loop()` + has been called, no drawing can happen, and functions like `save_frame()` or + `load_pixels()` may not be used. - Note that if the Sketch is resized, ``redraw()`` will be called to update the - Sketch, even after ``no_loop()`` has been specified. Otherwise, the Sketch would - enter an odd state until ``loop()`` was called. + Note that if the Sketch is resized, `redraw()` will be called to update the + Sketch, even after `no_loop()` has been specified. Otherwise, the Sketch would + enter an odd state until `loop()` was called. """ return self._instance.noLoop() @@ -11886,24 +11871,24 @@ def no_smooth(self) -> None: Draws all geometry and fonts with jagged (aliased) edges and images with hard edges between the pixels when enlarged rather than interpolating pixels. Note - that ``smooth()`` is active by default, so it is necessary to call - ``no_smooth()`` to disable smoothing of geometry, fonts, and images. + that `smooth()` is active by default, so it is necessary to call `no_smooth()` + to disable smoothing of geometry, fonts, and images. - The ``no_smooth()`` function can only be called once within a Sketch. It is - intended to be called from the ``settings()`` function. The ``smooth()`` - function follows the same rules. + The `no_smooth()` function can only be called once within a Sketch. It is + intended to be called from the `settings()` function. The `smooth()` function + follows the same rules. When programming in module mode and imported mode, py5 will allow calls to - ``no_smooth()`` from the ``setup()`` function if it is called at the beginning - of ``setup()``. This allows the user to omit the ``settings()`` function, much - like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``no_smooth()``, or calls - to ``size()``, ``full_screen()``, ``smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. + `no_smooth()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `no_smooth()`, or calls to + `size()`, `full_screen()`, `smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. """ return self._instance.noSmooth() @@ -11915,8 +11900,8 @@ def no_stroke(self) -> None: Notes ----- - Disables drawing the stroke (outline). If both ``no_stroke()`` and ``no_fill()`` - are called, nothing will be drawn to the screen. + Disables drawing the stroke (outline). If both `no_stroke()` and `no_fill()` are + called, nothing will be drawn to the screen. """ return self._instance.noStroke() @@ -11937,7 +11922,7 @@ def no_tint(self) -> None: @overload def noise_detail(self, lod: int, /) -> None: """Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. + produced by the `noise()` function. Underlying Processing method: PApplet.noiseDetail @@ -11962,20 +11947,20 @@ def noise_detail(self, lod: int, /) -> None: ----- Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. Similar to harmonics in physics, - Processing noise is computed over several octaves. Lower octaves contribute more - to the output signal and as such define the overall intensity of the noise, - whereas higher octaves create finer-grained details in the noise sequence. + produced by the `noise()` function. Similar to harmonics in physics, Processing + noise is computed over several octaves. Lower octaves contribute more to the + output signal and as such define the overall intensity of the noise, whereas + higher octaves create finer-grained details in the noise sequence. By default, noise is computed over 4 octaves with each octave contributing exactly half than its predecessor, starting at 50% strength for the first octave. This falloff amount can be changed by adding an additional function - parameter. For example, a ``falloff`` factor of 0.75 means each octave will now + parameter. For example, a `falloff` factor of 0.75 means each octave will now have 75% impact (25% less) of the previous lower octave. While any number between 0.0 and 1.0 is valid, note that values greater than 0.5 may result in noise() returning values greater than 1.0 or less than 0.0. - By changing these parameters, the signal created by the ``noise()`` function can + By changing these parameters, the signal created by the `noise()` function can be adapted to fit very specific needs and characteristics. """ pass @@ -11983,7 +11968,7 @@ def noise_detail(self, lod: int, /) -> None: @overload def noise_detail(self, lod: int, falloff: float, /) -> None: """Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. + produced by the `noise()` function. Underlying Processing method: PApplet.noiseDetail @@ -12008,27 +11993,27 @@ def noise_detail(self, lod: int, falloff: float, /) -> None: ----- Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. Similar to harmonics in physics, - Processing noise is computed over several octaves. Lower octaves contribute more - to the output signal and as such define the overall intensity of the noise, - whereas higher octaves create finer-grained details in the noise sequence. + produced by the `noise()` function. Similar to harmonics in physics, Processing + noise is computed over several octaves. Lower octaves contribute more to the + output signal and as such define the overall intensity of the noise, whereas + higher octaves create finer-grained details in the noise sequence. By default, noise is computed over 4 octaves with each octave contributing exactly half than its predecessor, starting at 50% strength for the first octave. This falloff amount can be changed by adding an additional function - parameter. For example, a ``falloff`` factor of 0.75 means each octave will now + parameter. For example, a `falloff` factor of 0.75 means each octave will now have 75% impact (25% less) of the previous lower octave. While any number between 0.0 and 1.0 is valid, note that values greater than 0.5 may result in noise() returning values greater than 1.0 or less than 0.0. - By changing these parameters, the signal created by the ``noise()`` function can + By changing these parameters, the signal created by the `noise()` function can be adapted to fit very specific needs and characteristics. """ pass def noise_detail(self, *args): """Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. + produced by the `noise()` function. Underlying Processing method: PApplet.noiseDetail @@ -12053,26 +12038,26 @@ def noise_detail(self, *args): ----- Adjusts the character and level of detail of Processing's noise algorithm, - produced by the ``noise()`` function. Similar to harmonics in physics, - Processing noise is computed over several octaves. Lower octaves contribute more - to the output signal and as such define the overall intensity of the noise, - whereas higher octaves create finer-grained details in the noise sequence. + produced by the `noise()` function. Similar to harmonics in physics, Processing + noise is computed over several octaves. Lower octaves contribute more to the + output signal and as such define the overall intensity of the noise, whereas + higher octaves create finer-grained details in the noise sequence. By default, noise is computed over 4 octaves with each octave contributing exactly half than its predecessor, starting at 50% strength for the first octave. This falloff amount can be changed by adding an additional function - parameter. For example, a ``falloff`` factor of 0.75 means each octave will now + parameter. For example, a `falloff` factor of 0.75 means each octave will now have 75% impact (25% less) of the previous lower octave. While any number between 0.0 and 1.0 is valid, note that values greater than 0.5 may result in noise() returning values greater than 1.0 or less than 0.0. - By changing these parameters, the signal created by the ``noise()`` function can + By changing these parameters, the signal created by the `noise()` function can be adapted to fit very specific needs and characteristics. """ return self._instance.noiseDetail(*args) def noise_seed(self, seed: int, /) -> None: - """Sets the seed value for ``noise()``. + """Sets the seed value for `noise()`. Underlying Processing method: PApplet.noiseSeed @@ -12085,7 +12070,7 @@ def noise_seed(self, seed: int, /) -> None: Notes ----- - Sets the seed value for ``noise()``. By default, ``noise()`` produces different + Sets the seed value for `noise()`. By default, `noise()` produces different results each time the program is run. Set the seed parameter to a constant to return the same pseudo-random numbers each time the Sketch is run. """ @@ -12112,11 +12097,11 @@ def normal(self, nx: float, ny: float, nz: float, /) -> None: ----- Sets the current normal vector. Used for drawing three dimensional shapes and - surfaces, ``normal()`` specifies a vector perpendicular to a shape's surface + surfaces, `normal()` specifies a vector perpendicular to a shape's surface which, in turn, determines how lighting affects it. Py5 attempts to automatically assign normals to shapes, but since that's imperfect, this is a better option when you want more control. This function is identical to - ``gl_normal3f()`` in OpenGL. + `gl_normal3f()` in OpenGL. """ return self._instance.normal(nx, ny, nz) @@ -12165,7 +12150,7 @@ def ortho(self) -> None: clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. """ pass @@ -12215,7 +12200,7 @@ def ortho(self, left: float, right: float, clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. """ pass @@ -12265,7 +12250,7 @@ def ortho(self, left: float, right: float, bottom: float, clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. """ pass @@ -12313,12 +12298,12 @@ def ortho(self, *args): clipping volume where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values. If no parameters are given, the default is used: - ``ortho(-width/2, width/2, -height/2, height/2)``. + `ortho(-width/2, width/2, -height/2, height/2)`. """ return self._instance.ortho(*args) def os_noise_seed(self, seed: int, /) -> None: - """Sets the seed value for ``os_noise()``. + """Sets the seed value for `os_noise()`. Parameters ---------- @@ -12329,7 +12314,7 @@ def os_noise_seed(self, seed: int, /) -> None: Notes ----- - Sets the seed value for ``os_noise()``. By default, ``os_noise()`` produces + Sets the seed value for `os_noise()`. By default, `os_noise()` produces different results each time the program is run. Set the seed parameter to a constant to return the same pseudo-random numbers each time the Sketch is run. """ @@ -12375,8 +12360,8 @@ def perspective(self) -> None: perspective of the world more accurately than orthographic projection. The version of perspective without parameters sets the default perspective and the version with four parameters allows the programmer to set the area precisely. - The default values are: ``perspective(PI/3.0, width/height, cameraZ/10.0, - cameraZ*10.0)`` where cameraZ is ``((height/2.0) / tan(PI*60.0/360.0))``. + The default values are: `perspective(PI/3.0, width/height, cameraZ/10.0, + cameraZ*10.0)` where cameraZ is `((height/2.0) / tan(PI*60.0/360.0))`. """ pass @@ -12421,8 +12406,8 @@ def perspective(self, fovy: float, aspect: float, perspective of the world more accurately than orthographic projection. The version of perspective without parameters sets the default perspective and the version with four parameters allows the programmer to set the area precisely. - The default values are: ``perspective(PI/3.0, width/height, cameraZ/10.0, - cameraZ*10.0)`` where cameraZ is ``((height/2.0) / tan(PI*60.0/360.0))``. + The default values are: `perspective(PI/3.0, width/height, cameraZ/10.0, + cameraZ*10.0)` where cameraZ is `((height/2.0) / tan(PI*60.0/360.0))`. """ pass @@ -12465,8 +12450,8 @@ def perspective(self, *args): perspective of the world more accurately than orthographic projection. The version of perspective without parameters sets the default perspective and the version with four parameters allows the programmer to set the area precisely. - The default values are: ``perspective(PI/3.0, width/height, cameraZ/10.0, - cameraZ*10.0)`` where cameraZ is ``((height/2.0) / tan(PI*60.0/360.0))``. + The default values are: `perspective(PI/3.0, width/height, cameraZ/10.0, + cameraZ*10.0)` where cameraZ is `((height/2.0) / tan(PI*60.0/360.0))`. """ return self._instance.perspective(*args) @@ -12490,28 +12475,28 @@ def pixel_density(self, density: int, /) -> None: This function makes it possible for py5 to render using all of the pixels on high resolutions screens like Apple Retina displays and Windows High-DPI displays. This function can only be run once within a program. It is intended to - be called from the ``settings()`` function. + be called from the `settings()` function. When programming in module mode and imported mode, py5 will allow calls to - ``pixel_density()`` from the ``setup()`` function if it is called at the - beginning of ``setup()``. This allows the user to omit the ``settings()`` - function, much like what can be done while programming in the Processing IDE. - Py5 does this by inspecting the ``setup()`` function and attempting to split it - into synthetic ``settings()`` and ``setup()`` functions if both were not created - by the user and the real ``setup()`` function contains a call to - ``pixel_density()``, or calls to ``size()``, ``full_screen()``, ``smooth()``, or - ``no_smooth()``. Calls to those functions must be at the very beginning of - ``setup()``, before any other Python code (but comments are ok). This feature is - not available when programming in class mode. - - The ``pixel_density()`` should only be used with hardcoded numbers (in almost - all cases this number will be 2) or in combination with ``display_density()`` as - in the second example. + `pixel_density()` from the `setup()` function if it is called at the beginning + of `setup()`. This allows the user to omit the `settings()` function, much like + what can be done while programming in the Processing IDE. Py5 does this by + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `pixel_density()`, or calls to + `size()`, `full_screen()`, `smooth()`, or `no_smooth()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + The `pixel_density()` should only be used with hardcoded numbers (in almost all + cases this number will be 2) or in combination with `display_density()` as in + the second example. When the pixel density is set to more than 1, it changes all of the pixel - operations including the way ``get()``, ``blend()``, ``copy()``, - ``update_pixels()``, and ``update_np_pixels()`` all work. See the reference for - ``pixel_width`` and ``pixel_height`` for more information. + operations including the way `get_pixels()`, `set_pixels()`, `blend()`, + `copy()`, `update_pixels()`, and `update_np_pixels()` all work. See the + reference for `pixel_width` and `pixel_height` for more information. """ return self._instance.pixelDensity(density) @@ -12547,19 +12532,18 @@ def point(self, x: float, y: float, /) -> None: Draws a point, a coordinate in space at the dimension of one pixel. The first parameter is the horizontal value for the point, the second value is the vertical value for the point, and the optional third value is the depth value. - Drawing this shape in 3D with the ``z`` parameter requires the ``P3D`` parameter - in combination with ``size()`` as shown in the second example. + Drawing this shape in 3D with the `z` parameter requires the `P3D` parameter in + combination with `size()` as shown in the second example. - Use ``stroke()`` to set the color of a ``point()``. + Use `stroke()` to set the color of a `point()`. - Point appears round with the default ``stroke_cap(ROUND)`` and square with - ``stroke_cap(PROJECT)``. Points are invisible with ``stroke_cap(SQUARE)`` (no - cap). + Point appears round with the default `stroke_cap(ROUND)` and square with + `stroke_cap(PROJECT)`. Points are invisible with `stroke_cap(SQUARE)` (no cap). - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the screen, depending on the graphics settings of the computer. Workarounds include - setting the pixel using the ``pixels[]`` or ``np_pixels[]`` arrays or drawing - the point using either ``circle()`` or ``square()``. + setting the pixel using the `pixels[]` or `np_pixels[]` arrays or drawing the + point using either `circle()` or `square()`. """ pass @@ -12595,19 +12579,18 @@ def point(self, x: float, y: float, z: float, /) -> None: Draws a point, a coordinate in space at the dimension of one pixel. The first parameter is the horizontal value for the point, the second value is the vertical value for the point, and the optional third value is the depth value. - Drawing this shape in 3D with the ``z`` parameter requires the ``P3D`` parameter - in combination with ``size()`` as shown in the second example. + Drawing this shape in 3D with the `z` parameter requires the `P3D` parameter in + combination with `size()` as shown in the second example. - Use ``stroke()`` to set the color of a ``point()``. + Use `stroke()` to set the color of a `point()`. - Point appears round with the default ``stroke_cap(ROUND)`` and square with - ``stroke_cap(PROJECT)``. Points are invisible with ``stroke_cap(SQUARE)`` (no - cap). + Point appears round with the default `stroke_cap(ROUND)` and square with + `stroke_cap(PROJECT)`. Points are invisible with `stroke_cap(SQUARE)` (no cap). - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the screen, depending on the graphics settings of the computer. Workarounds include - setting the pixel using the ``pixels[]`` or ``np_pixels[]`` arrays or drawing - the point using either ``circle()`` or ``square()``. + setting the pixel using the `pixels[]` or `np_pixels[]` arrays or drawing the + point using either `circle()` or `square()`. """ pass @@ -12642,19 +12625,18 @@ def point(self, *args): Draws a point, a coordinate in space at the dimension of one pixel. The first parameter is the horizontal value for the point, the second value is the vertical value for the point, and the optional third value is the depth value. - Drawing this shape in 3D with the ``z`` parameter requires the ``P3D`` parameter - in combination with ``size()`` as shown in the second example. + Drawing this shape in 3D with the `z` parameter requires the `P3D` parameter in + combination with `size()` as shown in the second example. - Use ``stroke()`` to set the color of a ``point()``. + Use `stroke()` to set the color of a `point()`. - Point appears round with the default ``stroke_cap(ROUND)`` and square with - ``stroke_cap(PROJECT)``. Points are invisible with ``stroke_cap(SQUARE)`` (no - cap). + Point appears round with the default `stroke_cap(ROUND)` and square with + `stroke_cap(PROJECT)`. Points are invisible with `stroke_cap(SQUARE)` (no cap). - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the screen, depending on the graphics settings of the computer. Workarounds include - setting the pixel using the ``pixels[]`` or ``np_pixels[]`` arrays or drawing - the point using either ``circle()`` or ``square()``. + setting the pixel using the `pixels[]` or `np_pixels[]` arrays or drawing the + point using either `circle()` or `square()`. """ return self._instance.point(*args) @@ -12688,15 +12670,16 @@ def point_light(self, v1: float, v2: float, v3: float, Notes ----- - Adds a point light. Lights need to be included in the ``draw()`` to remain - persistent in a looping program. Placing them in the ``setup()`` of a looping + Adds a point light. Lights need to be included in the `draw()` to remain + persistent in a looping program. Placing them in the `setup()` of a looping program will cause them to only have an effect the first time through the loop. - The ``v1``, ``v2``, and ``v3`` parameters are interpreted as either RGB or HSB - values, depending on the current color mode. The ``x``, ``y``, and ``z`` - parameters set the position of the light. + The `v1`, `v2`, and `v3` parameters are interpreted as either RGB or HSB values, + depending on the current color mode. The `x`, `y`, and `z` parameters set the + position of the light. """ return self._instance.pointLight(v1, v2, v3, x, y, z) + @_generator_to_list def points(self, coordinates: npt.NDArray[np.floating], /) -> None: """Draw a collection of points, each a coordinate in space at the dimension of one pixel. @@ -12714,40 +12697,40 @@ def points(self, coordinates: npt.NDArray[np.floating], /) -> None: Draw a collection of points, each a coordinate in space at the dimension of one pixel. The purpose of this method is to provide an alternative to repeatedly - calling ``point()`` in a loop. For a large number of points, the performance of - ``points()`` will be much faster. + calling `point()` in a loop. For a large number of points, the performance of + `points()` will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each - point. There should be two or three columns for 2D or 3D points, respectively. + The `coordinates` parameter should be a numpy array with one row for each point. + There should be two or three columns for 2D or 3D points, respectively. """ return self._instance.points(coordinates) def pop(self) -> None: - """The ``pop()`` function restores the previous drawing style settings and - transformations after ``push()`` has changed them. + """The `pop()` function restores the previous drawing style settings and + transformations after `push()` has changed them. Underlying Processing method: PApplet.pop Notes ----- - The ``pop()`` function restores the previous drawing style settings and - transformations after ``push()`` has changed them. Note that these functions are + The `pop()` function restores the previous drawing style settings and + transformations after `push()` has changed them. Note that these functions are always used together. They allow you to change the style and transformation settings and later return to what you had. When a new state is started with - ``push()``, it builds on the current style and transform information. + `push()`, it builds on the current style and transform information. - ``push()`` stores information related to the current transformation state and - style settings controlled by the following functions: ``rotate()``, - ``translate()``, ``scale()``, ``fill()``, ``stroke()``, ``tint()``, - ``stroke_weight()``, ``stroke_cap()``, ``stroke_join()``, ``image_mode()``, - ``rect_mode()``, ``ellipse_mode()``, ``color_mode()``, ``text_align()``, - ``text_font()``, ``text_mode()``, ``text_size()``, and ``text_leading()``. + `push()` stores information related to the current transformation state and + style settings controlled by the following functions: `rotate()`, `translate()`, + `scale()`, `fill()`, `stroke()`, `tint()`, `stroke_weight()`, `stroke_cap()`, + `stroke_join()`, `image_mode()`, `rect_mode()`, `ellipse_mode()`, + `color_mode()`, `text_align()`, `text_font()`, `text_mode()`, `text_size()`, and + `text_leading()`. - The ``push()`` and ``pop()`` functions can be used in place of - ``push_matrix()``, ``pop_matrix()``, ``push_style()``, and ``pop_style()``. The - difference is that ``push()`` and ``pop()`` control both the transformations - (rotate, scale, translate) and the drawing styles at the same time. + The `push()` and `pop()` functions can be used in place of `push_matrix()`, + `pop_matrix()`, `push_style()`, and `pop_style()`. The difference is that + `push()` and `pop()` control both the transformations (rotate, scale, translate) + and the drawing styles at the same time. """ return self._instance.pop() @@ -12761,30 +12744,28 @@ def pop_matrix(self) -> None: Pops the current transformation matrix off the matrix stack. Understanding pushing and popping requires understanding the concept of a matrix stack. The - ``push_matrix()`` function saves the current coordinate system to the stack and - ``pop_matrix()`` restores the prior coordinate system. ``push_matrix()`` and - ``pop_matrix()`` are used in conjuction with the other transformation functions + `push_matrix()` function saves the current coordinate system to the stack and + `pop_matrix()` restores the prior coordinate system. `push_matrix()` and + `pop_matrix()` are used in conjuction with the other transformation functions and may be embedded to control the scope of the transformations. """ return self._instance.popMatrix() def pop_style(self) -> None: - """The ``push_style()`` function saves the current style settings and - ``pop_style()`` restores the prior settings; these functions are always used - together. + """The `push_style()` function saves the current style settings and `pop_style()` + restores the prior settings; these functions are always used together. Underlying Processing method: PApplet.popStyle Notes ----- - The ``push_style()`` function saves the current style settings and - ``pop_style()`` restores the prior settings; these functions are always used - together. They allow you to change the style settings and later return to what - you had. When a new style is started with ``push_style()``, it builds on the - current style information. The ``push_style()`` and ``pop_style()`` method pairs - can be nested to provide more control (see the second example for a - demonstration.) + The `push_style()` function saves the current style settings and `pop_style()` + restores the prior settings; these functions are always used together. They + allow you to change the style settings and later return to what you had. When a + new style is started with `push_style()`, it builds on the current style + information. The `push_style()` and `pop_style()` method pairs can be nested to + provide more control (see the second example for a demonstration.) """ return self._instance.popStyle() @@ -12826,35 +12807,34 @@ def print_projection(self) -> None: @_context_wrapper('pop') def push(self) -> None: - """The ``push()`` function saves the current drawing style settings and - transformations, while ``pop()`` restores these settings. + """The `push()` function saves the current drawing style settings and + transformations, while `pop()` restores these settings. Underlying Processing method: PApplet.push Notes ----- - The ``push()`` function saves the current drawing style settings and - transformations, while ``pop()`` restores these settings. Note that these + The `push()` function saves the current drawing style settings and + transformations, while `pop()` restores these settings. Note that these functions are always used together. They allow you to change the style and transformation settings and later return to what you had. When a new state is - started with ``push()``, it builds on the current style and transform - information. - - ``push()`` stores information related to the current transformation state and - style settings controlled by the following functions: ``rotate()``, - ``translate()``, ``scale()``, ``fill()``, ``stroke()``, ``tint()``, - ``stroke_weight()``, ``stroke_cap()``, ``stroke_join()``, ``image_mode()``, - ``rect_mode()``, ``ellipse_mode()``, ``color_mode()``, ``text_align()``, - ``text_font()``, ``text_mode()``, ``text_size()``, and ``text_leading()``. - - The ``push()`` and ``pop()`` functions can be used in place of - ``push_matrix()``, ``pop_matrix()``, ``push_style()``, and ``pop_style()``. The - difference is that ``push()`` and ``pop()`` control both the transformations - (rotate, scale, translate) and the drawing styles at the same time. - - This method can be used as a context manager to ensure that ``pop()`` always - gets called, as shown in the last example. + started with `push()`, it builds on the current style and transform information. + + `push()` stores information related to the current transformation state and + style settings controlled by the following functions: `rotate()`, `translate()`, + `scale()`, `fill()`, `stroke()`, `tint()`, `stroke_weight()`, `stroke_cap()`, + `stroke_join()`, `image_mode()`, `rect_mode()`, `ellipse_mode()`, + `color_mode()`, `text_align()`, `text_font()`, `text_mode()`, `text_size()`, and + `text_leading()`. + + The `push()` and `pop()` functions can be used in place of `push_matrix()`, + `pop_matrix()`, `push_style()`, and `pop_style()`. The difference is that + `push()` and `pop()` control both the transformations (rotate, scale, translate) + and the drawing styles at the same time. + + This method can be used as a context manager to ensure that `pop()` always gets + called, as shown in the last example. """ return self._instance.push() @@ -12868,45 +12848,44 @@ def push_matrix(self) -> None: ----- Pushes the current transformation matrix onto the matrix stack. Understanding - ``push_matrix()`` and ``pop_matrix()`` requires understanding the concept of a - matrix stack. The ``push_matrix()`` function saves the current coordinate system - to the stack and ``pop_matrix()`` restores the prior coordinate system. - ``push_matrix()`` and ``pop_matrix()`` are used in conjuction with the other + `push_matrix()` and `pop_matrix()` requires understanding the concept of a + matrix stack. The `push_matrix()` function saves the current coordinate system + to the stack and `pop_matrix()` restores the prior coordinate system. + `push_matrix()` and `pop_matrix()` are used in conjuction with the other transformation functions and may be embedded to control the scope of the transformations. - This method can be used as a context manager to ensure that ``pop_matrix()`` + This method can be used as a context manager to ensure that `pop_matrix()` always gets called, as shown in the last example. """ return self._instance.pushMatrix() @_context_wrapper('pop_style') def push_style(self) -> None: - """The ``push_style()`` function saves the current style settings and - ``pop_style()`` restores the prior settings. + """The `push_style()` function saves the current style settings and `pop_style()` + restores the prior settings. Underlying Processing method: PApplet.pushStyle Notes ----- - The ``push_style()`` function saves the current style settings and - ``pop_style()`` restores the prior settings. Note that these functions are - always used together. They allow you to change the style settings and later - return to what you had. When a new style is started with ``push_style()``, it - builds on the current style information. The ``push_style()`` and - ``pop_style()`` method pairs can be nested to provide more control. (See the - second example for a demonstration.) + The `push_style()` function saves the current style settings and `pop_style()` + restores the prior settings. Note that these functions are always used together. + They allow you to change the style settings and later return to what you had. + When a new style is started with `push_style()`, it builds on the current style + information. The `push_style()` and `pop_style()` method pairs can be nested to + provide more control. (See the second example for a demonstration.) The style information controlled by the following functions are included in the - style: ``fill()``, ``stroke()``, ``tint()``, ``stroke_weight()``, - ``stroke_cap()``, ``stroke_join()``, ``image_mode()``, ``rect_mode()``, - ``ellipse_mode()``, ``shape_mode()``, ``color_mode()``, ``text_align()``, - ``text_font()``, ``text_mode()``, ``text_size()``, ``text_leading()``, - ``emissive()``, ``specular()``, ``shininess()``, and ``ambient()``. + style: `fill()`, `stroke()`, `tint()`, `stroke_weight()`, `stroke_cap()`, + `stroke_join()`, `image_mode()`, `rect_mode()`, `ellipse_mode()`, + `shape_mode()`, `color_mode()`, `text_align()`, `text_font()`, `text_mode()`, + `text_size()`, `text_leading()`, `emissive()`, `specular()`, `shininess()`, and + `ambient()`. - This method can be used as a context manager to ensure that ``pop_style()`` - always gets called, as shown in the last example. + This method can be used as a context manager to ensure that `pop_style()` always + gets called, as shown in the last example. """ return self._instance.pushStyle() @@ -12993,13 +12972,13 @@ def quadratic_vertex(self, cx: float, cy: float, ----- Specifies vertex coordinates for quadratic Bezier curves. Each call to - ``quadratic_vertex()`` defines the position of one control point and one anchor + `quadratic_vertex()` defines the position of one control point and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time - ``quadratic_vertex()`` is used within a ``begin_shape()`` call, it must be - prefaced with a call to ``vertex()`` to set the first anchor point. This method - must be used between ``begin_shape()`` and ``end_shape()`` and only when there - is no ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version - requires rendering with ``P3D``. + `quadratic_vertex()` is used within a `begin_shape()` call, it must be prefaced + with a call to `vertex()` to set the first anchor point. This method must be + used between `begin_shape()` and `end_shape()` and only when there is no `MODE` + parameter specified to `begin_shape()`. Using the 3D version requires rendering + with `P3D`. """ pass @@ -13043,13 +13022,13 @@ def quadratic_vertex(self, cx: float, cy: float, cz: float, ----- Specifies vertex coordinates for quadratic Bezier curves. Each call to - ``quadratic_vertex()`` defines the position of one control point and one anchor + `quadratic_vertex()` defines the position of one control point and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time - ``quadratic_vertex()`` is used within a ``begin_shape()`` call, it must be - prefaced with a call to ``vertex()`` to set the first anchor point. This method - must be used between ``begin_shape()`` and ``end_shape()`` and only when there - is no ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version - requires rendering with ``P3D``. + `quadratic_vertex()` is used within a `begin_shape()` call, it must be prefaced + with a call to `vertex()` to set the first anchor point. This method must be + used between `begin_shape()` and `end_shape()` and only when there is no `MODE` + parameter specified to `begin_shape()`. Using the 3D version requires rendering + with `P3D`. """ pass @@ -13091,16 +13070,17 @@ def quadratic_vertex(self, *args): ----- Specifies vertex coordinates for quadratic Bezier curves. Each call to - ``quadratic_vertex()`` defines the position of one control point and one anchor + `quadratic_vertex()` defines the position of one control point and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time - ``quadratic_vertex()`` is used within a ``begin_shape()`` call, it must be - prefaced with a call to ``vertex()`` to set the first anchor point. This method - must be used between ``begin_shape()`` and ``end_shape()`` and only when there - is no ``MODE`` parameter specified to ``begin_shape()``. Using the 3D version - requires rendering with ``P3D``. + `quadratic_vertex()` is used within a `begin_shape()` call, it must be prefaced + with a call to `vertex()` to set the first anchor point. This method must be + used between `begin_shape()` and `end_shape()` and only when there is no `MODE` + parameter specified to `begin_shape()`. Using the 3D version requires rendering + with `P3D`. """ return self._instance.quadraticVertex(*args) + @_generator_to_list def quadratic_vertices( self, coordinates: npt.NDArray[np.floating], /) -> None: """Create a collection of quadratic vertices. @@ -13117,11 +13097,11 @@ def quadratic_vertices( ----- Create a collection of quadratic vertices. The purpose of this method is to - provide an alternative to repeatedly calling ``quadratic_vertex()`` in a loop. - For a large number of quadratic vertices, the performance of - ``quadratic_vertices()`` will be much faster. + provide an alternative to repeatedly calling `quadratic_vertex()` in a loop. For + a large number of quadratic vertices, the performance of `quadratic_vertices()` + will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each + The `coordinates` parameter should be a numpy array with one row for each quadratic vertex. The first few columns are for the control point and the next few columns are for the anchor point. There should be four or six columns for 2D or 3D points, respectively. @@ -13180,7 +13160,7 @@ def rect(self, a: float, b: float, c: float, d: float, /) -> None: angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, however, may be changed with - the ``rect_mode()`` function. + the `rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -13245,7 +13225,7 @@ def rect(self, a: float, b: float, c: float, angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, however, may be changed with - the ``rect_mode()`` function. + the `rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -13310,7 +13290,7 @@ def rect(self, a: float, b: float, c: float, d: float, angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, however, may be changed with - the ``rect_mode()`` function. + the `rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -13373,7 +13353,7 @@ def rect(self, *args): angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, however, may be changed with - the ``rect_mode()`` function. + the `rect_mode()` function. To draw a rounded rectangle, add a fifth parameter, which is used as the radius value for all four corners. @@ -13387,7 +13367,7 @@ def rect(self, *args): def rect_mode(self, mode: int, /) -> None: """Modifies the location from which rectangles are drawn by changing the way in - which parameters given to ``rect()`` are intepreted. + which parameters given to `rect()` are intepreted. Underlying Processing method: PApplet.rectMode @@ -13401,21 +13381,21 @@ def rect_mode(self, mode: int, /) -> None: ----- Modifies the location from which rectangles are drawn by changing the way in - which parameters given to ``rect()`` are intepreted. + which parameters given to `rect()` are intepreted. - The default mode is ``rect_mode(CORNER)``, which interprets the first two - parameters of ``rect()`` as the upper-left corner of the shape, while the third + The default mode is `rect_mode(CORNER)`, which interprets the first two + parameters of `rect()` as the upper-left corner of the shape, while the third and fourth parameters are its width and height. - ``rect_mode(CORNERS)`` interprets the first two parameters of ``rect()`` as the + `rect_mode(CORNERS)` interprets the first two parameters of `rect()` as the location of one corner, and the third and fourth parameters as the location of the opposite corner. - ``rect_mode(CENTER)`` interprets the first two parameters of ``rect()`` as the + `rect_mode(CENTER)` interprets the first two parameters of `rect()` as the shape's center point, while the third and fourth parameters are its width and height. - ``rect_mode(RADIUS)`` also uses the first two parameters of ``rect()`` as the + `rect_mode(RADIUS)` also uses the first two parameters of `rect()` as the shape's center point, but uses the third and fourth parameters to specify half of the shapes's width and height. @@ -13426,7 +13406,7 @@ def rect_mode(self, mode: int, /) -> None: @_convert_hex_color() def red(self, rgb: int, /) -> float: - """Extracts the red value from a color, scaled to match current ``color_mode()``. + """Extracts the red value from a color, scaled to match current `color_mode()`. Underlying Processing method: PApplet.red @@ -13439,35 +13419,35 @@ def red(self, rgb: int, /) -> float: Notes ----- - Extracts the red value from a color, scaled to match current ``color_mode()``. + Extracts the red value from a color, scaled to match current `color_mode()`. - The ``red()`` function is easy to use and understand, but it is slower than a - technique called bit shifting. When working in ``color_mode(RGB, 255)``, you can - achieve the same results as ``red()`` but with greater speed by using the right - shift operator (``>>``) with a bit mask. For example, ``red(c)`` and ``c >> 16 & - 0xFF`` both extract the red value from a color variable ``c`` but the later is + The `red()` function is easy to use and understand, but it is slower than a + technique called bit shifting. When working in `color_mode(RGB, 255)`, you can + achieve the same results as `red()` but with greater speed by using the right + shift operator (`>>`) with a bit mask. For example, `red(c)` and `c >> 16 & + 0xFF` both extract the red value from a color variable `c` but the later is faster. """ return self._instance.red(rgb) def redraw(self) -> None: - """Executes the code within ``draw()`` one time. + """Executes the code within `draw()` one time. Underlying Processing method: PApplet.redraw Notes ----- - Executes the code within ``draw()`` one time. This functions allows the program - to update the display window only when necessary, for example when an event - registered by ``mouse_pressed()`` or ``key_pressed()`` occurs. + Executes the code within `draw()` one time. This functions allows the program to + update the display window only when necessary, for example when an event + registered by `mouse_pressed()` or `key_pressed()` occurs. - In structuring a program, it only makes sense to call ``redraw()`` within events - such as ``mouse_pressed()``. This is because ``redraw()`` does not run - ``draw()`` immediately (it only sets a flag that indicates an update is needed). + In structuring a program, it only makes sense to call `redraw()` within events + such as `mouse_pressed()`. This is because `redraw()` does not run `draw()` + immediately (it only sets a flag that indicates an update is needed). - The ``redraw()`` function does not work properly when called inside ``draw()``. - To enable/disable animations, use ``loop()`` and ``no_loop()``. + The `redraw()` function does not work properly when called inside `draw()`. To + enable/disable animations, use `loop()` and `no_loop()`. """ return self._instance.redraw() @@ -13480,7 +13460,7 @@ def reset_matrix(self) -> None: ----- Replaces the current matrix with the identity matrix. The equivalent function in - OpenGL is ``gl_load_identity()``. + OpenGL is `gl_load_identity()`. """ return self._instance.resetMatrix() @@ -13507,8 +13487,8 @@ def reset_shader(self) -> None: Notes ----- - Restores the default shaders. Code that runs after ``reset_shader()`` will not - be affected by previously defined shaders. + Restores the default shaders. Code that runs after `reset_shader()` will not be + affected by previously defined shaders. """ pass @@ -13535,8 +13515,8 @@ def reset_shader(self, kind: int, /) -> None: Notes ----- - Restores the default shaders. Code that runs after ``reset_shader()`` will not - be affected by previously defined shaders. + Restores the default shaders. Code that runs after `reset_shader()` will not be + affected by previously defined shaders. """ pass @@ -13562,14 +13542,14 @@ def reset_shader(self, *args): Notes ----- - Restores the default shaders. Code that runs after ``reset_shader()`` will not - be affected by previously defined shaders. + Restores the default shaders. Code that runs after `reset_shader()` will not be + affected by previously defined shaders. """ return self._instance.resetShader(*args) @overload def rotate(self, angle: float, /) -> None: - """Rotates the amount specified by the ``angle`` parameter. + """Rotates the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotate @@ -13599,27 +13579,27 @@ def rotate(self, angle: float, /) -> None: Notes ----- - Rotates the amount specified by the ``angle`` parameter. Angles must be - specified in radians (values from ``0`` to ``TWO_PI``), or they can be converted - from degrees to radians with the ``radians()`` function. + Rotates the amount specified by the `angle` parameter. Angles must be specified + in radians (values from `0` to `TWO_PI`), or they can be converted from degrees + to radians with the `radians()` function. The coordinates are always rotated around their relative position to the origin. Positive numbers rotate objects in a clockwise direction and negative numbers rotate in the couterclockwise direction. Transformations apply to everything that happens afterward, and subsequent calls to the function compound the - effect. For example, calling ``rotate(PI/2.0)`` once and then calling - ``rotate(PI/2.0)`` a second time is the same as a single ``rotate(PI)``. All - tranformations are reset when ``draw()`` begins again. + effect. For example, calling `rotate(PI/2.0)` once and then calling + `rotate(PI/2.0)` a second time is the same as a single `rotate(PI)`. All + tranformations are reset when `draw()` begins again. - Technically, ``rotate()`` multiplies the current transformation matrix by a - rotation matrix. This function can be further controlled by ``push_matrix()`` - and ``pop_matrix()``. + Technically, `rotate()` multiplies the current transformation matrix by a + rotation matrix. This function can be further controlled by `push_matrix()` and + `pop_matrix()`. """ pass @overload def rotate(self, angle: float, x: float, y: float, z: float, /) -> None: - """Rotates the amount specified by the ``angle`` parameter. + """Rotates the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotate @@ -13649,26 +13629,26 @@ def rotate(self, angle: float, x: float, y: float, z: float, /) -> None: Notes ----- - Rotates the amount specified by the ``angle`` parameter. Angles must be - specified in radians (values from ``0`` to ``TWO_PI``), or they can be converted - from degrees to radians with the ``radians()`` function. + Rotates the amount specified by the `angle` parameter. Angles must be specified + in radians (values from `0` to `TWO_PI`), or they can be converted from degrees + to radians with the `radians()` function. The coordinates are always rotated around their relative position to the origin. Positive numbers rotate objects in a clockwise direction and negative numbers rotate in the couterclockwise direction. Transformations apply to everything that happens afterward, and subsequent calls to the function compound the - effect. For example, calling ``rotate(PI/2.0)`` once and then calling - ``rotate(PI/2.0)`` a second time is the same as a single ``rotate(PI)``. All - tranformations are reset when ``draw()`` begins again. + effect. For example, calling `rotate(PI/2.0)` once and then calling + `rotate(PI/2.0)` a second time is the same as a single `rotate(PI)`. All + tranformations are reset when `draw()` begins again. - Technically, ``rotate()`` multiplies the current transformation matrix by a - rotation matrix. This function can be further controlled by ``push_matrix()`` - and ``pop_matrix()``. + Technically, `rotate()` multiplies the current transformation matrix by a + rotation matrix. This function can be further controlled by `push_matrix()` and + `pop_matrix()`. """ pass def rotate(self, *args): - """Rotates the amount specified by the ``angle`` parameter. + """Rotates the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotate @@ -13698,26 +13678,26 @@ def rotate(self, *args): Notes ----- - Rotates the amount specified by the ``angle`` parameter. Angles must be - specified in radians (values from ``0`` to ``TWO_PI``), or they can be converted - from degrees to radians with the ``radians()`` function. + Rotates the amount specified by the `angle` parameter. Angles must be specified + in radians (values from `0` to `TWO_PI`), or they can be converted from degrees + to radians with the `radians()` function. The coordinates are always rotated around their relative position to the origin. Positive numbers rotate objects in a clockwise direction and negative numbers rotate in the couterclockwise direction. Transformations apply to everything that happens afterward, and subsequent calls to the function compound the - effect. For example, calling ``rotate(PI/2.0)`` once and then calling - ``rotate(PI/2.0)`` a second time is the same as a single ``rotate(PI)``. All - tranformations are reset when ``draw()`` begins again. + effect. For example, calling `rotate(PI/2.0)` once and then calling + `rotate(PI/2.0)` a second time is the same as a single `rotate(PI)`. All + tranformations are reset when `draw()` begins again. - Technically, ``rotate()`` multiplies the current transformation matrix by a - rotation matrix. This function can be further controlled by ``push_matrix()`` - and ``pop_matrix()``. + Technically, `rotate()` multiplies the current transformation matrix by a + rotation matrix. This function can be further controlled by `push_matrix()` and + `pop_matrix()`. """ return self._instance.rotate(*args) def rotate_x(self, angle: float, /) -> None: - """Rotates around the x-axis the amount specified by the ``angle`` parameter. + """Rotates around the x-axis the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotateX @@ -13730,22 +13710,22 @@ def rotate_x(self, angle: float, /) -> None: Notes ----- - Rotates around the x-axis the amount specified by the ``angle`` parameter. - Angles should be specified in radians (values from ``0`` to ``TWO_PI``) or - converted from degrees to radians with the ``radians()`` function. Coordinates - are always rotated around their relative position to the origin. Positive - numbers rotate in a clockwise direction and negative numbers rotate in a - counterclockwise direction. Transformations apply to everything that happens - after and subsequent calls to the function accumulates the effect. For example, - calling ``rotate_x(PI/2)`` and then ``rotate_x(PI/2)`` is the same as - ``rotate_x(PI)``. If ``rotate_x()`` is run within the ``draw()``, the - transformation is reset when the loop begins again. This function requires using - ``P3D`` as a third parameter to ``size()`` as shown in the example. + Rotates around the x-axis the amount specified by the `angle` parameter. Angles + should be specified in radians (values from `0` to `TWO_PI`) or converted from + degrees to radians with the `radians()` function. Coordinates are always rotated + around their relative position to the origin. Positive numbers rotate in a + clockwise direction and negative numbers rotate in a counterclockwise direction. + Transformations apply to everything that happens after and subsequent calls to + the function accumulates the effect. For example, calling `rotate_x(PI/2)` and + then `rotate_x(PI/2)` is the same as `rotate_x(PI)`. If `rotate_x()` is run + within the `draw()`, the transformation is reset when the loop begins again. + This function requires using `P3D` as a third parameter to `size()` as shown in + the example. """ return self._instance.rotateX(angle) def rotate_y(self, angle: float, /) -> None: - """Rotates around the y-axis the amount specified by the ``angle`` parameter. + """Rotates around the y-axis the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotateY @@ -13758,22 +13738,22 @@ def rotate_y(self, angle: float, /) -> None: Notes ----- - Rotates around the y-axis the amount specified by the ``angle`` parameter. - Angles should be specified in radians (values from ``0`` to ``TWO_PI``) or - converted from degrees to radians with the ``radians()`` function. Coordinates - are always rotated around their relative position to the origin. Positive - numbers rotate in a clockwise direction and negative numbers rotate in a - counterclockwise direction. Transformations apply to everything that happens - after and subsequent calls to the function accumulates the effect. For example, - calling ``rotate_y(PI/2)`` and then ``rotate_y(PI/2)`` is the same as - ``rotate_y(PI)``. If ``rotate_y()`` is run within the ``draw()``, the - transformation is reset when the loop begins again. This function requires using - ``P3D`` as a third parameter to ``size()`` as shown in the example. + Rotates around the y-axis the amount specified by the `angle` parameter. Angles + should be specified in radians (values from `0` to `TWO_PI`) or converted from + degrees to radians with the `radians()` function. Coordinates are always rotated + around their relative position to the origin. Positive numbers rotate in a + clockwise direction and negative numbers rotate in a counterclockwise direction. + Transformations apply to everything that happens after and subsequent calls to + the function accumulates the effect. For example, calling `rotate_y(PI/2)` and + then `rotate_y(PI/2)` is the same as `rotate_y(PI)`. If `rotate_y()` is run + within the `draw()`, the transformation is reset when the loop begins again. + This function requires using `P3D` as a third parameter to `size()` as shown in + the example. """ return self._instance.rotateY(angle) def rotate_z(self, angle: float, /) -> None: - """Rotates around the z-axis the amount specified by the ``angle`` parameter. + """Rotates around the z-axis the amount specified by the `angle` parameter. Underlying Processing method: PApplet.rotateZ @@ -13786,17 +13766,17 @@ def rotate_z(self, angle: float, /) -> None: Notes ----- - Rotates around the z-axis the amount specified by the ``angle`` parameter. - Angles should be specified in radians (values from ``0`` to ``TWO_PI``) or - converted from degrees to radians with the ``radians()`` function. Coordinates - are always rotated around their relative position to the origin. Positive - numbers rotate in a clockwise direction and negative numbers rotate in a - counterclockwise direction. Transformations apply to everything that happens - after and subsequent calls to the function accumulates the effect. For example, - calling ``rotate_z(PI/2)`` and then ``rotate_z(PI/2)`` is the same as - ``rotate_z(PI)``. If ``rotate_z()`` is run within the ``draw()``, the - transformation is reset when the loop begins again. This function requires using - ``P3D`` as a third parameter to ``size()`` as shown in the example. + Rotates around the z-axis the amount specified by the `angle` parameter. Angles + should be specified in radians (values from `0` to `TWO_PI`) or converted from + degrees to radians with the `radians()` function. Coordinates are always rotated + around their relative position to the origin. Positive numbers rotate in a + clockwise direction and negative numbers rotate in a counterclockwise direction. + Transformations apply to everything that happens after and subsequent calls to + the function accumulates the effect. For example, calling `rotate_z(PI/2)` and + then `rotate_z(PI/2)` is the same as `rotate_z(PI)`. If `rotate_z()` is run + within the `draw()`, the transformation is reset when the loop begins again. + This function requires using `P3D` as a third parameter to `size()` as shown in + the example. """ return self._instance.rotateZ(angle) @@ -13856,15 +13836,15 @@ def scale(self, s: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. If ``scale()`` is called within - ``draw()``, the transformation is reset when the loop begins again. Using this - function with the ``z`` parameter requires using ``P3D`` as a parameter for - ``size()``, as shown in the third example. This function can be further - controlled with ``push_matrix()`` and ``pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. If `scale()` is called within + `draw()`, the transformation is reset when the loop begins again. Using this + function with the `z` parameter requires using `P3D` as a parameter for + `size()`, as shown in the third example. This function can be further controlled + with `push_matrix()` and `pop_matrix()`. """ pass @@ -13905,15 +13885,15 @@ def scale(self, x: float, y: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. If ``scale()`` is called within - ``draw()``, the transformation is reset when the loop begins again. Using this - function with the ``z`` parameter requires using ``P3D`` as a parameter for - ``size()``, as shown in the third example. This function can be further - controlled with ``push_matrix()`` and ``pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. If `scale()` is called within + `draw()`, the transformation is reset when the loop begins again. Using this + function with the `z` parameter requires using `P3D` as a parameter for + `size()`, as shown in the third example. This function can be further controlled + with `push_matrix()` and `pop_matrix()`. """ pass @@ -13954,15 +13934,15 @@ def scale(self, x: float, y: float, z: float, /) -> None: Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. If ``scale()`` is called within - ``draw()``, the transformation is reset when the loop begins again. Using this - function with the ``z`` parameter requires using ``P3D`` as a parameter for - ``size()``, as shown in the third example. This function can be further - controlled with ``push_matrix()`` and ``pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. If `scale()` is called within + `draw()`, the transformation is reset when the loop begins again. Using this + function with the `z` parameter requires using `P3D` as a parameter for + `size()`, as shown in the third example. This function can be further controlled + with `push_matrix()` and `pop_matrix()`. """ pass @@ -14002,15 +13982,15 @@ def scale(self, *args): Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the - function call ``scale(2.0)`` increases the dimension of a shape by 200%. + function call `scale(2.0)` increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to - the function multiply the effect. For example, calling ``scale(2.0)`` and then - ``scale(1.5)`` is the same as ``scale(3.0)``. If ``scale()`` is called within - ``draw()``, the transformation is reset when the loop begins again. Using this - function with the ``z`` parameter requires using ``P3D`` as a parameter for - ``size()``, as shown in the third example. This function can be further - controlled with ``push_matrix()`` and ``pop_matrix()``. + the function multiply the effect. For example, calling `scale(2.0)` and then + `scale(1.5)` is the same as `scale(3.0)`. If `scale()` is called within + `draw()`, the transformation is reset when the loop begins again. Using this + function with the `z` parameter requires using `P3D` as a parameter for + `size()`, as shown in the third example. This function can be further controlled + with `push_matrix()` and `pop_matrix()`. """ return self._instance.scale(*args) @@ -14257,14 +14237,161 @@ def second(cls) -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``second()`` function + Py5 communicates with the clock on your computer. The `second()` function returns the current second as a value from 0 - 59. """ return cls._cls.second() + @overload + def set_pixels(self, x: int, y: int, c: int, /) -> None: + """Changes the color of any pixel or writes an image directly into the drawing + surface. + + Underlying Processing method: Sketch.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Sketch window + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the drawing + surface. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `image_mode()`. + + Setting the color of a single pixel with `py5.set_pixels(x, y)` is easy, but not + as fast as putting the data directly into `pixels[]`. The equivalent statement + to `py5.set_pixels(x, y, 0)` using `pixels[]` is `py5.pixels[y*py5.width+x] = + 0`. See the reference for `pixels[]` for more information. + """ + pass + + @overload + def set_pixels(self, x: int, y: int, img: Py5Image, /) -> None: + """Changes the color of any pixel or writes an image directly into the drawing + surface. + + Underlying Processing method: Sketch.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Sketch window + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the drawing + surface. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `image_mode()`. + + Setting the color of a single pixel with `py5.set_pixels(x, y)` is easy, but not + as fast as putting the data directly into `pixels[]`. The equivalent statement + to `py5.set_pixels(x, y, 0)` using `pixels[]` is `py5.pixels[y*py5.width+x] = + 0`. See the reference for `pixels[]` for more information. + """ + pass + + @_auto_convert_to_py5image(2) + def set_pixels(self, *args): + """Changes the color of any pixel or writes an image directly into the drawing + surface. + + Underlying Processing method: Sketch.set + + Methods + ------- + + You can use any of the following signatures: + + * set_pixels(x: int, y: int, c: int, /) -> None + * set_pixels(x: int, y: int, img: Py5Image, /) -> None + + Parameters + ---------- + + c: int + any color value + + img: Py5Image + image to copy into the Sketch window + + x: int + x-coordinate of the pixel + + y: int + y-coordinate of the pixel + + Notes + ----- + + Changes the color of any pixel or writes an image directly into the drawing + surface. + + The `x` and `y` parameters specify the pixel to change and the color parameter + specifies the color value. The color parameter `c` is affected by the current + color mode (the default is RGB values from 0 to 255). When setting an image, the + `x` and `y` parameters define the coordinates for the upper-left corner of the + image, regardless of the current `image_mode()`. + + Setting the color of a single pixel with `py5.set_pixels(x, y)` is easy, but not + as fast as putting the data directly into `pixels[]`. The equivalent statement + to `py5.set_pixels(x, y, 0)` using `pixels[]` is `py5.pixels[y*py5.width+x] = + 0`. See the reference for `pixels[]` for more information. + """ + return self._instance.set(*args) + @overload def set_matrix(self, source: npt.NDArray[np.floating], /) -> None: - """Set the current matrix to the one specified through the parameter ``source``. + """Set the current matrix to the one specified through the parameter `source`. Underlying Processing method: PApplet.setMatrix @@ -14277,15 +14404,15 @@ def set_matrix(self, source: npt.NDArray[np.floating], /) -> None: Notes ----- - Set the current matrix to the one specified through the parameter ``source``. - Inside the Processing code it will call ``reset_matrix()`` followed by - ``apply_matrix()``. This will be very slow because ``apply_matrix()`` will try - to calculate the inverse of the transform, so avoid it whenever possible. + Set the current matrix to the one specified through the parameter `source`. + Inside the Processing code it will call `reset_matrix()` followed by + `apply_matrix()`. This will be very slow because `apply_matrix()` will try to + calculate the inverse of the transform, so avoid it whenever possible. """ pass def set_matrix(self, *args): - """Set the current matrix to the one specified through the parameter ``source``. + """Set the current matrix to the one specified through the parameter `source`. Underlying Processing method: PApplet.setMatrix @@ -14298,10 +14425,10 @@ def set_matrix(self, *args): Notes ----- - Set the current matrix to the one specified through the parameter ``source``. - Inside the Processing code it will call ``reset_matrix()`` followed by - ``apply_matrix()``. This will be very slow because ``apply_matrix()`` will try - to calculate the inverse of the transform, so avoid it whenever possible. + Set the current matrix to the one specified through the parameter `source`. + Inside the Processing code it will call `reset_matrix()` followed by + `apply_matrix()`. This will be very slow because `apply_matrix()` will try to + calculate the inverse of the transform, so avoid it whenever possible. """ return self._instance.setMatrix(*args) @@ -14331,8 +14458,8 @@ def shader(self, shader: Py5Shader, /) -> None: Notes ----- - Applies the shader specified by the parameters. It's compatible with the ``P2D`` - and ``P3D`` renderers, but not with the default renderer. + Applies the shader specified by the parameters. It's compatible with the `P2D` + and `P3D` renderers, but not with the default renderer. """ pass @@ -14362,8 +14489,8 @@ def shader(self, shader: Py5Shader, kind: int, /) -> None: Notes ----- - Applies the shader specified by the parameters. It's compatible with the ``P2D`` - and ``P3D`` renderers, but not with the default renderer. + Applies the shader specified by the parameters. It's compatible with the `P2D` + and `P3D` renderers, but not with the default renderer. """ pass @@ -14392,8 +14519,8 @@ def shader(self, *args): Notes ----- - Applies the shader specified by the parameters. It's compatible with the ``P2D`` - and ``P3D`` renderers, but not with the default renderer. + Applies the shader specified by the parameters. It's compatible with the `P2D` + and `P3D` renderers, but not with the default renderer. """ return self._instance.shader(*args) @@ -14441,11 +14568,11 @@ def shape(self, shape: Py5Shape, /) -> None: Draws shapes to the display window. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and custom- - created shapes. The ``shape`` parameter specifies the shape to display and the + created shapes. The `shape` parameter specifies the shape to display and the coordinate parameters define the location of the shape from its upper-left - corner. The shape is displayed at its original size unless the ``c`` and ``d`` - parameters specify a different size. The ``shape_mode()`` function can be used - to change the way these parameters are interpreted. + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `shape_mode()` function can be used to + change the way these parameters are interpreted. """ pass @@ -14493,11 +14620,11 @@ def shape(self, shape: Py5Shape, x: float, y: float, /) -> None: Draws shapes to the display window. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and custom- - created shapes. The ``shape`` parameter specifies the shape to display and the + created shapes. The `shape` parameter specifies the shape to display and the coordinate parameters define the location of the shape from its upper-left - corner. The shape is displayed at its original size unless the ``c`` and ``d`` - parameters specify a different size. The ``shape_mode()`` function can be used - to change the way these parameters are interpreted. + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `shape_mode()` function can be used to + change the way these parameters are interpreted. """ pass @@ -14546,11 +14673,11 @@ def shape(self, shape: Py5Shape, a: float, Draws shapes to the display window. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and custom- - created shapes. The ``shape`` parameter specifies the shape to display and the + created shapes. The `shape` parameter specifies the shape to display and the coordinate parameters define the location of the shape from its upper-left - corner. The shape is displayed at its original size unless the ``c`` and ``d`` - parameters specify a different size. The ``shape_mode()`` function can be used - to change the way these parameters are interpreted. + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `shape_mode()` function can be used to + change the way these parameters are interpreted. """ pass @@ -14597,11 +14724,11 @@ def shape(self, *args): Draws shapes to the display window. Shapes must be in the Sketch's "data" directory to load correctly. Py5 currently works with SVG, OBJ, and custom- - created shapes. The ``shape`` parameter specifies the shape to display and the + created shapes. The `shape` parameter specifies the shape to display and the coordinate parameters define the location of the shape from its upper-left - corner. The shape is displayed at its original size unless the ``c`` and ``d`` - parameters specify a different size. The ``shape_mode()`` function can be used - to change the way these parameters are interpreted. + corner. The shape is displayed at its original size unless the `c` and `d` + parameters specify a different size. The `shape_mode()` function can be used to + change the way these parameters are interpreted. """ return self._instance.shape(*args) @@ -14620,21 +14747,19 @@ def shape_mode(self, mode: int, /) -> None: ----- Modifies the location from which shapes draw. The default mode is - ``shape_mode(CORNER)``, which specifies the location to be the upper left corner - of the shape and uses the third and fourth parameters of ``shape()`` to specify - the width and height. The syntax ``shape_mode(CORNERS)`` uses the first and - second parameters of ``shape()`` to set the location of one corner and uses the - third and fourth parameters to set the opposite corner. The syntax - ``shape_mode(CENTER)`` draws the shape from its center point and uses the third - and forth parameters of ``shape()`` to specify the width and height. The - parameter must be written in ALL CAPS because Python is a case sensitive - language. + `shape_mode(CORNER)`, which specifies the location to be the upper left corner + of the shape and uses the third and fourth parameters of `shape()` to specify + the width and height. The syntax `shape_mode(CORNERS)` uses the first and second + parameters of `shape()` to set the location of one corner and uses the third and + fourth parameters to set the opposite corner. The syntax `shape_mode(CENTER)` + draws the shape from its center point and uses the third and forth parameters of + `shape()` to specify the width and height. The parameter must be written in ALL + CAPS because Python is a case sensitive language. """ return self._instance.shapeMode(mode) def shear_x(self, angle: float, /) -> None: - """Shears a shape around the x-axis the amount specified by the ``angle`` - parameter. + """Shears a shape around the x-axis the amount specified by the `angle` parameter. Underlying Processing method: PApplet.shearX @@ -14647,25 +14772,24 @@ def shear_x(self, angle: float, /) -> None: Notes ----- - Shears a shape around the x-axis the amount specified by the ``angle`` - parameter. Angles should be specified in radians (values from ``0`` to - ``TWO_PI``) or converted to radians with the ``radians()`` function. Objects are - always sheared around their relative position to the origin and positive numbers - shear objects in a clockwise direction. Transformations apply to everything that - happens after and subsequent calls to the function accumulates the effect. For - example, calling ``shear_x(PI/2)`` and then ``shear_x(PI/2)`` is the same as - ``shear_x(PI)``. If ``shear_x()`` is called within the ``draw()``, the - transformation is reset when the loop begins again. + Shears a shape around the x-axis the amount specified by the `angle` parameter. + Angles should be specified in radians (values from `0` to `TWO_PI`) or converted + to radians with the `radians()` function. Objects are always sheared around + their relative position to the origin and positive numbers shear objects in a + clockwise direction. Transformations apply to everything that happens after and + subsequent calls to the function accumulates the effect. For example, calling + `shear_x(PI/2)` and then `shear_x(PI/2)` is the same as `shear_x(PI)`. If + `shear_x()` is called within the `draw()`, the transformation is reset when the + loop begins again. - Technically, ``shear_x()`` multiplies the current transformation matrix by a - rotation matrix. This function can be further controlled by the - ``push_matrix()`` and ``pop_matrix()`` functions. + Technically, `shear_x()` multiplies the current transformation matrix by a + rotation matrix. This function can be further controlled by the `push_matrix()` + and `pop_matrix()` functions. """ return self._instance.shearX(angle) def shear_y(self, angle: float, /) -> None: - """Shears a shape around the y-axis the amount specified by the ``angle`` - parameter. + """Shears a shape around the y-axis the amount specified by the `angle` parameter. Underlying Processing method: PApplet.shearY @@ -14678,19 +14802,19 @@ def shear_y(self, angle: float, /) -> None: Notes ----- - Shears a shape around the y-axis the amount specified by the ``angle`` - parameter. Angles should be specified in radians (values from ``0`` to - ``TWO_PI``) or converted to radians with the ``radians()`` function. Objects are - always sheared around their relative position to the origin and positive numbers - shear objects in a clockwise direction. Transformations apply to everything that - happens after and subsequent calls to the function accumulates the effect. For - example, calling ``shear_y(PI/2)`` and then ``shear_y(PI/2)`` is the same as - ``shear_y(PI)``. If ``shear_y()`` is called within the ``draw()``, the - transformation is reset when the loop begins again. + Shears a shape around the y-axis the amount specified by the `angle` parameter. + Angles should be specified in radians (values from `0` to `TWO_PI`) or converted + to radians with the `radians()` function. Objects are always sheared around + their relative position to the origin and positive numbers shear objects in a + clockwise direction. Transformations apply to everything that happens after and + subsequent calls to the function accumulates the effect. For example, calling + `shear_y(PI/2)` and then `shear_y(PI/2)` is the same as `shear_y(PI)`. If + `shear_y()` is called within the `draw()`, the transformation is reset when the + loop begins again. - Technically, ``shear_y()`` multiplies the current transformation matrix by a - rotation matrix. This function can be further controlled by the - ``push_matrix()`` and ``pop_matrix()`` functions. + Technically, `shear_y()` multiplies the current transformation matrix by a + rotation matrix. This function can be further controlled by the `push_matrix()` + and `pop_matrix()` functions. """ return self._instance.shearY(angle) @@ -14709,8 +14833,8 @@ def shininess(self, shine: float, /) -> None: ----- Sets the amount of gloss in the surface of shapes. Use in combination with - ``ambient()``, ``specular()``, and ``emissive()`` to set the material properties - of shapes. + `ambient()`, `specular()`, and `emissive()` to set the material properties of + shapes. """ return self._instance.shininess(shine) @@ -14748,68 +14872,67 @@ def size(self, width: int, height: int, /) -> None: ----- Defines the dimension of the display window width and height in units of pixels. - This is intended to be called from the ``settings()`` function. + This is intended to be called from the `settings()` function. When programming in module mode and imported mode, py5 will allow calls to - ``size()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `size()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``size()``, or calls to - ``full_screen()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls - to those functions must be at the very beginning of ``setup()``, before any - other Python code (but comments are ok). This feature is not available when - programming in class mode. - - The built-in variables ``width`` and ``height`` are set by the parameters passed - to this function. For example, running ``size(640, 480)`` will assign 640 to the - ``width`` variable and 480 to the height ``variable``. If ``size()`` is not - used, the window will be given a default size of 100 x 100 pixels. - - The ``size()`` function can only be used once inside a Sketch, and it cannot be + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `size()`, or calls to + `full_screen()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + The built-in variables `width` and `height` are set by the parameters passed to + this function. For example, running `size(640, 480)` will assign 640 to the + `width` variable and 480 to the height `variable`. If `size()` is not used, the + window will be given a default size of 100 x 100 pixels. + + The `size()` function can only be used once inside a Sketch, and it cannot be used for resizing. - To run a Sketch at the full dimensions of a screen, use the ``full_screen()`` - function, rather than the older way of using ``size(display_width, - display_height)``. + To run a Sketch at the full dimensions of a screen, use the `full_screen()` + function, rather than the older way of using `size(display_width, + display_height)`. The maximum width and height is limited by your operating system, and is usually the width and height of your actual screen. On some machines it may simply be the number of pixels on your current screen, meaning that a screen of 800 x 600 - could support ``size(1600, 300)``, since that is the same number of pixels. This + could support `size(1600, 300)`, since that is the same number of pixels. This varies widely, so you'll have to try different rendering modes and sizes until you get what you're looking for. If you need something larger, use - ``create_graphics`` to create a non-visible drawing surface. + `create_graphics` to create a non-visible drawing surface. The minimum width and height is around 100 pixels in each direction. This is the smallest that is supported across Windows, macOS, and Linux. We enforce the minimum size so that Sketches will run identically on different machines. - The ``renderer`` parameter selects which rendering engine to use. For example, - if you will be drawing 3D shapes, use ``P3D``. In addition to the default - renderer, other renderers are: + The `renderer` parameter selects which rendering engine to use. For example, if + you will be drawing 3D shapes, use `P3D`. In addition to the default renderer, + other renderers are: - * ``P2D`` (Processing 2D): 2D graphics renderer that makes use of OpenGL- + * `P2D` (Processing 2D): 2D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``P3D`` (Processing 3D): 3D graphics renderer that makes use of OpenGL- + * `P3D` (Processing 3D): 3D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``FX2D`` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for + * `FX2D` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for some applications, but has some compatibility quirks. - * ``PDF``: The ``PDF`` renderer draws 2D graphics directly to an Acrobat PDF - file. This produces excellent results when you need vector shapes for high- - resolution output or printing. - * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This - is great for importing into other vector programs or using for digital - fabrication. - - When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you - must use the ``path`` parameter to specify the file to write the output to. No - window will open while the Sketch is running. You must also call - ``exit_sketch()`` to exit the Sketch and write the completed output to the file. - Without this call, the Sketch will not exit and the output file will be empty. - If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` - renderer and the strategy described in ``begin_raw()``. + * `PDF`: The `PDF` renderer draws 2D graphics directly to an Acrobat PDF file. + This produces excellent results when you need vector shapes for high-resolution + output or printing. + * `SVG`: The `SVG` renderer draws 2D graphics directly to an SVG file. This is + great for importing into other vector programs or using for digital fabrication. + + When using the `PDF` and `SVG` renderers with the `size()` method, you must use + the `path` parameter to specify the file to write the output to. No window will + open while the Sketch is running. You must also call `exit_sketch()` to exit the + Sketch and write the completed output to the file. Without this call, the Sketch + will not exit and the output file will be empty. If you would like to draw 3D + objects to a PDF or SVG file, use the `P3D` renderer and the strategy described + in `begin_raw()`. """ pass @@ -14847,68 +14970,67 @@ def size(self, width: int, height: int, renderer: str, /) -> None: ----- Defines the dimension of the display window width and height in units of pixels. - This is intended to be called from the ``settings()`` function. + This is intended to be called from the `settings()` function. When programming in module mode and imported mode, py5 will allow calls to - ``size()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `size()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``size()``, or calls to - ``full_screen()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls - to those functions must be at the very beginning of ``setup()``, before any - other Python code (but comments are ok). This feature is not available when - programming in class mode. - - The built-in variables ``width`` and ``height`` are set by the parameters passed - to this function. For example, running ``size(640, 480)`` will assign 640 to the - ``width`` variable and 480 to the height ``variable``. If ``size()`` is not - used, the window will be given a default size of 100 x 100 pixels. - - The ``size()`` function can only be used once inside a Sketch, and it cannot be + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `size()`, or calls to + `full_screen()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + The built-in variables `width` and `height` are set by the parameters passed to + this function. For example, running `size(640, 480)` will assign 640 to the + `width` variable and 480 to the height `variable`. If `size()` is not used, the + window will be given a default size of 100 x 100 pixels. + + The `size()` function can only be used once inside a Sketch, and it cannot be used for resizing. - To run a Sketch at the full dimensions of a screen, use the ``full_screen()`` - function, rather than the older way of using ``size(display_width, - display_height)``. + To run a Sketch at the full dimensions of a screen, use the `full_screen()` + function, rather than the older way of using `size(display_width, + display_height)`. The maximum width and height is limited by your operating system, and is usually the width and height of your actual screen. On some machines it may simply be the number of pixels on your current screen, meaning that a screen of 800 x 600 - could support ``size(1600, 300)``, since that is the same number of pixels. This + could support `size(1600, 300)`, since that is the same number of pixels. This varies widely, so you'll have to try different rendering modes and sizes until you get what you're looking for. If you need something larger, use - ``create_graphics`` to create a non-visible drawing surface. + `create_graphics` to create a non-visible drawing surface. The minimum width and height is around 100 pixels in each direction. This is the smallest that is supported across Windows, macOS, and Linux. We enforce the minimum size so that Sketches will run identically on different machines. - The ``renderer`` parameter selects which rendering engine to use. For example, - if you will be drawing 3D shapes, use ``P3D``. In addition to the default - renderer, other renderers are: + The `renderer` parameter selects which rendering engine to use. For example, if + you will be drawing 3D shapes, use `P3D`. In addition to the default renderer, + other renderers are: - * ``P2D`` (Processing 2D): 2D graphics renderer that makes use of OpenGL- + * `P2D` (Processing 2D): 2D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``P3D`` (Processing 3D): 3D graphics renderer that makes use of OpenGL- + * `P3D` (Processing 3D): 3D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``FX2D`` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for + * `FX2D` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for some applications, but has some compatibility quirks. - * ``PDF``: The ``PDF`` renderer draws 2D graphics directly to an Acrobat PDF - file. This produces excellent results when you need vector shapes for high- - resolution output or printing. - * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This - is great for importing into other vector programs or using for digital - fabrication. - - When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you - must use the ``path`` parameter to specify the file to write the output to. No - window will open while the Sketch is running. You must also call - ``exit_sketch()`` to exit the Sketch and write the completed output to the file. - Without this call, the Sketch will not exit and the output file will be empty. - If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` - renderer and the strategy described in ``begin_raw()``. + * `PDF`: The `PDF` renderer draws 2D graphics directly to an Acrobat PDF file. + This produces excellent results when you need vector shapes for high-resolution + output or printing. + * `SVG`: The `SVG` renderer draws 2D graphics directly to an SVG file. This is + great for importing into other vector programs or using for digital fabrication. + + When using the `PDF` and `SVG` renderers with the `size()` method, you must use + the `path` parameter to specify the file to write the output to. No window will + open while the Sketch is running. You must also call `exit_sketch()` to exit the + Sketch and write the completed output to the file. Without this call, the Sketch + will not exit and the output file will be empty. If you would like to draw 3D + objects to a PDF or SVG file, use the `P3D` renderer and the strategy described + in `begin_raw()`. """ pass @@ -14947,68 +15069,67 @@ def size(self, width: int, height: int, ----- Defines the dimension of the display window width and height in units of pixels. - This is intended to be called from the ``settings()`` function. + This is intended to be called from the `settings()` function. When programming in module mode and imported mode, py5 will allow calls to - ``size()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `size()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``size()``, or calls to - ``full_screen()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls - to those functions must be at the very beginning of ``setup()``, before any - other Python code (but comments are ok). This feature is not available when - programming in class mode. - - The built-in variables ``width`` and ``height`` are set by the parameters passed - to this function. For example, running ``size(640, 480)`` will assign 640 to the - ``width`` variable and 480 to the height ``variable``. If ``size()`` is not - used, the window will be given a default size of 100 x 100 pixels. - - The ``size()`` function can only be used once inside a Sketch, and it cannot be + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `size()`, or calls to + `full_screen()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + The built-in variables `width` and `height` are set by the parameters passed to + this function. For example, running `size(640, 480)` will assign 640 to the + `width` variable and 480 to the height `variable`. If `size()` is not used, the + window will be given a default size of 100 x 100 pixels. + + The `size()` function can only be used once inside a Sketch, and it cannot be used for resizing. - To run a Sketch at the full dimensions of a screen, use the ``full_screen()`` - function, rather than the older way of using ``size(display_width, - display_height)``. + To run a Sketch at the full dimensions of a screen, use the `full_screen()` + function, rather than the older way of using `size(display_width, + display_height)`. The maximum width and height is limited by your operating system, and is usually the width and height of your actual screen. On some machines it may simply be the number of pixels on your current screen, meaning that a screen of 800 x 600 - could support ``size(1600, 300)``, since that is the same number of pixels. This + could support `size(1600, 300)`, since that is the same number of pixels. This varies widely, so you'll have to try different rendering modes and sizes until you get what you're looking for. If you need something larger, use - ``create_graphics`` to create a non-visible drawing surface. + `create_graphics` to create a non-visible drawing surface. The minimum width and height is around 100 pixels in each direction. This is the smallest that is supported across Windows, macOS, and Linux. We enforce the minimum size so that Sketches will run identically on different machines. - The ``renderer`` parameter selects which rendering engine to use. For example, - if you will be drawing 3D shapes, use ``P3D``. In addition to the default - renderer, other renderers are: + The `renderer` parameter selects which rendering engine to use. For example, if + you will be drawing 3D shapes, use `P3D`. In addition to the default renderer, + other renderers are: - * ``P2D`` (Processing 2D): 2D graphics renderer that makes use of OpenGL- + * `P2D` (Processing 2D): 2D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``P3D`` (Processing 3D): 3D graphics renderer that makes use of OpenGL- + * `P3D` (Processing 3D): 3D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``FX2D`` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for + * `FX2D` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for some applications, but has some compatibility quirks. - * ``PDF``: The ``PDF`` renderer draws 2D graphics directly to an Acrobat PDF - file. This produces excellent results when you need vector shapes for high- - resolution output or printing. - * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This - is great for importing into other vector programs or using for digital - fabrication. - - When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you - must use the ``path`` parameter to specify the file to write the output to. No - window will open while the Sketch is running. You must also call - ``exit_sketch()`` to exit the Sketch and write the completed output to the file. - Without this call, the Sketch will not exit and the output file will be empty. - If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` - renderer and the strategy described in ``begin_raw()``. + * `PDF`: The `PDF` renderer draws 2D graphics directly to an Acrobat PDF file. + This produces excellent results when you need vector shapes for high-resolution + output or printing. + * `SVG`: The `SVG` renderer draws 2D graphics directly to an SVG file. This is + great for importing into other vector programs or using for digital fabrication. + + When using the `PDF` and `SVG` renderers with the `size()` method, you must use + the `path` parameter to specify the file to write the output to. No window will + open while the Sketch is running. You must also call `exit_sketch()` to exit the + Sketch and write the completed output to the file. Without this call, the Sketch + will not exit and the output file will be empty. If you would like to draw 3D + objects to a PDF or SVG file, use the `P3D` renderer and the strategy described + in `begin_raw()`. """ pass @@ -15046,68 +15167,67 @@ def size(self, *args): ----- Defines the dimension of the display window width and height in units of pixels. - This is intended to be called from the ``settings()`` function. + This is intended to be called from the `settings()` function. When programming in module mode and imported mode, py5 will allow calls to - ``size()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `size()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``size()``, or calls to - ``full_screen()``, ``smooth()``, ``no_smooth()``, or ``pixel_density()``. Calls - to those functions must be at the very beginning of ``setup()``, before any - other Python code (but comments are ok). This feature is not available when - programming in class mode. - - The built-in variables ``width`` and ``height`` are set by the parameters passed - to this function. For example, running ``size(640, 480)`` will assign 640 to the - ``width`` variable and 480 to the height ``variable``. If ``size()`` is not - used, the window will be given a default size of 100 x 100 pixels. - - The ``size()`` function can only be used once inside a Sketch, and it cannot be + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `size()`, or calls to + `full_screen()`, `smooth()`, `no_smooth()`, or `pixel_density()`. Calls to those + functions must be at the very beginning of `setup()`, before any other Python + code (but comments are ok). This feature is not available when programming in + class mode. + + The built-in variables `width` and `height` are set by the parameters passed to + this function. For example, running `size(640, 480)` will assign 640 to the + `width` variable and 480 to the height `variable`. If `size()` is not used, the + window will be given a default size of 100 x 100 pixels. + + The `size()` function can only be used once inside a Sketch, and it cannot be used for resizing. - To run a Sketch at the full dimensions of a screen, use the ``full_screen()`` - function, rather than the older way of using ``size(display_width, - display_height)``. + To run a Sketch at the full dimensions of a screen, use the `full_screen()` + function, rather than the older way of using `size(display_width, + display_height)`. The maximum width and height is limited by your operating system, and is usually the width and height of your actual screen. On some machines it may simply be the number of pixels on your current screen, meaning that a screen of 800 x 600 - could support ``size(1600, 300)``, since that is the same number of pixels. This + could support `size(1600, 300)`, since that is the same number of pixels. This varies widely, so you'll have to try different rendering modes and sizes until you get what you're looking for. If you need something larger, use - ``create_graphics`` to create a non-visible drawing surface. + `create_graphics` to create a non-visible drawing surface. The minimum width and height is around 100 pixels in each direction. This is the smallest that is supported across Windows, macOS, and Linux. We enforce the minimum size so that Sketches will run identically on different machines. - The ``renderer`` parameter selects which rendering engine to use. For example, - if you will be drawing 3D shapes, use ``P3D``. In addition to the default - renderer, other renderers are: + The `renderer` parameter selects which rendering engine to use. For example, if + you will be drawing 3D shapes, use `P3D`. In addition to the default renderer, + other renderers are: - * ``P2D`` (Processing 2D): 2D graphics renderer that makes use of OpenGL- + * `P2D` (Processing 2D): 2D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``P3D`` (Processing 3D): 3D graphics renderer that makes use of OpenGL- + * `P3D` (Processing 3D): 3D graphics renderer that makes use of OpenGL- compatible graphics hardware. - * ``FX2D`` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for + * `FX2D` (JavaFX 2D): A 2D renderer that uses JavaFX, which may be faster for some applications, but has some compatibility quirks. - * ``PDF``: The ``PDF`` renderer draws 2D graphics directly to an Acrobat PDF - file. This produces excellent results when you need vector shapes for high- - resolution output or printing. - * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This - is great for importing into other vector programs or using for digital - fabrication. - - When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you - must use the ``path`` parameter to specify the file to write the output to. No - window will open while the Sketch is running. You must also call - ``exit_sketch()`` to exit the Sketch and write the completed output to the file. - Without this call, the Sketch will not exit and the output file will be empty. - If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` - renderer and the strategy described in ``begin_raw()``. + * `PDF`: The `PDF` renderer draws 2D graphics directly to an Acrobat PDF file. + This produces excellent results when you need vector shapes for high-resolution + output or printing. + * `SVG`: The `SVG` renderer draws 2D graphics directly to an SVG file. This is + great for importing into other vector programs or using for digital fabrication. + + When using the `PDF` and `SVG` renderers with the `size()` method, you must use + the `path` parameter to specify the file to write the output to. No window will + open while the Sketch is running. You must also call `exit_sketch()` to exit the + Sketch and write the completed output to the file. Without this call, the Sketch + will not exit and the output file will be empty. If you would like to draw 3D + objects to a PDF or SVG file, use the `P3D` renderer and the strategy described + in `begin_raw()`. """ return self._instance.size(*args) @@ -15135,35 +15255,34 @@ def smooth(self) -> None: ----- Draws all geometry with smooth (anti-aliased) edges. This behavior is the - default, so ``smooth()`` only needs to be used when a program needs to set the - smoothing in a different way. The ``level`` parameter increases the amount of + default, so `smooth()` only needs to be used when a program needs to set the + smoothing in a different way. The `level` parameter increases the amount of smoothness. This is the level of over sampling applied to the graphics buffer. - With the ``P2D`` and ``P3D`` renderers, ``smooth(2)`` is the default, this is - called "2x anti-aliasing." The code ``smooth(4)`` is used for 4x anti-aliasing - and ``smooth(8)`` is specified for "8x anti-aliasing." The maximum anti-aliasing - level is determined by the hardware of the machine that is running the software, - so ``smooth(4)`` and ``smooth(8)`` will not work with every computer. + With the `P2D` and `P3D` renderers, `smooth(2)` is the default, this is called + "2x anti-aliasing." The code `smooth(4)` is used for 4x anti-aliasing and + `smooth(8)` is specified for "8x anti-aliasing." The maximum anti-aliasing level + is determined by the hardware of the machine that is running the software, so + `smooth(4)` and `smooth(8)` will not work with every computer. - The default renderer uses ``smooth(3)`` by default. This is bicubic smoothing. - The other option for the default renderer is ``smooth(2)``, which is bilinear + The default renderer uses `smooth(3)` by default. This is bicubic smoothing. The + other option for the default renderer is `smooth(2)`, which is bilinear smoothing. - The ``smooth()`` function can only be set once within a Sketch. It is intended - to be called from the ``settings()`` function. The ``no_smooth()`` function - follows the same rules. + The `smooth()` function can only be set once within a Sketch. It is intended to + be called from the `settings()` function. The `no_smooth()` function follows the + same rules. When programming in module mode and imported mode, py5 will allow calls to - ``smooth()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `smooth()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``smooth()``, or calls to - ``size()``, ``full_screen()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `smooth()`, or calls to `size()`, + `full_screen()`, `no_smooth()`, or `pixel_density()`. Calls to those functions + must be at the very beginning of `setup()`, before any other Python code (but + comments are ok). This feature is not available when programming in class mode. """ pass @@ -15191,35 +15310,34 @@ def smooth(self, level: int, /) -> None: ----- Draws all geometry with smooth (anti-aliased) edges. This behavior is the - default, so ``smooth()`` only needs to be used when a program needs to set the - smoothing in a different way. The ``level`` parameter increases the amount of + default, so `smooth()` only needs to be used when a program needs to set the + smoothing in a different way. The `level` parameter increases the amount of smoothness. This is the level of over sampling applied to the graphics buffer. - With the ``P2D`` and ``P3D`` renderers, ``smooth(2)`` is the default, this is - called "2x anti-aliasing." The code ``smooth(4)`` is used for 4x anti-aliasing - and ``smooth(8)`` is specified for "8x anti-aliasing." The maximum anti-aliasing - level is determined by the hardware of the machine that is running the software, - so ``smooth(4)`` and ``smooth(8)`` will not work with every computer. + With the `P2D` and `P3D` renderers, `smooth(2)` is the default, this is called + "2x anti-aliasing." The code `smooth(4)` is used for 4x anti-aliasing and + `smooth(8)` is specified for "8x anti-aliasing." The maximum anti-aliasing level + is determined by the hardware of the machine that is running the software, so + `smooth(4)` and `smooth(8)` will not work with every computer. - The default renderer uses ``smooth(3)`` by default. This is bicubic smoothing. - The other option for the default renderer is ``smooth(2)``, which is bilinear + The default renderer uses `smooth(3)` by default. This is bicubic smoothing. The + other option for the default renderer is `smooth(2)`, which is bilinear smoothing. - The ``smooth()`` function can only be set once within a Sketch. It is intended - to be called from the ``settings()`` function. The ``no_smooth()`` function - follows the same rules. + The `smooth()` function can only be set once within a Sketch. It is intended to + be called from the `settings()` function. The `no_smooth()` function follows the + same rules. When programming in module mode and imported mode, py5 will allow calls to - ``smooth()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `smooth()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``smooth()``, or calls to - ``size()``, ``full_screen()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `smooth()`, or calls to `size()`, + `full_screen()`, `no_smooth()`, or `pixel_density()`. Calls to those functions + must be at the very beginning of `setup()`, before any other Python code (but + comments are ok). This feature is not available when programming in class mode. """ pass @@ -15247,35 +15365,34 @@ def smooth(self, *args): ----- Draws all geometry with smooth (anti-aliased) edges. This behavior is the - default, so ``smooth()`` only needs to be used when a program needs to set the - smoothing in a different way. The ``level`` parameter increases the amount of + default, so `smooth()` only needs to be used when a program needs to set the + smoothing in a different way. The `level` parameter increases the amount of smoothness. This is the level of over sampling applied to the graphics buffer. - With the ``P2D`` and ``P3D`` renderers, ``smooth(2)`` is the default, this is - called "2x anti-aliasing." The code ``smooth(4)`` is used for 4x anti-aliasing - and ``smooth(8)`` is specified for "8x anti-aliasing." The maximum anti-aliasing - level is determined by the hardware of the machine that is running the software, - so ``smooth(4)`` and ``smooth(8)`` will not work with every computer. + With the `P2D` and `P3D` renderers, `smooth(2)` is the default, this is called + "2x anti-aliasing." The code `smooth(4)` is used for 4x anti-aliasing and + `smooth(8)` is specified for "8x anti-aliasing." The maximum anti-aliasing level + is determined by the hardware of the machine that is running the software, so + `smooth(4)` and `smooth(8)` will not work with every computer. - The default renderer uses ``smooth(3)`` by default. This is bicubic smoothing. - The other option for the default renderer is ``smooth(2)``, which is bilinear + The default renderer uses `smooth(3)` by default. This is bicubic smoothing. The + other option for the default renderer is `smooth(2)`, which is bilinear smoothing. - The ``smooth()`` function can only be set once within a Sketch. It is intended - to be called from the ``settings()`` function. The ``no_smooth()`` function - follows the same rules. + The `smooth()` function can only be set once within a Sketch. It is intended to + be called from the `settings()` function. The `no_smooth()` function follows the + same rules. When programming in module mode and imported mode, py5 will allow calls to - ``smooth()`` from the ``setup()`` function if it is called at the beginning of - ``setup()``. This allows the user to omit the ``settings()`` function, much like + `smooth()` from the `setup()` function if it is called at the beginning of + `setup()`. This allows the user to omit the `settings()` function, much like what can be done while programming in the Processing IDE. Py5 does this by - inspecting the ``setup()`` function and attempting to split it into synthetic - ``settings()`` and ``setup()`` functions if both were not created by the user - and the real ``setup()`` function contains a call to ``smooth()``, or calls to - ``size()``, ``full_screen()``, ``no_smooth()``, or ``pixel_density()``. Calls to - those functions must be at the very beginning of ``setup()``, before any other - Python code (but comments are ok). This feature is not available when - programming in class mode. + inspecting the `setup()` function and attempting to split it into synthetic + `settings()` and `setup()` functions if both were not created by the user and + the real `setup()` function contains a call to `smooth()`, or calls to `size()`, + `full_screen()`, `no_smooth()`, or `pixel_density()`. Calls to those functions + must be at the very beginning of `setup()`, before any other Python code (but + comments are ok). This feature is not available when programming in class mode. """ return self._instance.smooth(*args) @@ -15319,8 +15436,8 @@ def specular(self, gray: float, /) -> None: Sets the specular color of the materials used for shapes drawn to the screen, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a - diffuse light). Use in combination with ``emissive()``, ``ambient()``, and - ``shininess()`` to set the material properties of shapes. + diffuse light). Use in combination with `emissive()`, `ambient()`, and + `shininess()` to set the material properties of shapes. """ pass @@ -15364,8 +15481,8 @@ def specular(self, v1: float, v2: float, v3: float, /) -> None: Sets the specular color of the materials used for shapes drawn to the screen, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a - diffuse light). Use in combination with ``emissive()``, ``ambient()``, and - ``shininess()`` to set the material properties of shapes. + diffuse light). Use in combination with `emissive()`, `ambient()`, and + `shininess()` to set the material properties of shapes. """ pass @@ -15409,8 +15526,8 @@ def specular(self, rgb: int, /) -> None: Sets the specular color of the materials used for shapes drawn to the screen, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a - diffuse light). Use in combination with ``emissive()``, ``ambient()``, and - ``shininess()`` to set the material properties of shapes. + diffuse light). Use in combination with `emissive()`, `ambient()`, and + `shininess()` to set the material properties of shapes. """ pass @@ -15454,8 +15571,8 @@ def specular(self, *args): Sets the specular color of the materials used for shapes drawn to the screen, which sets the color of highlights. Specular refers to light which bounces off a surface in a preferred direction (rather than bouncing in all directions like a - diffuse light). Use in combination with ``emissive()``, ``ambient()``, and - ``shininess()`` to set the material properties of shapes. + diffuse light). Use in combination with `emissive()`, `ambient()`, and + `shininess()` to set the material properties of shapes. """ return self._instance.specular(*args) @@ -15509,11 +15626,11 @@ def sphere_detail(self, res: int, /) -> None: Controls the detail used to render a sphere by adjusting the number of vertices of the sphere mesh. The default resolution is 30, which creates a fairly - detailed sphere definition with vertices every ``360/30 = 12`` degrees. If - you're going to render a great number of spheres per frame, it is advised to - reduce the level of detail using this function. The setting stays active until - ``sphere_detail()`` is called again with a new parameter and so should *not* be - called prior to every ``sphere()`` statement, unless you wish to render spheres + detailed sphere definition with vertices every `360/30 = 12` degrees. If you're + going to render a great number of spheres per frame, it is advised to reduce the + level of detail using this function. The setting stays active until + `sphere_detail()` is called again with a new parameter and so should *not* be + called prior to every `sphere()` statement, unless you wish to render spheres with different settings, e.g. using less detail for smaller spheres or ones further away from the camera. To control the detail of the horizontal and vertical resolution independently, use the version of the functions with two @@ -15553,11 +15670,11 @@ def sphere_detail(self, ures: int, vres: int, /) -> None: Controls the detail used to render a sphere by adjusting the number of vertices of the sphere mesh. The default resolution is 30, which creates a fairly - detailed sphere definition with vertices every ``360/30 = 12`` degrees. If - you're going to render a great number of spheres per frame, it is advised to - reduce the level of detail using this function. The setting stays active until - ``sphere_detail()`` is called again with a new parameter and so should *not* be - called prior to every ``sphere()`` statement, unless you wish to render spheres + detailed sphere definition with vertices every `360/30 = 12` degrees. If you're + going to render a great number of spheres per frame, it is advised to reduce the + level of detail using this function. The setting stays active until + `sphere_detail()` is called again with a new parameter and so should *not* be + called prior to every `sphere()` statement, unless you wish to render spheres with different settings, e.g. using less detail for smaller spheres or ones further away from the camera. To control the detail of the horizontal and vertical resolution independently, use the version of the functions with two @@ -15596,11 +15713,11 @@ def sphere_detail(self, *args): Controls the detail used to render a sphere by adjusting the number of vertices of the sphere mesh. The default resolution is 30, which creates a fairly - detailed sphere definition with vertices every ``360/30 = 12`` degrees. If - you're going to render a great number of spheres per frame, it is advised to - reduce the level of detail using this function. The setting stays active until - ``sphere_detail()`` is called again with a new parameter and so should *not* be - called prior to every ``sphere()`` statement, unless you wish to render spheres + detailed sphere definition with vertices every `360/30 = 12` degrees. If you're + going to render a great number of spheres per frame, it is advised to reduce the + level of detail using this function. The setting stays active until + `sphere_detail()` is called again with a new parameter and so should *not* be + called prior to every `sphere()` statement, unless you wish to render spheres with different settings, e.g. using less detail for smaller spheres or ones further away from the camera. To control the detail of the horizontal and vertical resolution independently, use the version of the functions with two @@ -15665,15 +15782,14 @@ def spot_light( Notes ----- - Adds a spot light. Lights need to be included in the ``draw()`` to remain - persistent in a looping program. Placing them in the ``setup()`` of a looping + Adds a spot light. Lights need to be included in the `draw()` to remain + persistent in a looping program. Placing them in the `setup()` of a looping program will cause them to only have an effect the first time through the loop. - The ``v1``, ``v2``, and ``v3`` parameters are interpreted as either RGB or HSB - values, depending on the current color mode. The ``x``, ``y``, and ``z`` - parameters specify the position of the light and ``nx``, ``ny``, ``nz`` specify - the direction of light. The ``angle`` parameter affects angle of the spotlight - cone, while ``concentration`` sets the bias of light focusing toward the center - of that cone. + The `v1`, `v2`, and `v3` parameters are interpreted as either RGB or HSB values, + depending on the current color mode. The `x`, `y`, and `z` parameters specify + the position of the light and `nx`, `ny`, `nz` specify the direction of light. + The `angle` parameter affects angle of the spotlight cone, while `concentration` + sets the bias of light focusing toward the center of that cone. """ return self._instance.spotLight( v1, v2, v3, x, y, z, nx, ny, nz, angle, concentration) @@ -15702,7 +15818,7 @@ def square(self, x: float, y: float, extent: float, /) -> None: ninety degrees and each side is the same length. By default, the first two parameters set the location of the upper-left corner, the third sets the width and height. The way these parameters are interpreted, however, may be changed - with the ``rect_mode()`` function. + with the `rect_mode()` function. """ return self._instance.square(x, y, extent) @@ -15750,31 +15866,30 @@ def stroke(self, gray: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -15822,31 +15937,30 @@ def stroke(self, gray: float, alpha: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -15894,31 +16008,30 @@ def stroke(self, v1: float, v2: float, v3: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -15966,31 +16079,30 @@ def stroke(self, v1: float, v2: float, v3: float, alpha: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -16038,31 +16150,30 @@ def stroke(self, rgb: int, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -16110,31 +16221,30 @@ def stroke(self, rgb: int, alpha: float, /) -> None: Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ pass @@ -16182,31 +16292,30 @@ def stroke(self, *args): Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current - ``color_mode()``. The default color space is RGB, with each value in the range + `color_mode()`. The default color space is RGB, with each value in the range from 0 to 255. - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. When drawing in 2D with the default renderer, you may need - ``hint(ENABLE_STROKE_PURE)`` to improve drawing quality (at the expense of - performance). See the ``hint()`` documentation for more details. + `hint(ENABLE_STROKE_PURE)` to improve drawing quality (at the expense of + performance). See the `hint()` documentation for more details. """ return self._instance.stroke(*args) @@ -16226,10 +16335,10 @@ def stroke_cap(self, cap: int, /) -> None: Sets the style for rendering line endings. These ends are either squared, extended, or rounded, each of which specified with the corresponding parameters: - ``SQUARE``, ``PROJECT``, and ``ROUND``. The default cap is ``ROUND``. + `SQUARE`, `PROJECT`, and `ROUND`. The default cap is `ROUND`. - To make ``point()`` appear square, use ``stroke_cap(PROJECT)``. Using - ``stroke_cap(SQUARE)`` (no cap) causes points to become invisible. + To make `point()` appear square, use `stroke_cap(PROJECT)`. Using + `stroke_cap(SQUARE)` (no cap) causes points to become invisible. """ return self._instance.strokeCap(cap) @@ -16249,7 +16358,7 @@ def stroke_join(self, join: int, /) -> None: Sets the style of the joints which connect line segments. These joints are either mitered, beveled, or rounded and specified with the corresponding - parameters ``MITER``, ``BEVEL``, and ``ROUND``. The default joint is ``MITER``. + parameters `MITER`, `BEVEL`, and `ROUND`. The default joint is `MITER`. """ return self._instance.strokeJoin(join) @@ -16271,10 +16380,10 @@ def stroke_weight(self, weight: float, /) -> None: Sets the width of the stroke used for lines, points, and the border around shapes. All widths are set in units of pixels. - Using ``point()`` with ``strokeWeight(1)`` or smaller may draw nothing to the + Using `point()` with `strokeWeight(1)` or smaller may draw nothing to the screen, depending on the graphics settings of the computer. Workarounds include - setting the pixel using the ``pixels[]`` or ``np_pixels[]`` arrays or drawing - the point using either ``circle()`` or ``square()``. + setting the pixel using the `pixels[]` or `np_pixels[]` arrays or drawing the + point using either `circle()` or `square()`. """ return self._instance.strokeWeight(weight) @@ -16351,19 +16460,19 @@ def text(self, c: chr, x: float, y: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -16441,19 +16550,19 @@ def text(self, c: chr, x: float, y: float, z: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -16532,19 +16641,19 @@ def text(self, chars: list[chr], start: int, Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -16623,19 +16732,19 @@ def text(self, chars: list[chr], start: int, Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -16713,19 +16822,19 @@ def text(self, num: float, x: float, y: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -16803,19 +16912,19 @@ def text(self, num: float, x: float, y: float, z: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -16893,19 +17002,19 @@ def text(self, num: int, x: float, y: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -16983,19 +17092,19 @@ def text(self, num: int, x: float, y: float, z: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -17073,19 +17182,19 @@ def text(self, str: str, x: float, y: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -17163,19 +17272,19 @@ def text(self, str: str, x: float, y: float, z: float, /) -> None: Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -17254,19 +17363,19 @@ def text(self, str: str, x1: float, y1: float, Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ pass @@ -17344,19 +17453,19 @@ def text(self, *args): Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. - A default font will be used unless a font is set with the ``text_font()`` - function and a default size will be used unless a font is set with - ``text_size()``. Change the color of the text with the ``fill()`` function. The - text displays in relation to the ``text_align()`` function, which gives the - option to draw to the left, right, and center of the coordinates. - - The ``x2`` and ``y2`` parameters define a rectangular area to display within and - may only be used with string data. When these parameters are specified, they are - interpreted based on the current ``rect_mode()`` setting. Text that does not fit + A default font will be used unless a font is set with the `text_font()` function + and a default size will be used unless a font is set with `text_size()`. Change + the color of the text with the `fill()` function. The text displays in relation + to the `text_align()` function, which gives the option to draw to the left, + right, and center of the coordinates. + + The `x2` and `y2` parameters define a rectangular area to display within and may + only be used with string data. When these parameters are specified, they are + interpreted based on the current `rect_mode()` setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. - Note that py5 lets you call ``text()`` without first specifying a Py5Font with - ``text_font()``. In that case, a generic sans-serif font will be used instead. + Note that py5 lets you call `text()` without first specifying a Py5Font with + `text_font()`. In that case, a generic sans-serif font will be used instead. (See the third example.) """ return self._instance.text(*args) @@ -17387,27 +17496,26 @@ def text_align(self, align_x: int, /) -> None: Notes ----- - Sets the current alignment for drawing text. The parameters ``LEFT``, - ``CENTER``, and ``RIGHT`` set the display characteristics of the letters in - relation to the values for the ``x`` and ``y`` parameters of the ``text()`` - function. + Sets the current alignment for drawing text. The parameters `LEFT`, `CENTER`, + and `RIGHT` set the display characteristics of the letters in relation to the + values for the `x` and `y` parameters of the `text()` function. An optional second parameter can be used to vertically align the text. - ``BASELINE`` is the default, and the vertical alignment will be reset to - ``BASELINE`` if the second parameter is not used. The ``TOP`` and ``CENTER`` - parameters are straightforward. The ``BOTTOM`` parameter offsets the line based - on the current ``text_descent()``. For multiple lines, the final line will be - aligned to the bottom, with the previous lines appearing above it. - - When using ``text()`` with width and height parameters, ``BASELINE`` is ignored, - and treated as ``TOP``. (Otherwise, text would by default draw outside the box, - since ``BASELINE`` is the default setting. ``BASELINE`` is not a useful drawing - mode for text drawn in a rectangle.) - - The vertical alignment is based on the value of ``text_ascent()``, which many + `BASELINE` is the default, and the vertical alignment will be reset to + `BASELINE` if the second parameter is not used. The `TOP` and `CENTER` + parameters are straightforward. The `BOTTOM` parameter offsets the line based on + the current `text_descent()`. For multiple lines, the final line will be aligned + to the bottom, with the previous lines appearing above it. + + When using `text()` with width and height parameters, `BASELINE` is ignored, and + treated as `TOP`. (Otherwise, text would by default draw outside the box, since + `BASELINE` is the default setting. `BASELINE` is not a useful drawing mode for + text drawn in a rectangle.) + + The vertical alignment is based on the value of `text_ascent()`, which many fonts do not specify correctly. It may be necessary to use a hack and offset by a few pixels by hand so that the offset looks correct. To do this as less of a - hack, use some percentage of ``text_ascent()`` or ``text_descent()`` so that the + hack, use some percentage of `text_ascent()` or `text_descent()` so that the hack works even if you change the size of the font. """ pass @@ -17438,27 +17546,26 @@ def text_align(self, align_x: int, align_y: int, /) -> None: Notes ----- - Sets the current alignment for drawing text. The parameters ``LEFT``, - ``CENTER``, and ``RIGHT`` set the display characteristics of the letters in - relation to the values for the ``x`` and ``y`` parameters of the ``text()`` - function. + Sets the current alignment for drawing text. The parameters `LEFT`, `CENTER`, + and `RIGHT` set the display characteristics of the letters in relation to the + values for the `x` and `y` parameters of the `text()` function. An optional second parameter can be used to vertically align the text. - ``BASELINE`` is the default, and the vertical alignment will be reset to - ``BASELINE`` if the second parameter is not used. The ``TOP`` and ``CENTER`` - parameters are straightforward. The ``BOTTOM`` parameter offsets the line based - on the current ``text_descent()``. For multiple lines, the final line will be - aligned to the bottom, with the previous lines appearing above it. - - When using ``text()`` with width and height parameters, ``BASELINE`` is ignored, - and treated as ``TOP``. (Otherwise, text would by default draw outside the box, - since ``BASELINE`` is the default setting. ``BASELINE`` is not a useful drawing - mode for text drawn in a rectangle.) - - The vertical alignment is based on the value of ``text_ascent()``, which many + `BASELINE` is the default, and the vertical alignment will be reset to + `BASELINE` if the second parameter is not used. The `TOP` and `CENTER` + parameters are straightforward. The `BOTTOM` parameter offsets the line based on + the current `text_descent()`. For multiple lines, the final line will be aligned + to the bottom, with the previous lines appearing above it. + + When using `text()` with width and height parameters, `BASELINE` is ignored, and + treated as `TOP`. (Otherwise, text would by default draw outside the box, since + `BASELINE` is the default setting. `BASELINE` is not a useful drawing mode for + text drawn in a rectangle.) + + The vertical alignment is based on the value of `text_ascent()`, which many fonts do not specify correctly. It may be necessary to use a hack and offset by a few pixels by hand so that the offset looks correct. To do this as less of a - hack, use some percentage of ``text_ascent()`` or ``text_descent()`` so that the + hack, use some percentage of `text_ascent()` or `text_descent()` so that the hack works even if you change the size of the font. """ pass @@ -17488,27 +17595,26 @@ def text_align(self, *args): Notes ----- - Sets the current alignment for drawing text. The parameters ``LEFT``, - ``CENTER``, and ``RIGHT`` set the display characteristics of the letters in - relation to the values for the ``x`` and ``y`` parameters of the ``text()`` - function. + Sets the current alignment for drawing text. The parameters `LEFT`, `CENTER`, + and `RIGHT` set the display characteristics of the letters in relation to the + values for the `x` and `y` parameters of the `text()` function. An optional second parameter can be used to vertically align the text. - ``BASELINE`` is the default, and the vertical alignment will be reset to - ``BASELINE`` if the second parameter is not used. The ``TOP`` and ``CENTER`` - parameters are straightforward. The ``BOTTOM`` parameter offsets the line based - on the current ``text_descent()``. For multiple lines, the final line will be - aligned to the bottom, with the previous lines appearing above it. - - When using ``text()`` with width and height parameters, ``BASELINE`` is ignored, - and treated as ``TOP``. (Otherwise, text would by default draw outside the box, - since ``BASELINE`` is the default setting. ``BASELINE`` is not a useful drawing - mode for text drawn in a rectangle.) - - The vertical alignment is based on the value of ``text_ascent()``, which many + `BASELINE` is the default, and the vertical alignment will be reset to + `BASELINE` if the second parameter is not used. The `TOP` and `CENTER` + parameters are straightforward. The `BOTTOM` parameter offsets the line based on + the current `text_descent()`. For multiple lines, the final line will be aligned + to the bottom, with the previous lines appearing above it. + + When using `text()` with width and height parameters, `BASELINE` is ignored, and + treated as `TOP`. (Otherwise, text would by default draw outside the box, since + `BASELINE` is the default setting. `BASELINE` is not a useful drawing mode for + text drawn in a rectangle.) + + The vertical alignment is based on the value of `text_ascent()`, which many fonts do not specify correctly. It may be necessary to use a hack and offset by a few pixels by hand so that the offset looks correct. To do this as less of a - hack, use some percentage of ``text_ascent()`` or ``text_descent()`` so that the + hack, use some percentage of `text_ascent()` or `text_descent()` so that the hack works even if you change the size of the font. """ return self._instance.textAlign(*args) @@ -17541,7 +17647,7 @@ def text_descent(self) -> float: @overload def text_font(self, which: Py5Font, /) -> None: - """Sets the current font that will be drawn with the ``text()`` function. + """Sets the current font that will be drawn with the `text()` function. Underlying Processing method: PApplet.textFont @@ -17565,24 +17671,24 @@ def text_font(self, which: Py5Font, /) -> None: Notes ----- - Sets the current font that will be drawn with the ``text()`` function. Fonts - must be created for py5 with ``create_font()`` or loaded with ``load_font()`` - before they can be used. The font set through ``text_font()`` will be used in - all subsequent calls to the ``text()`` function. If no ``size`` parameter is - specified, the font size defaults to the original size (the size in which it was - created with ``create_font_file()``) overriding any previous calls to - ``text_font()`` or ``text_size()``. + Sets the current font that will be drawn with the `text()` function. Fonts must + be created for py5 with `create_font()` or loaded with `load_font()` before they + can be used. The font set through `text_font()` will be used in all subsequent + calls to the `text()` function. If no `size` parameter is specified, the font + size defaults to the original size (the size in which it was created with + `create_font_file()`) overriding any previous calls to `text_font()` or + `text_size()`. - When fonts are rendered as an image texture (as is the case with the ``P2D`` and - ``P3D`` renderers as well as with ``load_font()`` and vlw files), you should - create fonts at the sizes that will be used most commonly. Using ``text_font()`` - without the size parameter will result in the cleanest type. + When fonts are rendered as an image texture (as is the case with the `P2D` and + `P3D` renderers as well as with `load_font()` and vlw files), you should create + fonts at the sizes that will be used most commonly. Using `text_font()` without + the size parameter will result in the cleanest type. """ pass @overload def text_font(self, which: Py5Font, size: float, /) -> None: - """Sets the current font that will be drawn with the ``text()`` function. + """Sets the current font that will be drawn with the `text()` function. Underlying Processing method: PApplet.textFont @@ -17606,23 +17712,23 @@ def text_font(self, which: Py5Font, size: float, /) -> None: Notes ----- - Sets the current font that will be drawn with the ``text()`` function. Fonts - must be created for py5 with ``create_font()`` or loaded with ``load_font()`` - before they can be used. The font set through ``text_font()`` will be used in - all subsequent calls to the ``text()`` function. If no ``size`` parameter is - specified, the font size defaults to the original size (the size in which it was - created with ``create_font_file()``) overriding any previous calls to - ``text_font()`` or ``text_size()``. + Sets the current font that will be drawn with the `text()` function. Fonts must + be created for py5 with `create_font()` or loaded with `load_font()` before they + can be used. The font set through `text_font()` will be used in all subsequent + calls to the `text()` function. If no `size` parameter is specified, the font + size defaults to the original size (the size in which it was created with + `create_font_file()`) overriding any previous calls to `text_font()` or + `text_size()`. - When fonts are rendered as an image texture (as is the case with the ``P2D`` and - ``P3D`` renderers as well as with ``load_font()`` and vlw files), you should - create fonts at the sizes that will be used most commonly. Using ``text_font()`` - without the size parameter will result in the cleanest type. + When fonts are rendered as an image texture (as is the case with the `P2D` and + `P3D` renderers as well as with `load_font()` and vlw files), you should create + fonts at the sizes that will be used most commonly. Using `text_font()` without + the size parameter will result in the cleanest type. """ pass def text_font(self, *args): - """Sets the current font that will be drawn with the ``text()`` function. + """Sets the current font that will be drawn with the `text()` function. Underlying Processing method: PApplet.textFont @@ -17646,18 +17752,18 @@ def text_font(self, *args): Notes ----- - Sets the current font that will be drawn with the ``text()`` function. Fonts - must be created for py5 with ``create_font()`` or loaded with ``load_font()`` - before they can be used. The font set through ``text_font()`` will be used in - all subsequent calls to the ``text()`` function. If no ``size`` parameter is - specified, the font size defaults to the original size (the size in which it was - created with ``create_font_file()``) overriding any previous calls to - ``text_font()`` or ``text_size()``. + Sets the current font that will be drawn with the `text()` function. Fonts must + be created for py5 with `create_font()` or loaded with `load_font()` before they + can be used. The font set through `text_font()` will be used in all subsequent + calls to the `text()` function. If no `size` parameter is specified, the font + size defaults to the original size (the size in which it was created with + `create_font_file()`) overriding any previous calls to `text_font()` or + `text_size()`. - When fonts are rendered as an image texture (as is the case with the ``P2D`` and - ``P3D`` renderers as well as with ``load_font()`` and vlw files), you should - create fonts at the sizes that will be used most commonly. Using ``text_font()`` - without the size parameter will result in the cleanest type. + When fonts are rendered as an image texture (as is the case with the `P2D` and + `P3D` renderers as well as with `load_font()` and vlw files), you should create + fonts at the sizes that will be used most commonly. Using `text_font()` without + the size parameter will result in the cleanest type. """ return self._instance.textFont(*args) @@ -17676,10 +17782,10 @@ def text_leading(self, leading: float, /) -> None: ----- Sets the spacing between lines of text in units of pixels. This setting will be - used in all subsequent calls to the ``text()`` function. Note, however, that - the leading is reset by ``text_size()``. For example, if the leading is set to - 20 with ``text_leading(20)``, then if ``text_size(48)`` is run at a later point, - the leading will be reset to the default for the text size of 48. + used in all subsequent calls to the `text()` function. Note, however, that the + leading is reset by `text_size()`. For example, if the leading is set to 20 with + `text_leading(20)`, then if `text_size(48)` is run at a later point, the leading + will be reset to the default for the text size of 48. """ return self._instance.textLeading(leading) @@ -17699,19 +17805,19 @@ def text_mode(self, mode: int, /) -> None: ----- Sets the way text draws to the screen, either as texture maps or as vector - geometry. The default ``text_mode(MODEL)``, uses textures to render the fonts. - The ``text_mode(SHAPE)`` mode draws text using the glyph outlines of individual - characters rather than as textures. This mode is only supported with the ``PDF`` - and ``P3D`` renderer settings. With the ``PDF`` renderer, you must call - ``text_mode(SHAPE)`` before any other drawing occurs. If the outlines are not - available, then ``text_mode(SHAPE)`` will be ignored and ``text_mode(MODEL)`` - will be used instead. - - The ``text_mode(SHAPE)`` option in ``P3D`` can be combined with ``begin_raw()`` - to write vector-accurate text to 2D and 3D output files, for instance ``DXF`` or - ``PDF``. The ``SHAPE`` mode is not currently optimized for ``P3D``, so if - recording shape data, use ``text_mode(MODEL)`` until you're ready to capture the - geometry with ``begin_raw()``. + geometry. The default `text_mode(MODEL)`, uses textures to render the fonts. The + `text_mode(SHAPE)` mode draws text using the glyph outlines of individual + characters rather than as textures. This mode is only supported with the `PDF` + and `P3D` renderer settings. With the `PDF` renderer, you must call + `text_mode(SHAPE)` before any other drawing occurs. If the outlines are not + available, then `text_mode(SHAPE)` will be ignored and `text_mode(MODEL)` will + be used instead. + + The `text_mode(SHAPE)` option in `P3D` can be combined with `begin_raw()` to + write vector-accurate text to 2D and 3D output files, for instance `DXF` or + `PDF`. The `SHAPE` mode is not currently optimized for `P3D`, so if recording + shape data, use `text_mode(MODEL)` until you're ready to capture the geometry + with `begin_raw()`. """ return self._instance.textMode(mode) @@ -17730,7 +17836,7 @@ def text_size(self, size: float, /) -> None: ----- Sets the current font size. This size will be used in all subsequent calls to - the ``text()`` function. Font size is measured in units of pixels. + the `text()` function. Font size is measured in units of pixels. """ return self._instance.textSize(size) @@ -17895,7 +18001,7 @@ def text_width(self, *args): """ return self._instance.textWidth(*args) - @_auto_convert_to_py5image + @_auto_convert_to_py5image(0) def texture(self, image: Py5Image, /) -> None: """Sets a texture to be applied to vertex points. @@ -17910,11 +18016,11 @@ def texture(self, image: Py5Image, /) -> None: Notes ----- - Sets a texture to be applied to vertex points. The ``texture()`` method must be - called between ``begin_shape()`` and ``end_shape()`` and before any calls to - ``vertex()``. This method only works with the ``P2D`` and ``P3D`` renderers. + Sets a texture to be applied to vertex points. The `texture()` method must be + called between `begin_shape()` and `end_shape()` and before any calls to + `vertex()`. This method only works with the `P2D` and `P3D` renderers. - When textures are in use, the fill color is ignored. Instead, use ``tint()`` to + When textures are in use, the fill color is ignored. Instead, use `tint()` to specify the color of the texture as it is applied to the shape. """ return self._instance.texture(image) @@ -17933,14 +18039,14 @@ def texture_mode(self, mode: int, /) -> None: Notes ----- - Sets the coordinate space for texture mapping. The default mode is ``IMAGE``, - which refers to the actual pixel coordinates of the image. ``NORMAL`` refers to - a normalized space of values ranging from 0 to 1. This function only works with - the ``P2D`` and ``P3D`` renderers. + Sets the coordinate space for texture mapping. The default mode is `IMAGE`, + which refers to the actual pixel coordinates of the image. `NORMAL` refers to a + normalized space of values ranging from 0 to 1. This function only works with + the `P2D` and `P3D` renderers. - With ``IMAGE``, if an image is 100 x 200 pixels, mapping the image onto the - entire size of a quad would require the points (0,0) (100,0) (100,200) (0,200). - The same mapping in ``NORMAL`` is (0,0) (1,0) (1,1) (0,1). + With `IMAGE`, if an image is 100 x 200 pixels, mapping the image onto the entire + size of a quad would require the points (0,0) (100,0) (100,200) (0,200). The + same mapping in `NORMAL` is (0,0) (1,0) (1,1) (0,1). """ return self._instance.textureMode(mode) @@ -17959,8 +18065,8 @@ def texture_wrap(self, wrap: int, /) -> None: ----- Defines if textures repeat or draw once within a texture map. The two parameters - are ``CLAMP`` (the default behavior) and ``REPEAT``. This function only works - with the ``P2D`` and ``P3D`` renderers. + are `CLAMP` (the default behavior) and `REPEAT`. This function only works with + the `P2D` and `P3D` renderers. """ return self._instance.textureWrap(wrap) @@ -18010,30 +18116,29 @@ def tint(self, gray: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -18083,30 +18188,29 @@ def tint(self, gray: float, alpha: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -18156,30 +18260,29 @@ def tint(self, v1: float, v2: float, v3: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -18229,30 +18332,29 @@ def tint(self, v1: float, v2: float, v3: float, alpha: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -18302,30 +18404,29 @@ def tint(self, rgb: int, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -18375,30 +18476,29 @@ def tint(self, rgb: int, alpha: float, /) -> None: colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ pass @@ -18448,30 +18548,29 @@ def tint(self, *args): colors or made transparent by including an alpha value. To apply transparency to an image without affecting its color, use white as the - tint color and specify an alpha value. For instance, ``tint(255, 128)`` will - make an image 50% transparent (assuming the default alpha range of 0-255, which - can be changed with ``color_mode()``). + tint color and specify an alpha value. For instance, `tint(255, 128)` will make + an image 50% transparent (assuming the default alpha range of 0-255, which can + be changed with `color_mode()`). - When using hexadecimal notation to specify a color, use "``0x``" before the - values (e.g., ``0xFFCCFFAA``). The hexadecimal value must be specified with - eight characters; the first two characters define the alpha component, and the + When using hexadecimal notation to specify a color, use "`0x`" before the values + (e.g., `0xFFCCFFAA`). The hexadecimal value must be specified with eight + characters; the first two characters define the alpha component, and the remainder define the red, green, and blue components. When using web color notation to specify a color, create a string beginning with - the "``#``" character followed by three, four, six, or eight characters. The - example colors ``"#D93"`` and ``"#DD9933"`` specify red, green, and blue values - (in that order) for the color and assume the color has no transparency. The - example colors ``"#D93F"`` and ``"#DD9933FF"`` specify red, green, blue, and - alpha values (in that order) for the color. Notice that in web color notation - the alpha channel is last, which is consistent with CSS colors, and in - hexadecimal notation the alpha channel is first, which is consistent with - Processing color values. + the "`#`" character followed by three, four, six, or eight characters. The + example colors `"#D93"` and `"#DD9933"` specify red, green, and blue values (in + that order) for the color and assume the color has no transparency. The example + colors `"#D93F"` and `"#DD9933FF"` specify red, green, blue, and alpha values + (in that order) for the color. Notice that in web color notation the alpha + channel is last, which is consistent with CSS colors, and in hexadecimal + notation the alpha channel is first, which is consistent with Processing color + values. The value for the gray parameter must be less than or equal to the current - maximum value as specified by ``color_mode()``. The default maximum value is - 255. + maximum value as specified by `color_mode()`. The default maximum value is 255. - The ``tint()`` function is also used to control the coloring of textures in 3D. + The `tint()` function is also used to control the coloring of textures in 3D. """ return self._instance.tint(*args) @@ -18504,18 +18603,18 @@ def translate(self, x: float, y: float, /) -> None: Notes ----- - Specifies an amount to displace objects within the display window. The ``x`` - parameter specifies left/right translation, the ``y`` parameter specifies - up/down translation, and the ``z`` parameter specifies translations toward/away - from the screen. Using this function with the ``z`` parameter requires using - ``P3D`` as a parameter in combination with size as shown in the second example. + Specifies an amount to displace objects within the display window. The `x` + parameter specifies left/right translation, the `y` parameter specifies up/down + translation, and the `z` parameter specifies translations toward/away from the + screen. Using this function with the `z` parameter requires using `P3D` as a + parameter in combination with size as shown in the second example. Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. If ``translate()`` is called within ``draw()``, the - transformation is reset when the loop begins again. This function can be further - controlled by using ``push_matrix()`` and ``pop_matrix()``. + `translate(50, 0)` and then `translate(20, 0)` is the same as `translate(70, + 0)`. If `translate()` is called within `draw()`, the transformation is reset + when the loop begins again. This function can be further controlled by using + `push_matrix()` and `pop_matrix()`. """ pass @@ -18548,18 +18647,18 @@ def translate(self, x: float, y: float, z: float, /) -> None: Notes ----- - Specifies an amount to displace objects within the display window. The ``x`` - parameter specifies left/right translation, the ``y`` parameter specifies - up/down translation, and the ``z`` parameter specifies translations toward/away - from the screen. Using this function with the ``z`` parameter requires using - ``P3D`` as a parameter in combination with size as shown in the second example. + Specifies an amount to displace objects within the display window. The `x` + parameter specifies left/right translation, the `y` parameter specifies up/down + translation, and the `z` parameter specifies translations toward/away from the + screen. Using this function with the `z` parameter requires using `P3D` as a + parameter in combination with size as shown in the second example. Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. If ``translate()`` is called within ``draw()``, the - transformation is reset when the loop begins again. This function can be further - controlled by using ``push_matrix()`` and ``pop_matrix()``. + `translate(50, 0)` and then `translate(20, 0)` is the same as `translate(70, + 0)`. If `translate()` is called within `draw()`, the transformation is reset + when the loop begins again. This function can be further controlled by using + `push_matrix()` and `pop_matrix()`. """ pass @@ -18591,18 +18690,18 @@ def translate(self, *args): Notes ----- - Specifies an amount to displace objects within the display window. The ``x`` - parameter specifies left/right translation, the ``y`` parameter specifies - up/down translation, and the ``z`` parameter specifies translations toward/away - from the screen. Using this function with the ``z`` parameter requires using - ``P3D`` as a parameter in combination with size as shown in the second example. + Specifies an amount to displace objects within the display window. The `x` + parameter specifies left/right translation, the `y` parameter specifies up/down + translation, and the `z` parameter specifies translations toward/away from the + screen. Using this function with the `z` parameter requires using `P3D` as a + parameter in combination with size as shown in the second example. Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling - ``translate(50, 0)`` and then ``translate(20, 0)`` is the same as - ``translate(70, 0)``. If ``translate()`` is called within ``draw()``, the - transformation is reset when the loop begins again. This function can be further - controlled by using ``push_matrix()`` and ``pop_matrix()``. + `translate(50, 0)` and then `translate(20, 0)` is the same as `translate(70, + 0)`. If `translate()` is called within `draw()`, the transformation is reset + when the loop begins again. This function can be further controlled by using + `push_matrix()` and `pop_matrix()`. """ return self._instance.translate(*args) @@ -18644,7 +18743,7 @@ def triangle(self, x1: float, y1: float, x2: float, @overload def update_pixels(self) -> None: - """Updates the display window with the data in the ``pixels[]`` array. + """Updates the display window with the data in the `pixels[]` array. Underlying Processing method: PApplet.updatePixels @@ -18674,16 +18773,16 @@ def update_pixels(self) -> None: Notes ----- - Updates the display window with the data in the ``pixels[]`` array. Use in - conjunction with ``load_pixels()``. If you're only reading pixels from the - array, there's no need to call ``update_pixels()`` — updating is only necessary - to apply changes. + Updates the display window with the data in the `pixels[]` array. Use in + conjunction with `load_pixels()`. If you're only reading pixels from the array, + there's no need to call `update_pixels()` — updating is only necessary to apply + changes. """ pass @overload def update_pixels(self, x1: int, y1: int, x2: int, y2: int, /) -> None: - """Updates the display window with the data in the ``pixels[]`` array. + """Updates the display window with the data in the `pixels[]` array. Underlying Processing method: PApplet.updatePixels @@ -18713,15 +18812,15 @@ def update_pixels(self, x1: int, y1: int, x2: int, y2: int, /) -> None: Notes ----- - Updates the display window with the data in the ``pixels[]`` array. Use in - conjunction with ``load_pixels()``. If you're only reading pixels from the - array, there's no need to call ``update_pixels()`` — updating is only necessary - to apply changes. + Updates the display window with the data in the `pixels[]` array. Use in + conjunction with `load_pixels()`. If you're only reading pixels from the array, + there's no need to call `update_pixels()` — updating is only necessary to apply + changes. """ pass def update_pixels(self, *args): - """Updates the display window with the data in the ``pixels[]`` array. + """Updates the display window with the data in the `pixels[]` array. Underlying Processing method: PApplet.updatePixels @@ -18751,10 +18850,10 @@ def update_pixels(self, *args): Notes ----- - Updates the display window with the data in the ``pixels[]`` array. Use in - conjunction with ``load_pixels()``. If you're only reading pixels from the - array, there's no need to call ``update_pixels()`` — updating is only necessary - to apply changes. + Updates the display window with the data in the `pixels[]` array. Use in + conjunction with `load_pixels()`. If you're only reading pixels from the array, + there's no need to call `update_pixels()` — updating is only necessary to apply + changes. """ return self._instance.updatePixels(*args) @@ -18800,19 +18899,19 @@ def vertex(self, x: float, y: float, /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ pass @@ -18858,19 +18957,19 @@ def vertex(self, x: float, y: float, z: float, /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ pass @@ -18916,19 +19015,19 @@ def vertex(self, x: float, y: float, u: float, v: float, /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ pass @@ -18975,19 +19074,19 @@ def vertex(self, x: float, y: float, z: float, ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ pass @@ -19033,19 +19132,19 @@ def vertex(self, v: npt.NDArray[np.floating], /) -> None: ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ pass @@ -19090,22 +19189,23 @@ def vertex(self, *args): ----- Add a new vertex to a shape. All shapes are constructed by connecting a series - of vertices. The ``vertex()`` method is used to specify the vertex coordinates - for points, lines, triangles, quads, and polygons. It is used exclusively within - the ``begin_shape()`` and ``end_shape()`` functions. + of vertices. The `vertex()` method is used to specify the vertex coordinates for + points, lines, triangles, quads, and polygons. It is used exclusively within the + `begin_shape()` and `end_shape()` functions. - Drawing a vertex in 3D using the ``z`` parameter requires the ``P3D`` renderer, - as shown in the second example. + Drawing a vertex in 3D using the `z` parameter requires the `P3D` renderer, as + shown in the second example. - This method is also used to map a texture onto geometry. The ``texture()`` - function declares the texture to apply to the geometry and the ``u`` and ``v`` + This method is also used to map a texture onto geometry. The `texture()` + function declares the texture to apply to the geometry and the `u` and `v` coordinates define the mapping of this texture to the form. By default, the - coordinates used for ``u`` and ``v`` are specified in relation to the image's - size in pixels, but this relation can be changed with the Sketch's - ``texture_mode()`` method. + coordinates used for `u` and `v` are specified in relation to the image's size + in pixels, but this relation can be changed with the Sketch's `texture_mode()` + method. """ return self._instance.vertex(*args) + @_generator_to_list def vertices(self, coordinates: npt.NDArray[np.floating], /) -> None: """Create a collection of vertices. @@ -19121,10 +19221,10 @@ def vertices(self, coordinates: npt.NDArray[np.floating], /) -> None: ----- Create a collection of vertices. The purpose of this method is to provide an - alternative to repeatedly calling ``vertex()`` in a loop. For a large number of - vertices, the performance of ``vertices()`` will be much faster. + alternative to repeatedly calling `vertex()` in a loop. For a large number of + vertices, the performance of `vertices()` will be much faster. - The ``coordinates`` parameter should be a numpy array with one row for each + The `coordinates` parameter should be a numpy array with one row for each vertex. There should be two or three columns for 2D or 3D points, respectively. """ return self._instance.vertices(coordinates) @@ -19146,12 +19246,12 @@ def window_move(self, x: int, y: int, /) -> None: Notes ----- - Set the Sketch's window location. Calling this repeatedly from the ``draw()`` + Set the Sketch's window location. Calling this repeatedly from the `draw()` function may result in a sluggish Sketch. Negative or invalid coordinates are - ignored. To hide a Sketch window, use ``Py5Surface.set_visible()``. + ignored. To hide a Sketch window, use `Py5Surface.set_visible()`. - This method provides the same functionality as ``Py5Surface.set_location()`` but - without the need to interact directly with the ``Py5Surface`` object. + This method provides the same functionality as `Py5Surface.set_location()` but + without the need to interact directly with the `Py5Surface` object. """ return self._instance.windowMove(x, y) @@ -19179,24 +19279,24 @@ def window_ratio(self, wide: int, high: int, /) -> None: The usefulness of this feature is demonstrated in the example code. The size of the text will change as the window changes size. Observe the example makes two - calls to ``text_size()`` with fixed values of ``200`` and ``100``. Without this + calls to `text_size()` with fixed values of `200` and `100`. Without this feature, calculating the appropriate text size for all window sizes would be difficult. Similarly, positioning the text in the same relative location would - also involve several calculations. Using ``window_ratio()`` makes resizable + also involve several calculations. Using `window_ratio()` makes resizable Sketches that resize well easier to create. - When using this feature, use ``rmouse_x`` and ``rmouse_y`` to get the cursor - coordinates. The transformations involve calls to ``translate()`` and - ``scale()``, and the parameters to those methods can be accessed with - ``ratio_top``, ``ratio_left``, and ``ratio_scale``. The transformed coordinates - enabled with this feature can be negative for the top and left areas of the - window that do not fit the desired aspect ratio. Experimenting with the example - and seeing how the numbers change will provide more understanding than what can - be explained with words. + When using this feature, use `rmouse_x` and `rmouse_y` to get the cursor + coordinates. The transformations involve calls to `translate()` and `scale()`, + and the parameters to those methods can be accessed with `ratio_top`, + `ratio_left`, and `ratio_scale`. The transformed coordinates enabled with this + feature can be negative for the top and left areas of the window that do not fit + the desired aspect ratio. Experimenting with the example and seeing how the + numbers change will provide more understanding than what can be explained with + words. When calling this method, it is better to do so with values like - ``window_ratio(1280, 720)`` and not ``window_ratio(16, 9)``. The aspect ratio is - the same for both but the latter might result in floating point accuracy issues. + `window_ratio(1280, 720)` and not `window_ratio(16, 9)`. The aspect ratio is the + same for both but the latter might result in floating point accuracy issues. """ return self._instance.windowRatio(wide, high) @@ -19219,10 +19319,10 @@ def window_resizable(self, resizable: bool, /) -> None: By default, the Sketch window is not resizable. Changing the window size will clear the drawing canvas. If you do this, the - ``width`` and ``height`` variables will change. + `width` and `height` variables will change. - This method provides the same functionality as ``Py5Surface.set_resizable()`` - but without the need to interact directly with the ``Py5Surface`` object. + This method provides the same functionality as `Py5Surface.set_resizable()` but + without the need to interact directly with the `Py5Surface` object. """ return self._instance.windowResizable(resizable) @@ -19244,13 +19344,13 @@ def window_resize(self, new_width: int, new_height: int, /) -> None: ----- Set a new width and height for the Sketch window. You do not need to call - ``window_resizable()`` before calling this. + `window_resizable()` before calling this. Changing the window size will clear the drawing canvas. If you do this, the - ``width`` and ``height`` variables will change. + `width` and `height` variables will change. - This method provides the same functionality as ``Py5Surface.set_size()`` but - without the need to interact directly with the ``Py5Surface`` object. + This method provides the same functionality as `Py5Surface.set_size()` but + without the need to interact directly with the `Py5Surface` object. """ return self._instance.windowResize(new_width, new_height) @@ -19271,8 +19371,8 @@ def window_title(self, title: str, /) -> None: Set the Sketch window's title. This will typically appear at the window's title bar. The default window title is "Sketch". - This method provides the same functionality as ``Py5Surface.set_title()`` but - without the need to interact directly with the ``Py5Surface`` object. + This method provides the same functionality as `Py5Surface.set_title()` but + without the need to interact directly with the `Py5Surface` object. """ return self._instance.windowTitle(title) @@ -19285,7 +19385,7 @@ def year(cls) -> int: Notes ----- - Py5 communicates with the clock on your computer. The ``year()`` function - returns the current year as an integer (2003, 2004, 2005, etc). + Py5 communicates with the clock on your computer. The `year()` function returns + the current year as an integer (2003, 2004, 2005, etc). """ return cls._cls.year() diff --git a/py5/spelling.py b/py5/spelling.py new file mode 100644 index 0000000..2483eef --- /dev/null +++ b/py5/spelling.py @@ -0,0 +1,83 @@ +# ***************************************************************************** +# +# Part of the py5 library +# Copyright (C) 2020-2023 Jim Schmitz +# +# This library is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 2.1 of the License, or (at +# your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . +# +# ***************************************************************************** +import string + + +# many thanks to Peter Norvig for his spelling corrector tutorial: +# http://norvig.com/spell-correct.html + + +def edits1(word): + letters = (string.ascii_uppercase if word == word.upper() + else string.ascii_lowercase) + '_' + + splits = [(word[:i], word[i:]) for i in range(len(word) + 1)] + deletes = [L + R[1:] for L, R in splits if R] + transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R) > 1] + replaces = [L + c + R[1:] for L, R in splits if R for c in letters] + inserts = [L + c + R for L, R in splits for c in letters] + + return set(deletes + transposes + replaces + inserts) + + +def edits2(word): + return (e2 for e1 in edits1(word) for e2 in edits1(e1)) + + +def known(words, dictionary): + return list(set(w for w in words if w in dictionary)) + + +def candidates(word, dictionary): + if word in dictionary: + return set([word]) + else: + return known( + edits1(word), + dictionary) or ( + len(word) <= 10 and known( + edits2(word), + dictionary)) or [] + + +def suggestions(word, word_list): + words = ['"' + w + '"' for w in sorted(candidates(word, word_list))] + if len(words) == 0: + return None + elif len(words) == 1: + return words[0] + elif len(words) == 2: + return words[0] + ' or ' + words[1] + else: + return ', '.join(words[:-1]) + ', or ' + words[-1] + + +def error_msg(obj_name, word, obj, module=False): + msg = 'py5 has no field or function' if module else obj_name + \ + ' objects have no fields or methods' + msg += ' named "' + word + '"' + + if word and word[0] != '_' and ( + suggestion_list := suggestions( + word, set( + dir(obj)))): + msg += '. Did you mean ' + suggestion_list + '?' + + return msg diff --git a/py5/surface.py b/py5/surface.py index 99f162d..db0350f 100644 --- a/py5/surface.py +++ b/py5/surface.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -22,6 +22,7 @@ import weakref from .image import Py5Image # noqa +from . import spelling def _return_py5surface(f): @@ -55,6 +56,15 @@ def __new__(cls, psurface): cls._py5_object_cache.add(o) return o + def __str__(self) -> str: + return f"Py5Surface(id=" + str(id(self)) + ")" + + def __repr__(self) -> str: + return self.__str__() + + def __getattr__(self, name): + raise AttributeError(spelling.error_msg('Py5Surface', name, self)) + def get_native(self) -> Any: """Get the Sketch's Java native window object. @@ -83,14 +93,14 @@ def is_stopped(self) -> bool: ----- Determine if the surface is currently running an animation. A Sketch that has - called ``no_loop()`` or has no ``draw()`` function is not animating, and will - result in this method returning ``True``. If there is a ``draw()`` function and - ``no_loop()`` has not been called, this will return ``False``. Calling - Py5Surface's ``Py5Surface.stop_thread()`` will make all future calls to - ``is_stopped()`` return ``True``. - - The output of this method is independent of ``Py5Surface.pause_thread()`` and - ``Py5Surface.resume_thread()``. + called `no_loop()` or has no `draw()` function is not animating, and will result + in this method returning `True`. If there is a `draw()` function and `no_loop()` + has not been called, this will return `False`. Calling Py5Surface's + `Py5Surface.stop_thread()` will make all future calls to `is_stopped()` return + `True`. + + The output of this method is independent of `Py5Surface.pause_thread()` and + `Py5Surface.resume_thread()`. """ return self._instance.isStopped() @@ -103,12 +113,12 @@ def pause_thread(self) -> None: ----- Pause a running Sketch. The Sketch window will be static and unresponsive. You - can resume the Sketch with ``Py5Surface.resume_thread()``. + can resume the Sketch with `Py5Surface.resume_thread()`. - The ``frame_count`` will not increment while the Sketch is paused. + The `frame_count` will not increment while the Sketch is paused. Pausing a Sketch is not the same as stopping a Sketch, so this method will not - change the results of ``Py5Surface.is_stopped()``. + change the results of `Py5Surface.is_stopped()`. """ return self._instance.pauseThread() @@ -121,9 +131,9 @@ def resume_thread(self) -> None: ----- Resume a paused Sketch. The Sketch window will resume operating as it did before - ``Py5Surface.pause_thread()`` was called. + `Py5Surface.pause_thread()` was called. - The ``frame_count`` will continue incrementing after the Sketch is resumed. + The `frame_count` will continue incrementing after the Sketch is resumed. """ return self._instance.resumeThread() @@ -142,8 +152,8 @@ def set_always_on_top(self, always: bool, /) -> None: ----- Set the Sketch window to always be on top of other windows. By default, the - Sketch window can be covered by other windows. Setting this to ``True`` will - keep that from happening. + Sketch window can be covered by other windows. Setting this to `True` will keep + that from happening. """ return self._instance.setAlwaysOnTop(always) @@ -164,9 +174,9 @@ def set_icon(self, icon: Py5Image, /) -> None: Set the Sketch window icon. This will typically appear in the window's title bar. The default window icon is the same as Processing's. - This method will not work for the ``P2D`` or ``P3D`` renderers. Setting the icon - for those renderers is a bit tricky; the icon must be a PNG file and it must be - done in ``settings()``. See the second example to learn how to do that. + This method will not work for the `P2D` or `P3D` renderers. Setting the icon for + those renderers is a bit tricky; the icon must be a PNG file and it must be done + in `settings()`. See the second example to learn how to do that. """ return self._instance.setIcon(icon) @@ -187,11 +197,11 @@ def set_location(self, x: int, y: int, /) -> None: Notes ----- - Set the Sketch's window location. Calling this repeatedly from the ``draw()`` + Set the Sketch's window location. Calling this repeatedly from the `draw()` function may result in a sluggish Sketch. Negative or invalid coordinates are - ignored. To hide a Sketch window, use ``Py5Surface.set_visible()``. + ignored. To hide a Sketch window, use `Py5Surface.set_visible()`. - This method provides the same functionality as ``window_move()``. + This method provides the same functionality as `window_move()`. """ return self._instance.setLocation(x, y) @@ -214,9 +224,9 @@ def set_resizable(self, resizable: bool, /) -> None: By default, the Sketch window is not resizable. Changing the window size will clear the drawing canvas. If you do this, the - ``width`` and ``height`` variables will change. + `width` and `height` variables will change. - This method provides the same functionality as ``window_resizable()``. + This method provides the same functionality as `window_resizable()`. """ return self._instance.setResizable(resizable) @@ -238,12 +248,12 @@ def set_size(self, width: int, height: int, /) -> None: ----- Set a new width and height for the Sketch window. You do not need to call - ``Py5Surface.set_resizable()`` before calling this. + `Py5Surface.set_resizable()` before calling this. Changing the window size will clear the drawing canvas. If you do this, the - ``width`` and ``height`` variables will change. + `width` and `height` variables will change. - This method provides the same functionality as ``window_resize()``. + This method provides the same functionality as `window_resize()`. """ return self._instance.setSize(width, height) @@ -264,7 +274,7 @@ def set_title(self, title: str, /) -> None: Set the Sketch window's title. This will typically appear at the window's title bar. The default window title is "Sketch". - This method provides the same functionality as ``window_title()``. + This method provides the same functionality as `window_title()`. """ return self._instance.setTitle(title) @@ -296,11 +306,11 @@ def stop_thread(self) -> bool: ----- Stop the animation thread. The Sketch window will remain open but will be static - and unresponsive. Use ``Py5Surface.is_stopped()`` to determine if a Sketch has + and unresponsive. Use `Py5Surface.is_stopped()` to determine if a Sketch has been stopped or not. - This method is different from ``Py5Surface.pause_thread()`` in that it will - irreversably stop the animation. Use ``Py5Surface.pause_thread()`` and - ``Py5Surface.resume_thread()`` if you want to pause and resume a running Sketch. + This method is different from `Py5Surface.pause_thread()` in that it will + irreversably stop the animation. Use `Py5Surface.pause_thread()` and + `Py5Surface.resume_thread()` if you want to pause and resume a running Sketch. """ return self._instance.stopThread() diff --git a/py5/utilities.py b/py5/utilities.py new file mode 100644 index 0000000..e42445d --- /dev/null +++ b/py5/utilities.py @@ -0,0 +1,79 @@ +# ***************************************************************************** +# +# Part of the py5 library +# Copyright (C) 2020-2023 Jim Schmitz +# +# This library is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 2.1 of the License, or (at +# your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . +# +# ***************************************************************************** +import jpype + +from . import spelling + + +class Py5Utilities: + """Py5Utilities enables hybrid programming, enabling you to augment your py5 Sketch + code with Java. + + Notes + ----- + + Py5Utilities enables hybrid programming, enabling you to augment your py5 Sketch + code with Java. This is very much like creating custom Processing extensions to + enhance py5. Read the online documentation to learn more about how to use this + feature. + """ + + def __init__(self, sketch): + self._sketch = sketch + try: + self._instance = jpype.JClass( + 'py5utils.Py5Utilities')(sketch._instance) + self._dir = list(set(dir(self._instance)) - + set('equals getClass hashCode notify notifyAll wait toString'.split())) + except BaseException: + self._instance = None + self._dir = [] + + from .object_conversion import convert_to_python_type + self._convert_to_python_type = convert_to_python_type + + def __str__(self) -> str: + if self._instance is None: + return "Py5Utilities()" + else: + return "Py5Utilities(sketch=" + self._sketch.__str__() + ")" + + def __repr__(self) -> str: + return self.__str__() + + def __dir__(self): + return self._dir + + def __getattr__(self, name): + if self._instance is None: + raise AttributeError( + "Py5Utilities class was not instantiated for this Sketch. Check your classpath if you believe this to be an error.") + elif hasattr(self._instance, name): + attr = getattr(self._instance, name) + if callable(attr): + return lambda *args: self._convert_to_python_type(attr(*args)) + else: + return self._convert_to_python_type(attr) + else: + raise AttributeError( + spelling.error_msg( + 'Py5Utilities', + name, + self._instance)) diff --git a/py5/vector.py b/py5/vector.py index 2c32244..84283dc 100644 --- a/py5/vector.py +++ b/py5/vector.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -23,10 +23,13 @@ import operator from collections.abc import Sequence, Iterable import re +import warnings import numpy as np import numpy.typing as npt +from . import spelling + class Py5Vector(Sequence): """Class to describe a 2D, 3D, or 4D vector. @@ -36,12 +39,12 @@ class Py5Vector(Sequence): Class to describe a 2D, 3D, or 4D vector. A vector is an entity that has both a magnitude and a direction. This datatype stores the components of the vector as - a set of coordinates. A 3D vector, for example, has ``Py5Vector.x``, - ``Py5Vector.y``, and ``Py5Vector.z`` values that quantify the vector along the 3 + a set of coordinates. A 3D vector, for example, has `Py5Vector.x`, + `Py5Vector.y`, and `Py5Vector.z` values that quantify the vector along the 3 dimensions X, Y, and Z. The magnitude and direction can be accessed via the - properties ``Py5Vector.mag`` and ``Py5Vector.heading``. + properties `Py5Vector.mag` and `Py5Vector.heading`. - In many of the py5 examples, you will see ``Py5Vector`` used to describe a + In many of the py5 examples, you will see `Py5Vector` used to describe a position, velocity, or acceleration. For example, if you consider a rectangle moving across the screen, at any given instant it has a position (a vector that points from the origin to its location), a velocity (the rate at which the @@ -49,32 +52,30 @@ class Py5Vector(Sequence): acceleration (the rate at which the object's velocity changes per time unit, expressed as a vector). - The ``Py5Vector`` class works well with numpy and in most cases you will be able + The `Py5Vector` class works well with numpy and in most cases you will be able to do math operations that combine vectors and numpy arrays. - To create a vector, you can write code like ``v = Py5Vector(1, 2, 3)``, which + To create a vector, you can write code like `v = Py5Vector(1, 2, 3)`, which would create a 3D vector with the x, y, and z values equal to 1, 2, and 3. To create a vector of zeros, omit the vector values and specify the desired - dimension with the ``dim`` parameter, such as ``v = Py5Vector(dim=4)``. + dimension with the `dim` parameter, such as `v = Py5Vector(dim=4)`. Internally, Py5Vector stores the vector values in a numpy array. By default, the data type (dtype) of that numpy array is the default float size for your - computer, which is typically a 64 bit float, or ``np.float64``. To create a - vector with a different float size, pass your desired numpy float dtype to the - ``dtype`` parameter, like ``v3 = py5.Py5Vector(1 / 3, 1 / 7, - dtype=np.float16)``. + computer, which is typically a 64 bit float, or `np.float64`. To create a vector + with a different float size, pass your desired numpy float dtype to the `dtype` + parameter, like `v3 = py5.Py5Vector(1 / 3, 1 / 7, dtype=np.float16)`. When creating a new Py5Vector, the initial vector values need not be discrete values. You can provide a list of numbers, a numpy array, or another Py5Vector. - For example, ``v4 = py5.Py5Vector([1, 2, 3])`` creates a Py5Vector from a list, - and ``v5 = py5.Py5Vector(v4, 0)`` creates a 4D Py5Vector from a 3D Py5Vector and - a constant value. + For example, `v4 = py5.Py5Vector([1, 2, 3])` creates a Py5Vector from a list, + and `v5 = py5.Py5Vector(v4, 0)` creates a 4D Py5Vector from a 3D Py5Vector and a + constant value. When creating a new Py5Vector from a single numpy array, py5 will by default create its own copy of the numpy array for the Py5Vector to use. To instruct py5 to instead use the same numpy array and share its data with provided array, set - the ``copy`` parameter to ``False``, such as ``v6 = py5.Py5Vector(arr, - copy=False)``. + the `copy` parameter to `False`, such as `v6 = py5.Py5Vector(arr, copy=False)`. """ _DEFAULT_DIM = 3 @@ -196,8 +197,7 @@ def __getattr__(self, name): raise RuntimeError( 'Invalid swizzle: length must be between 2 and 4 characters') else: - raise AttributeError( - f"'Py5Vector' object has no attribute '{name}'") + raise AttributeError(spelling.error_msg('Py5Vector', name, self)) def __setattr__(self, name, val): if name.startswith('_') or not (hasattr(self, '_data') and not ( @@ -448,8 +448,7 @@ def astype(self, dtype) -> Py5Vector: ----- Create a new Py5Vector instance with a specified numpy dtype. Only floating - types (``np.float16``, ``np.float32``, ``np.float64``, and ``np.float128``) are - allowed. + types (`np.float16`, `np.float32`, `np.float64`, and `np.float128`) are allowed. """ return Py5Vector(self._data, dtype=dtype, copy=True) @@ -540,8 +539,8 @@ def _get_dtype(self) -> type: Notes ----- - Vector data type. This will be one of ``np.float16``, ``np.float32``, - ``np.float64``, or ``np.float128``. + Vector data type. This will be one of `np.float16`, `np.float32`, `np.float64`, + or `np.float128`. """ return self._data.dtype @@ -583,8 +582,8 @@ def _get_dtype(self) -> type: Notes ----- - Vector data type. This will be one of ``np.float16``, ``np.float32``, - ``np.float64``, or ``np.float128``.""") + Vector data type. This will be one of `np.float16`, `np.float32`, `np.float64`, + or `np.float128`.""") def _run_calc(self, other, calc, name, maybe_vector=False): other_type = 'numpy array' if isinstance( @@ -635,14 +634,14 @@ def lerp(self, ----- Calculates a vector between two vectors at a specific increment. The two vectors - must have the same dimension. The ``amt`` parameter is the amount to interpolate + must have the same dimension. The `amt` parameter is the amount to interpolate between the two values where 0.0 equal to the first point, 0.1 is very near the - first point, 0.5 is half-way in between, etc. If the ``amt`` parameter is - greater than 1.0 or less than 0.0, the interpolated vector will be outside of - the range specified by the two vectors. + first point, 0.5 is half-way in between, etc. If the `amt` parameter is greater + than 1.0 or less than 0.0, the interpolated vector will be outside of the range + specified by the two vectors. - This method is similar to ``lerp()`` and ``lerp_color()``, but for vectors - instead of numbers or colors. + This method is similar to `lerp()` and `lerp_color()`, but for vectors instead + of numbers or colors. """ return self._run_calc(other, lambda s, @@ -780,13 +779,12 @@ def set_mag(self, mag: float) -> Py5Vector: adjust the vector's magnitude to that value. Negative values will result in an error. """ - if mag < 0: - raise RuntimeError('Cannot set magnitude to a negative number') - elif mag == 0: + if mag == 0: self._data[:] = 0 else: self.normalize() self._data *= mag + return self def _get_mag_sq(self) -> float: @@ -836,7 +834,9 @@ def normalize(self) -> Py5Vector: self._data /= mag return self else: - raise RuntimeError('Cannot normalize Py5Vector of zeros') + warnings.warn( + 'Using normalize on a zero vector has no effect', + stacklevel=2) def _get_norm(self) -> Py5Vector: """Normalized copy of the vector. @@ -891,9 +891,9 @@ def set_limit(self, max_mag: float) -> Py5Vector: ----- Constrain the vector's magnitude to a specified value. If the vector's magnitude - is already less than or equal to ``max_mag``, this method will have no effect. - If the vector's magnitude is larger, it will be set to ``max_mag``. The - ``max_mag`` parameter cannot be a negative number. + is already less than or equal to `max_mag`, this method will have no effect. If + the vector's magnitude is larger, it will be set to `max_mag`. The `max_mag` + parameter cannot be a negative number. """ if max_mag < 0: raise RuntimeError('Cannot set limit to a negative number') @@ -921,7 +921,7 @@ def _get_heading(self) -> Union(float, tuple[float]): coordinates. The first heading value, inclination, is the angle relative to the positive z axis. The second heading value, azimuth, is the counter clockwise rotation of the vector around the z axis relative to the positive x axis. Note - that this is slightly different from p5's ``fromAngles()`` function, which also + that this is slightly different from p5's `fromAngles()` function, which also follows the ISO convention but measures angles relative to the top of the screen (negative y axis). @@ -965,7 +965,7 @@ def set_heading(self, *heading) -> Py5Vector: coordinates. The first heading value, inclination, is the angle relative to the positive z axis. The second heading value, azimuth, is the counter clockwise rotation of the vector around the z axis relative to the positive x axis. Note - that this is slightly different from p5's ``fromAngles()`` function, which also + that this is slightly different from p5's `fromAngles()` function, which also follows the ISO convention but measures angles relative to the top of the screen (negative y axis). @@ -1024,7 +1024,7 @@ def set_heading(self, *heading) -> Py5Vector: coordinates. The first heading value, inclination, is the angle relative to the positive z axis. The second heading value, azimuth, is the counter clockwise rotation of the vector around the z axis relative to the positive x axis. Note - that this is slightly different from p5's ``fromAngles()`` function, which also + that this is slightly different from p5's `fromAngles()` function, which also follows the ISO convention but measures angles relative to the top of the screen (negative y axis). @@ -1061,7 +1061,7 @@ def from_heading(cls, *heading, dtype: int = np.float_) -> Py5Vector: coordinates. The first heading value, inclination, is the angle relative to the positive z axis. The second heading value, azimuth, is the counter clockwise rotation of the vector around the z axis relative to the positive x axis. Note - that this is slightly different from p5's ``fromAngles()`` function, which also + that this is slightly different from p5's `fromAngles()` function, which also follows the ISO convention but measures angles relative to the top of the screen (negative y axis). @@ -1101,19 +1101,19 @@ def random(cls, dim: int, *, dtype: type = np.float_) -> Py5Vector: Notes ----- - Create a new vector with random values. Use the ``dim`` parameter to specify if + Create a new vector with random values. Use the `dim` parameter to specify if the vector should have 2, 3, or 4 dimensions. The new vector will have a magnitude of 1 and a heading that is uniformly distributed across all possible headings for a vector with the given dimension. - When used as a ``Py5Vector`` class method, the ``dim`` parameter is required to + When used as a `Py5Vector` class method, the `dim` parameter is required to specify what the new vector's dimension should be. When used as a class method - for the ``Py5Vector2D``, ``Py5Vector3D``, or ``Py5Vector4D`` child classes, the - ``dim`` parameter is optional and will default to the dimension implied by the - specific class. When used as a method on a vector instance, the ``dim`` - parameter is also optional and will default to the vector instance's dimension. - See the example code for examples of all of these use cases. + for the `Py5Vector2D`, `Py5Vector3D`, or `Py5Vector4D` child classes, the `dim` + parameter is optional and will default to the dimension implied by the specific + class. When used as a method on a vector instance, the `dim` parameter is also + optional and will default to the vector instance's dimension. See the example + code for examples of all of these use cases. """ if dim == 2: return Py5Vector( @@ -1144,12 +1144,12 @@ class Py5Vector2D(Py5Vector): Class to describe a 2D, 3D, or 4D vector. A vector is an entity that has both a magnitude and a direction. This datatype stores the components of the vector as - a set of coordinates. A 3D vector, for example, has ``Py5Vector.x``, - ``Py5Vector.y``, and ``Py5Vector.z`` values that quantify the vector along the 3 + a set of coordinates. A 3D vector, for example, has `Py5Vector.x`, + `Py5Vector.y`, and `Py5Vector.z` values that quantify the vector along the 3 dimensions X, Y, and Z. The magnitude and direction can be accessed via the - properties ``Py5Vector.mag`` and ``Py5Vector.heading``. + properties `Py5Vector.mag` and `Py5Vector.heading`. - In many of the py5 examples, you will see ``Py5Vector`` used to describe a + In many of the py5 examples, you will see `Py5Vector` used to describe a position, velocity, or acceleration. For example, if you consider a rectangle moving across the screen, at any given instant it has a position (a vector that points from the origin to its location), a velocity (the rate at which the @@ -1157,32 +1157,30 @@ class Py5Vector2D(Py5Vector): acceleration (the rate at which the object's velocity changes per time unit, expressed as a vector). - The ``Py5Vector`` class works well with numpy and in most cases you will be able + The `Py5Vector` class works well with numpy and in most cases you will be able to do math operations that combine vectors and numpy arrays. - To create a vector, you can write code like ``v = Py5Vector(1, 2, 3)``, which + To create a vector, you can write code like `v = Py5Vector(1, 2, 3)`, which would create a 3D vector with the x, y, and z values equal to 1, 2, and 3. To create a vector of zeros, omit the vector values and specify the desired - dimension with the ``dim`` parameter, such as ``v = Py5Vector(dim=4)``. + dimension with the `dim` parameter, such as `v = Py5Vector(dim=4)`. Internally, Py5Vector stores the vector values in a numpy array. By default, the data type (dtype) of that numpy array is the default float size for your - computer, which is typically a 64 bit float, or ``np.float64``. To create a - vector with a different float size, pass your desired numpy float dtype to the - ``dtype`` parameter, like ``v3 = py5.Py5Vector(1 / 3, 1 / 7, - dtype=np.float16)``. + computer, which is typically a 64 bit float, or `np.float64`. To create a vector + with a different float size, pass your desired numpy float dtype to the `dtype` + parameter, like `v3 = py5.Py5Vector(1 / 3, 1 / 7, dtype=np.float16)`. When creating a new Py5Vector, the initial vector values need not be discrete values. You can provide a list of numbers, a numpy array, or another Py5Vector. - For example, ``v4 = py5.Py5Vector([1, 2, 3])`` creates a Py5Vector from a list, - and ``v5 = py5.Py5Vector(v4, 0)`` creates a 4D Py5Vector from a 3D Py5Vector and - a constant value. + For example, `v4 = py5.Py5Vector([1, 2, 3])` creates a Py5Vector from a list, + and `v5 = py5.Py5Vector(v4, 0)` creates a 4D Py5Vector from a 3D Py5Vector and a + constant value. When creating a new Py5Vector from a single numpy array, py5 will by default create its own copy of the numpy array for the Py5Vector to use. To instruct py5 to instead use the same numpy array and share its data with provided array, set - the ``copy`` parameter to ``False``, such as ``v6 = py5.Py5Vector(arr, - copy=False)``. + the `copy` parameter to `False`, such as `v6 = py5.Py5Vector(arr, copy=False)`. """ def __new__(cls, *args, dtype: type = np.float_): @@ -1214,17 +1212,17 @@ def rotate(self, angle: float) -> Py5Vector2D: ----- Rotate vector by a specified angle. This method is only applicable to 2D and 3D - vectors. Use the ``angle`` parameter to specify the rotation angle. To rotate 3D - vectors, you must use the ``dim`` parameter to specify which dimension to rotate + vectors. Use the `angle` parameter to specify the rotation angle. To rotate 3D + vectors, you must use the `dim` parameter to specify which dimension to rotate around. The dimension can be specified with the values 1, 2, or 3, or by using - the strings ``'x'``, ``'y'``, or ``'z'``. + the strings `'x'`, `'y'`, or `'z'`. A 2D vector will be rotated in the counter-clockwise direction for positive - ``angle`` values and in the clockwise direction for negative ``angle`` values. + `angle` values and in the clockwise direction for negative `angle` values. A 3D vector's rotation will follow the right-hand rule. Using your right hand, point your thumb in the direction of the axis to rotate around. Your fingers - will curl in the direction of rotation when the ``angle`` parameter is positive. + will curl in the direction of rotation when the `angle` parameter is positive. """ sin_angle = np.sin(angle) cos_angle = np.cos(angle) @@ -1250,19 +1248,19 @@ def random(cls, dim: int = 2, *, dtype: type = np.float_) -> Py5Vector2D: Notes ----- - Create a new vector with random values. Use the ``dim`` parameter to specify if + Create a new vector with random values. Use the `dim` parameter to specify if the vector should have 2, 3, or 4 dimensions. The new vector will have a magnitude of 1 and a heading that is uniformly distributed across all possible headings for a vector with the given dimension. - When used as a ``Py5Vector`` class method, the ``dim`` parameter is required to + When used as a `Py5Vector` class method, the `dim` parameter is required to specify what the new vector's dimension should be. When used as a class method - for the ``Py5Vector2D``, ``Py5Vector3D``, or ``Py5Vector4D`` child classes, the - ``dim`` parameter is optional and will default to the dimension implied by the - specific class. When used as a method on a vector instance, the ``dim`` - parameter is also optional and will default to the vector instance's dimension. - See the example code for examples of all of these use cases. + for the `Py5Vector2D`, `Py5Vector3D`, or `Py5Vector4D` child classes, the `dim` + parameter is optional and will default to the dimension implied by the specific + class. When used as a method on a vector instance, the `dim` parameter is also + optional and will default to the vector instance's dimension. See the example + code for examples of all of these use cases. """ return super().random(dim, dtype=dtype) @@ -1275,12 +1273,12 @@ class Py5Vector3D(Py5Vector): Class to describe a 2D, 3D, or 4D vector. A vector is an entity that has both a magnitude and a direction. This datatype stores the components of the vector as - a set of coordinates. A 3D vector, for example, has ``Py5Vector.x``, - ``Py5Vector.y``, and ``Py5Vector.z`` values that quantify the vector along the 3 + a set of coordinates. A 3D vector, for example, has `Py5Vector.x`, + `Py5Vector.y`, and `Py5Vector.z` values that quantify the vector along the 3 dimensions X, Y, and Z. The magnitude and direction can be accessed via the - properties ``Py5Vector.mag`` and ``Py5Vector.heading``. + properties `Py5Vector.mag` and `Py5Vector.heading`. - In many of the py5 examples, you will see ``Py5Vector`` used to describe a + In many of the py5 examples, you will see `Py5Vector` used to describe a position, velocity, or acceleration. For example, if you consider a rectangle moving across the screen, at any given instant it has a position (a vector that points from the origin to its location), a velocity (the rate at which the @@ -1288,32 +1286,30 @@ class Py5Vector3D(Py5Vector): acceleration (the rate at which the object's velocity changes per time unit, expressed as a vector). - The ``Py5Vector`` class works well with numpy and in most cases you will be able + The `Py5Vector` class works well with numpy and in most cases you will be able to do math operations that combine vectors and numpy arrays. - To create a vector, you can write code like ``v = Py5Vector(1, 2, 3)``, which + To create a vector, you can write code like `v = Py5Vector(1, 2, 3)`, which would create a 3D vector with the x, y, and z values equal to 1, 2, and 3. To create a vector of zeros, omit the vector values and specify the desired - dimension with the ``dim`` parameter, such as ``v = Py5Vector(dim=4)``. + dimension with the `dim` parameter, such as `v = Py5Vector(dim=4)`. Internally, Py5Vector stores the vector values in a numpy array. By default, the data type (dtype) of that numpy array is the default float size for your - computer, which is typically a 64 bit float, or ``np.float64``. To create a - vector with a different float size, pass your desired numpy float dtype to the - ``dtype`` parameter, like ``v3 = py5.Py5Vector(1 / 3, 1 / 7, - dtype=np.float16)``. + computer, which is typically a 64 bit float, or `np.float64`. To create a vector + with a different float size, pass your desired numpy float dtype to the `dtype` + parameter, like `v3 = py5.Py5Vector(1 / 3, 1 / 7, dtype=np.float16)`. When creating a new Py5Vector, the initial vector values need not be discrete values. You can provide a list of numbers, a numpy array, or another Py5Vector. - For example, ``v4 = py5.Py5Vector([1, 2, 3])`` creates a Py5Vector from a list, - and ``v5 = py5.Py5Vector(v4, 0)`` creates a 4D Py5Vector from a 3D Py5Vector and - a constant value. + For example, `v4 = py5.Py5Vector([1, 2, 3])` creates a Py5Vector from a list, + and `v5 = py5.Py5Vector(v4, 0)` creates a 4D Py5Vector from a 3D Py5Vector and a + constant value. When creating a new Py5Vector from a single numpy array, py5 will by default create its own copy of the numpy array for the Py5Vector to use. To instruct py5 to instead use the same numpy array and share its data with provided array, set - the ``copy`` parameter to ``False``, such as ``v6 = py5.Py5Vector(arr, - copy=False)``. + the `copy` parameter to `False`, such as `v6 = py5.Py5Vector(arr, copy=False)`. """ def __new__(cls, *args, dtype: type = np.float_): @@ -1375,17 +1371,17 @@ def rotate(self, angle: float, dim: Union[int, str]) -> Py5Vector3D: ----- Rotate vector by a specified angle. This method is only applicable to 2D and 3D - vectors. Use the ``angle`` parameter to specify the rotation angle. To rotate 3D - vectors, you must use the ``dim`` parameter to specify which dimension to rotate + vectors. Use the `angle` parameter to specify the rotation angle. To rotate 3D + vectors, you must use the `dim` parameter to specify which dimension to rotate around. The dimension can be specified with the values 1, 2, or 3, or by using - the strings ``'x'``, ``'y'``, or ``'z'``. + the strings `'x'`, `'y'`, or `'z'`. A 2D vector will be rotated in the counter-clockwise direction for positive - ``angle`` values and in the clockwise direction for negative ``angle`` values. + `angle` values and in the clockwise direction for negative `angle` values. A 3D vector's rotation will follow the right-hand rule. Using your right hand, point your thumb in the direction of the axis to rotate around. Your fingers - will curl in the direction of rotation when the ``angle`` parameter is positive. + will curl in the direction of rotation when the `angle` parameter is positive. """ sin_angle = np.sin(angle) cos_angle = np.cos(angle) @@ -1420,14 +1416,14 @@ def rotate_around(self, angle: float, v: Py5Vector3D) -> Py5Vector3D: ----- Rotate around an arbitrary 3D vector. This method is only applicable to 3D - vectors. Use the ``angle`` parameter to specify the rotation angle and the ``v`` - parameter to specify the vector to rotate around. The ``v`` vector does not need + vectors. Use the `angle` parameter to specify the rotation angle and the `v` + parameter to specify the vector to rotate around. The `v` vector does not need to be aligned to any axis or normalized, but it must be a 3D vector and it cannot be a vector of zeros. The vector's rotation will follow the right-hand rule. Using your right hand, point your thumb in the direction of the vector to rotate around. Your fingers - will curl in the direction of rotation when the ``angle`` parameter is positive. + will curl in the direction of rotation when the `angle` parameter is positive. """ if not isinstance(v, Py5Vector3D): raise RuntimeError('Can only rotate around another 3D Py5Vector') @@ -1492,19 +1488,19 @@ def random(cls, dim: int = 3, *, dtype: type = np.float_) -> Py5Vector3D: Notes ----- - Create a new vector with random values. Use the ``dim`` parameter to specify if + Create a new vector with random values. Use the `dim` parameter to specify if the vector should have 2, 3, or 4 dimensions. The new vector will have a magnitude of 1 and a heading that is uniformly distributed across all possible headings for a vector with the given dimension. - When used as a ``Py5Vector`` class method, the ``dim`` parameter is required to + When used as a `Py5Vector` class method, the `dim` parameter is required to specify what the new vector's dimension should be. When used as a class method - for the ``Py5Vector2D``, ``Py5Vector3D``, or ``Py5Vector4D`` child classes, the - ``dim`` parameter is optional and will default to the dimension implied by the - specific class. When used as a method on a vector instance, the ``dim`` - parameter is also optional and will default to the vector instance's dimension. - See the example code for examples of all of these use cases. + for the `Py5Vector2D`, `Py5Vector3D`, or `Py5Vector4D` child classes, the `dim` + parameter is optional and will default to the dimension implied by the specific + class. When used as a method on a vector instance, the `dim` parameter is also + optional and will default to the vector instance's dimension. See the example + code for examples of all of these use cases. """ return super().random(dim, dtype=dtype) @@ -1517,12 +1513,12 @@ class Py5Vector4D(Py5Vector): Class to describe a 2D, 3D, or 4D vector. A vector is an entity that has both a magnitude and a direction. This datatype stores the components of the vector as - a set of coordinates. A 3D vector, for example, has ``Py5Vector.x``, - ``Py5Vector.y``, and ``Py5Vector.z`` values that quantify the vector along the 3 + a set of coordinates. A 3D vector, for example, has `Py5Vector.x`, + `Py5Vector.y`, and `Py5Vector.z` values that quantify the vector along the 3 dimensions X, Y, and Z. The magnitude and direction can be accessed via the - properties ``Py5Vector.mag`` and ``Py5Vector.heading``. + properties `Py5Vector.mag` and `Py5Vector.heading`. - In many of the py5 examples, you will see ``Py5Vector`` used to describe a + In many of the py5 examples, you will see `Py5Vector` used to describe a position, velocity, or acceleration. For example, if you consider a rectangle moving across the screen, at any given instant it has a position (a vector that points from the origin to its location), a velocity (the rate at which the @@ -1530,32 +1526,30 @@ class Py5Vector4D(Py5Vector): acceleration (the rate at which the object's velocity changes per time unit, expressed as a vector). - The ``Py5Vector`` class works well with numpy and in most cases you will be able + The `Py5Vector` class works well with numpy and in most cases you will be able to do math operations that combine vectors and numpy arrays. - To create a vector, you can write code like ``v = Py5Vector(1, 2, 3)``, which + To create a vector, you can write code like `v = Py5Vector(1, 2, 3)`, which would create a 3D vector with the x, y, and z values equal to 1, 2, and 3. To create a vector of zeros, omit the vector values and specify the desired - dimension with the ``dim`` parameter, such as ``v = Py5Vector(dim=4)``. + dimension with the `dim` parameter, such as `v = Py5Vector(dim=4)`. Internally, Py5Vector stores the vector values in a numpy array. By default, the data type (dtype) of that numpy array is the default float size for your - computer, which is typically a 64 bit float, or ``np.float64``. To create a - vector with a different float size, pass your desired numpy float dtype to the - ``dtype`` parameter, like ``v3 = py5.Py5Vector(1 / 3, 1 / 7, - dtype=np.float16)``. + computer, which is typically a 64 bit float, or `np.float64`. To create a vector + with a different float size, pass your desired numpy float dtype to the `dtype` + parameter, like `v3 = py5.Py5Vector(1 / 3, 1 / 7, dtype=np.float16)`. When creating a new Py5Vector, the initial vector values need not be discrete values. You can provide a list of numbers, a numpy array, or another Py5Vector. - For example, ``v4 = py5.Py5Vector([1, 2, 3])`` creates a Py5Vector from a list, - and ``v5 = py5.Py5Vector(v4, 0)`` creates a 4D Py5Vector from a 3D Py5Vector and - a constant value. + For example, `v4 = py5.Py5Vector([1, 2, 3])` creates a Py5Vector from a list, + and `v5 = py5.Py5Vector(v4, 0)` creates a 4D Py5Vector from a 3D Py5Vector and a + constant value. When creating a new Py5Vector from a single numpy array, py5 will by default create its own copy of the numpy array for the Py5Vector to use. To instruct py5 to instead use the same numpy array and share its data with provided array, set - the ``copy`` parameter to ``False``, such as ``v6 = py5.Py5Vector(arr, - copy=False)``. + the `copy` parameter to `False`, such as `v6 = py5.Py5Vector(arr, copy=False)`. """ def __new__(cls, *args, dtype: type = np.float_): @@ -1636,18 +1630,18 @@ def random(cls, dim: int = 4, *, dtype: type = np.float_) -> Py5Vector4D: Notes ----- - Create a new vector with random values. Use the ``dim`` parameter to specify if + Create a new vector with random values. Use the `dim` parameter to specify if the vector should have 2, 3, or 4 dimensions. The new vector will have a magnitude of 1 and a heading that is uniformly distributed across all possible headings for a vector with the given dimension. - When used as a ``Py5Vector`` class method, the ``dim`` parameter is required to + When used as a `Py5Vector` class method, the `dim` parameter is required to specify what the new vector's dimension should be. When used as a class method - for the ``Py5Vector2D``, ``Py5Vector3D``, or ``Py5Vector4D`` child classes, the - ``dim`` parameter is optional and will default to the dimension implied by the - specific class. When used as a method on a vector instance, the ``dim`` - parameter is also optional and will default to the vector instance's dimension. - See the example code for examples of all of these use cases. + for the `Py5Vector2D`, `Py5Vector3D`, or `Py5Vector4D` child classes, the `dim` + parameter is optional and will default to the dimension implied by the specific + class. When used as a method on a vector instance, the `dim` parameter is also + optional and will default to the vector instance's dimension. See the example + code for examples of all of these use cases. """ return super().random(dim, dtype=dtype) diff --git a/py5_tools/__init__.py b/py5_tools/__init__.py index 770a343..8957c2a 100644 --- a/py5_tools/__init__.py +++ b/py5_tools/__init__.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -28,4 +28,4 @@ from . import translators # noqa -__version__ = '0.8.3a1' +__version__ = '0.9.0a0' diff --git a/py5_tools/config.py b/py5_tools/config.py index 92fabe4..a53d67a 100644 --- a/py5_tools/config.py +++ b/py5_tools/config.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -17,7 +17,7 @@ # along with this library. If not, see . # # ***************************************************************************** -from typing import Union +from typing import Union, Callable from types import ModuleType @@ -26,7 +26,32 @@ def register_processing_mode_key( - key: str, value: Union[callable, ModuleType], *, callback_once: bool = False): + key: str, value: Union[Callable, ModuleType], *, callback_once: bool = False): + """Register a callable or module when programming in py5's Processing Mode. + + Parameters + ---------- + + callback_once: bool = False + deregister key after single use + + key: str + key used from Processing Mode callPython() method + + value: Union[Callable, ModuleType] + callable or module to link to key + + Notes + ----- + + Register a callable or module when programming in py5's Processing Mode. This + will make Python code available to Processing Mode py5 users to call in Java + with the `callPython()` method. Please read py5's online documentation to learn + more about Processing Mode. + + The `value` parameter can be a callable, a module or an object. If `value` is a + module or an object, the `key` parameter in the Java `callPython()` call should + use dots ("`.`") to access the module's or object's callables.""" _PY5_PROCESSING_MODE_KEYS[key] = value if callback_once: _PY5_PROCESSING_MODE_CALLBACK_ONCE.add(key) diff --git a/py5_tools/environ.py b/py5_tools/environ.py index ed3da24..80ad109 100644 --- a/py5_tools/environ.py +++ b/py5_tools/environ.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by diff --git a/py5_tools/hooks/__init__.py b/py5_tools/hooks/__init__.py index a8cdc96..0d26f43 100644 --- a/py5_tools/hooks/__init__.py +++ b/py5_tools/hooks/__init__.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by diff --git a/py5_tools/hooks/frame_hooks.py b/py5_tools/hooks/frame_hooks.py index 5b0c3aa..2214a3e 100644 --- a/py5_tools/hooks/frame_hooks.py +++ b/py5_tools/hooks/frame_hooks.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -59,17 +59,17 @@ def screenshot( Take a screenshot of a running Sketch. - The returned image is a ``PIL.Image`` object. It can be assigned to a variable - or embedded in the notebook. + The returned image is a `PIL.Image` object. It can be assigned to a variable or + embedded in the notebook. By default the Sketch will be the currently running Sketch, as returned by - ``get_current_sketch()``. Use the ``sketch`` parameter to specify a different + `get_current_sketch()`. Use the `sketch` parameter to specify a different running Sketch, such as a Sketch created using Class mode. - If your Sketch has a ``post_draw()`` method, use the ``hook_post_draw`` - parameter to make this function run after ``post_draw()`` instead of ``draw()``. - This is important when using Processing libraries that support ``post_draw()`` - such as Camera3D or ColorBlindness.""" + If your Sketch has a `post_draw()` method, use the `hook_post_draw` parameter to + make this function run after `post_draw()` instead of `draw()`. This is + important when using Processing libraries that support `post_draw()` such as + Camera3D or ColorBlindness.""" import py5 if sketch is None: sketch = py5.get_current_sketch() @@ -107,7 +107,7 @@ def screenshot( def save_frames(dirname: str, *, filename: str = 'frame_####.png', period: float = 0.0, start: int = None, limit: int = 0, sketch: Sketch = None, hook_post_draw: bool = False, - block: bool = False) -> None: + block: bool = False, display_progress: bool = True) -> None: """Save a running Sketch's frames to a directory. Parameters @@ -119,6 +119,9 @@ def save_frames(dirname: str, *, filename: str = 'frame_####.png', dirname: str directory to save the frames + display_progress: bool = True + display progress as frames are saved + filename: str = 'frame_####.png' filename template to use for saved frames @@ -144,23 +147,28 @@ def save_frames(dirname: str, *, filename: str = 'frame_####.png', By default this function will return right away and save frames in the background while the Sketch is running. The frames will be saved in the - directory specified by the ``dirname`` parameter. Set the ``block`` parameter to - ``True`` to instruct the method to not return until the number of frames saved - reaches the number specified by the ``limit`` parameter. This blocking feature - is not available on OSX when the Sketch is executed through an IPython kernel. + directory specified by the `dirname` parameter. Set the `block` parameter to + `True` to instruct the method to not return until the number of frames saved + reaches the number specified by the `limit` parameter. This blocking feature is + not available on OSX when the Sketch is executed through an IPython kernel. By default the Sketch will be the currently running Sketch, as returned by - ``get_current_sketch()``. Use the ``sketch`` parameter to specify a different + `get_current_sketch()`. Use the `sketch` parameter to specify a different running Sketch, such as a Sketch created using Class mode. - If the ``limit`` parameter is used, this function will wait to return a list of + If the `limit` parameter is used, this function will wait to return a list of the filenames. If not, it will return right away as the frames are saved in the background. It will keep doing so as long as the Sketch continues to run. - If your Sketch has a ``post_draw()`` method, use the ``hook_post_draw`` - parameter to make this function run after ``post_draw()`` instead of ``draw()``. - This is important when using Processing libraries that support ``post_draw()`` - such as Camera3D or ColorBlindness.""" + By default this function will report its progress as frames are saved. If you + are using a Jupyter Notebook and happen to be saving tens of thousands of + frames, this might cause Jupyter to crash. To avoid that fate, set the + `display_progress` parameter to `False`. + + If your Sketch has a `post_draw()` method, use the `hook_post_draw` parameter to + make this function run after `post_draw()` instead of `draw()`. This is + important when using Processing libraries that support `post_draw()` such as + Camera3D or ColorBlindness.""" import py5 if sketch is None: sketch = py5.get_current_sketch() @@ -186,7 +194,13 @@ def save_frames(dirname: str, *, filename: str = 'frame_####.png', if not dirname.exists(): dirname.mkdir(parents=True) - hook = SaveFramesHook(dirname, filename, period, start, limit) + hook = SaveFramesHook( + dirname, + filename, + period, + start, + limit, + display_progress) sketch._add_post_hook( 'post_draw' if hook_post_draw else 'draw', hook.hook_name, @@ -245,42 +259,41 @@ def offline_frame_processing(func: Callable[[npt.NDArray[np.uint8]], None], *, Process Sketch frames in a separate thread that will minimize the performance impact on the Sketch's main animation thread. As the Sketch runs it will place a numpy array of the frame's pixels in a queue that will be later passed to the - user provided processing function (the ``func`` parameter). That function should - not call any Sketch methods. The ``offline_frame_processing()`` functionality is + user provided processing function (the `func` parameter). That function should + not call any Sketch methods. The `offline_frame_processing()` functionality is well suited for goals such as live-streaming to YouTube or encoding a video file, both of which might otherwise impact the Sketch's frame rate significantly. The user provided processing function must take a single numpy array as a - parameter. That numpy array will have a shape of ``(batch size, height, width, - 3)`` and have a dtype of ``np.uint8``. The ``batch_size`` parameter defaults to - 1 but can be set to other values to stack frames together into a larger array. + parameter. That numpy array will have a shape of `(batch size, height, width, + 3)` and have a dtype of `np.uint8`. The `batch_size` parameter defaults to 1 but + can be set to other values to stack frames together into a larger array. Therefore a "batch" will consist of one or more frames. - Use the ``limit`` parameter to stop frame processing after a set number of - frames. You can also use the ``stop_processing_func`` parameter to provide a - callable that returns ``True`` when processing should complete (which will stop - right away and ignore unprocessed frames in the queue). Use the - ``complete_func`` parameter to pass a function that will be called once after - frame processing has stopped. + Use the `limit` parameter to stop frame processing after a set number of frames. + You can also use the `stop_processing_func` parameter to provide a callable that + returns `True` when processing should complete (which will stop right away and + ignore unprocessed frames in the queue). Use the `complete_func` parameter to + pass a function that will be called once after frame processing has stopped. - The ``queue_limit`` parameter specifies a maximum queue size. If frames are - added to the queue faster than they can be processed, the queue size will grow + The `queue_limit` parameter specifies a maximum queue size. If frames are added + to the queue faster than they can be processed, the queue size will grow unbounded. Setting a queue limit will cause the oldest frames on the queue to be - dropped, one batch at a time. You can use the ``period`` parameter to pause + dropped, one batch at a time. You can use the `period` parameter to pause between frames that are collected for processing, throttling the workload. By default this function will return right away and will process frames in the - background while the Sketch is running. Set the ``block`` parameter to ``True`` - to instruct the method to not return until the processing is complete or the - Sketch terminates. This blocking feature is not available on OSX when the Sketch - is executed through an IPython kernel. - - Use the ``sketch`` parameter to specify a different running Sketch, such as a - Sketch created using Class mode. If your Sketch has a ``post_draw()`` method, - use the ``hook_post_draw`` parameter to make this function run after - ``post_draw()`` instead of ``draw()``. This is important when using Processing - libraries that support ``post_draw()`` such as Camera3D or ColorBlindness.""" + background while the Sketch is running. Set the `block` parameter to `True` to + instruct the method to not return until the processing is complete or the Sketch + terminates. This blocking feature is not available on OSX when the Sketch is + executed through an IPython kernel. + + Use the `sketch` parameter to specify a different running Sketch, such as a + Sketch created using Class mode. If your Sketch has a `post_draw()` method, use + the `hook_post_draw` parameter to make this function run after `post_draw()` + instead of `draw()`. This is important when using Processing libraries that + support `post_draw()` such as Camera3D or ColorBlindness.""" import py5 if sketch is None: sketch = py5.get_current_sketch() @@ -353,21 +366,21 @@ def animated_gif(filename: str, count: int, period: float, duration: float, *, Create an animated GIF using a running Sketch. By default the Sketch will be the currently running Sketch, as returned by - ``get_current_sketch()``. Use the ``sketch`` parameter to specify a different + `get_current_sketch()`. Use the `sketch` parameter to specify a different running Sketch, such as a Sketch created using Class mode. By default this function will return right away and construct the animated gif in the background while the Sketch is running. The completed gif will be saved - to the location specified by the ``filename`` parameter when it is ready. Set - the ``block`` parameter to ``True`` to instruct the method to not return until - the gif construction is complete. This blocking feature is not available on OSX - when the Sketch is executed through an IPython kernel. If the Sketch terminates + to the location specified by the `filename` parameter when it is ready. Set the + `block` parameter to `True` to instruct the method to not return until the gif + construction is complete. This blocking feature is not available on OSX when the + Sketch is executed through an IPython kernel. If the Sketch terminates prematurely, no gif will be created. - If your Sketch has a ``post_draw()`` method, use the ``hook_post_draw`` - parameter to make this function run after ``post_draw()`` instead of ``draw()``. - This is important when using Processing libraries that support ``post_draw()`` - such as Camera3D or ColorBlindness.""" + If your Sketch has a `post_draw()` method, use the `hook_post_draw` parameter to + make this function run after `post_draw()` instead of `draw()`. This is + important when using Processing libraries that support `post_draw()` such as + Camera3D or ColorBlindness.""" import py5 if sketch is None: sketch = py5.get_current_sketch() @@ -447,22 +460,22 @@ def capture_frames(count: float, By default this function will return right away and will capture frames in the background while the Sketch is running. The returned list of PIL Image objects - (``list[PIL.Image]``) will initially be empty, and will be populated all at once - when the complete set of frames has been captured. Set the ``block`` parameter - to ``True`` to instruct the method to capture the frames in the foreground and - to not return until the complete list of frames is ready to be returned. To get - access to the captured frames as they become available, use the - ``py5_tools.offline_frame_processing()`` function instead. If the Sketch is + (`list[PIL.Image]`) will initially be empty, and will be populated all at once + when the complete set of frames has been captured. Set the `block` parameter to + `True` to instruct the method to capture the frames in the foreground and to not + return until the complete list of frames is ready to be returned. To get access + to the captured frames as they become available, use the + `py5_tools.offline_frame_processing()` function instead. If the Sketch is terminated prematurely, the returned list will be empty. By default the Sketch will be the currently running Sketch, as returned by - ``get_current_sketch()``. Use the ``sketch`` parameter to specify a different + `get_current_sketch()`. Use the `sketch` parameter to specify a different running Sketch, such as a Sketch created using Class mode. - If your Sketch has a ``post_draw()`` method, use the ``hook_post_draw`` - parameter to make this function run after ``post_draw()`` instead of ``draw()``. - This is important when using Processing libraries that support ``post_draw()`` - such as Camera3D or ColorBlindness.""" + If your Sketch has a `post_draw()` method, use the `hook_post_draw` parameter to + make this function run after `post_draw()` instead of `draw()`. This is + important when using Processing libraries that support `post_draw()` such as + Camera3D or ColorBlindness.""" import py5 if sketch is None: sketch = py5.get_current_sketch() diff --git a/py5_tools/hooks/hooks.py b/py5_tools/hooks/hooks.py index dc7c41b..052d0f3 100644 --- a/py5_tools/hooks/hooks.py +++ b/py5_tools/hooks/hooks.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -82,13 +82,21 @@ def __call__(self, sketch): class SaveFramesHook(BaseHook): - def __init__(self, dirname, filename, period, start, limit): + def __init__( + self, + dirname, + filename, + period, + start, + limit, + display_progress): super().__init__('py5save_frames_hook') self.dirname = dirname self.filename = filename self.period = period self.start = start self.limit = limit + self.display_progress = display_progress self.num_offset = None self.filenames = [] self.last_frame_time = 0 @@ -107,8 +115,9 @@ def __call__(self, sketch): self.last_frame_time = time.time() if len(self.filenames) == self.limit: self.hook_finished(sketch) - self.status_msg( - f'saving frame {len(self.filenames)}' + (f'/{self.limit}' if self.limit else '')) + if self.display_progress: + self.status_msg( + f'saving frame {len(self.filenames)}' + (f'/{self.limit}' if self.limit else '')) except Exception as e: self.hook_error(sketch, e) diff --git a/py5_tools/hooks/zmq_hooks.py b/py5_tools/hooks/zmq_hooks.py index 44e0c4b..5fa5d0c 100644 --- a/py5_tools/hooks/zmq_hooks.py +++ b/py5_tools/hooks/zmq_hooks.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -26,7 +26,6 @@ try: from py5jupyter.widgets import Py5SketchPortal except ImportError: - # TODO: deprecated class Py5SketchPortal(widgets.Image): def __init__(self, sketch, w, h): super().__init__() @@ -77,7 +76,7 @@ def sketch_portal(*, time_limit: float = 0.0, throttle_frame_rate: float = 30, new frame replacing the previous frame. By default the Sketch will be the currently running Sketch, as returned by - ``get_current_sketch()``. Use the ``sketch`` parameter to specify a different + `get_current_sketch()`. Use the `sketch` parameter to specify a different running Sketch, such as a Sketch created using Class mode. The Sketch Portal is a custom Jupyter Widget and can handle keyboard or mouse @@ -100,29 +99,29 @@ def sketch_portal(*, time_limit: float = 0.0, throttle_frame_rate: float = 30, for the Sketch Portal. Creating a "New Console for Notebook" and creating a portal there works well also. - This command can be called before ``run_sketch()`` if the current Sketch is in - the ``is_ready`` state. - - Use the ``time_limit`` parameter to set a time limit (seconds). Use - ``throttle_frame_rate`` to throttle the stream's frame rate (frames per second) - to a slower pace than the Sketch's actual draw frame rate. By default, - ``throttle_frame_rate`` is set to 30, which is half of the Sketch's default draw - frame rate of 60 frames per second. Set this parameter to ``None`` to disable - throttling. The ``scale`` parameter is a scaling factor that can adjust the - portal height and width. The ``quality`` parameter sets the JPEG quality factor - (default 75) for the stream, which must be between 1 (worst) and 100 (best). If - the portal causes the Sketch's frame rate to drop, try adjusting the portal's + This command can be called before `run_sketch()` if the current Sketch is in the + `is_ready` state. + + Use the `time_limit` parameter to set a time limit (seconds). Use + `throttle_frame_rate` to throttle the stream's frame rate (frames per second) to + a slower pace than the Sketch's actual draw frame rate. By default, + `throttle_frame_rate` is set to 30, which is half of the Sketch's default draw + frame rate of 60 frames per second. Set this parameter to `None` to disable + throttling. The `scale` parameter is a scaling factor that can adjust the portal + height and width. The `quality` parameter sets the JPEG quality factor (default + 75) for the stream, which must be between 1 (worst) and 100 (best). If the + portal causes the Sketch's frame rate to drop, try adjusting the portal's throttle frame rate, quality, and scale. - If your Sketch has a ``post_draw()`` method, use the ``hook_post_draw`` - parameter to make this function run after ``post_draw()`` instead of ``draw()``. - This is important when using Processing libraries that support ``post_draw()`` - such as Camera3D or ColorBlindness. + If your Sketch has a `post_draw()` method, use the `hook_post_draw` parameter to + make this function run after `post_draw()` instead of `draw()`. This is + important when using Processing libraries that support `post_draw()` such as + Camera3D or ColorBlindness. To stop a Sketch Portal, wait for the time limit to expire, call - ``exit_sketch()``, or press the "exit_sketch()" button below the portal. If you - delete the cell with the ``Py5SketchPortal`` object, the portal will no longer - be visible but the Sketch will still be streaming frames to the notebook client, + `exit_sketch()`, or press the "exit_sketch()" button below the portal. If you + delete the cell with the `Py5SketchPortal` object, the portal will no longer be + visible but the Sketch will still be streaming frames to the notebook client, wasting resources. A Sketch can only have one open portal, so opening a new portal with different options will replace an existing portal.""" environment = _environ.Environment() @@ -133,7 +132,6 @@ def sketch_portal(*, time_limit: float = 0.0, throttle_frame_rate: float = 30, raise RuntimeError( 'The sketch_widget() function can only be used with ZMQInteractiveShell (such as Jupyter Lab)') if issubclass(Py5SketchPortal, widgets.Image): - # TODO: deprecated warnings.warn( 'Please install the py5jupyter package for interactive Py5SketchPortal functionality.') diff --git a/py5_tools/hooks/zmq_hooks_fail.py b/py5_tools/hooks/zmq_hooks_fail.py index 213c754..5737d01 100644 --- a/py5_tools/hooks/zmq_hooks_fail.py +++ b/py5_tools/hooks/zmq_hooks_fail.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -67,7 +67,7 @@ def sketch_portal( new frame replacing the previous frame. By default the Sketch will be the currently running Sketch, as returned by - ``get_current_sketch()``. Use the ``sketch`` parameter to specify a different + `get_current_sketch()`. Use the `sketch` parameter to specify a different running Sketch, such as a Sketch created using Class mode. The Sketch Portal is a custom Jupyter Widget and can handle keyboard or mouse @@ -90,29 +90,29 @@ def sketch_portal( for the Sketch Portal. Creating a "New Console for Notebook" and creating a portal there works well also. - This command can be called before ``run_sketch()`` if the current Sketch is in - the ``is_ready`` state. - - Use the ``time_limit`` parameter to set a time limit (seconds). Use - ``throttle_frame_rate`` to throttle the stream's frame rate (frames per second) - to a slower pace than the Sketch's actual draw frame rate. By default, - ``throttle_frame_rate`` is set to 30, which is half of the Sketch's default draw - frame rate of 60 frames per second. Set this parameter to ``None`` to disable - throttling. The ``scale`` parameter is a scaling factor that can adjust the - portal height and width. The ``quality`` parameter sets the JPEG quality factor - (default 75) for the stream, which must be between 1 (worst) and 100 (best). If - the portal causes the Sketch's frame rate to drop, try adjusting the portal's + This command can be called before `run_sketch()` if the current Sketch is in the + `is_ready` state. + + Use the `time_limit` parameter to set a time limit (seconds). Use + `throttle_frame_rate` to throttle the stream's frame rate (frames per second) to + a slower pace than the Sketch's actual draw frame rate. By default, + `throttle_frame_rate` is set to 30, which is half of the Sketch's default draw + frame rate of 60 frames per second. Set this parameter to `None` to disable + throttling. The `scale` parameter is a scaling factor that can adjust the portal + height and width. The `quality` parameter sets the JPEG quality factor (default + 75) for the stream, which must be between 1 (worst) and 100 (best). If the + portal causes the Sketch's frame rate to drop, try adjusting the portal's throttle frame rate, quality, and scale. - If your Sketch has a ``post_draw()`` method, use the ``hook_post_draw`` - parameter to make this function run after ``post_draw()`` instead of ``draw()``. - This is important when using Processing libraries that support ``post_draw()`` - such as Camera3D or ColorBlindness. + If your Sketch has a `post_draw()` method, use the `hook_post_draw` parameter to + make this function run after `post_draw()` instead of `draw()`. This is + important when using Processing libraries that support `post_draw()` such as + Camera3D or ColorBlindness. To stop a Sketch Portal, wait for the time limit to expire, call - ``exit_sketch()``, or press the "exit_sketch()" button below the portal. If you - delete the cell with the ``Py5SketchPortal`` object, the portal will no longer - be visible but the Sketch will still be streaming frames to the notebook client, + `exit_sketch()`, or press the "exit_sketch()" button below the portal. If you + delete the cell with the `Py5SketchPortal` object, the portal will no longer be + visible but the Sketch will still be streaming frames to the notebook client, wasting resources. A Sketch can only have one open portal, so opening a new portal with different options will replace an existing portal.""" raise RuntimeError( diff --git a/py5_tools/imported.py b/py5_tools/imported.py index 0798b93..c744667 100644 --- a/py5_tools/imported.py +++ b/py5_tools/imported.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -23,6 +23,7 @@ from multiprocessing import Process from pathlib import Path import re +import tempfile import stackprinter @@ -54,11 +55,11 @@ def get_imported_mode() -> bool: _STATIC_CODE_FRAMEWORK = """ -import ast as _PY5BOT_ast +import ast as _PY5STATIC_ast import py5_tools py5_tools.set_imported_mode(True) -import py5_tools.parsing as _PY5BOT_parsing +import py5_tools.parsing as _PY5STATIC_parsing from py5 import * _PY5_NS_ = locals().copy() @@ -67,8 +68,8 @@ def settings(): with open('{0}', 'r') as f: exec( compile( - _PY5BOT_parsing.transform_py5_code( - _PY5BOT_ast.parse(f.read(), filename='{0}', mode='exec'), + _PY5STATIC_parsing.transform_py5_code( + _PY5STATIC_ast.parse(f.read(), filename='{0}', mode='exec'), ), filename='{0}', mode='exec' @@ -81,8 +82,8 @@ def setup(): with open('{1}', 'r') as f: exec( compile( - _PY5BOT_parsing.transform_py5_code( - _PY5BOT_ast.parse(f.read(), filename='{1}', mode='exec'), + _PY5STATIC_parsing.transform_py5_code( + _PY5STATIC_ast.parse(f.read(), filename='{1}', mode='exec'), ), filename='{1}', mode='exec' @@ -95,7 +96,7 @@ def setup(): -run_sketch(block=True, py5_options={2}, sketch_args={3}) +run_sketch(block={4}, py5_options={2}, sketch_args={3}) if {1} and is_dead_from_error: exit_sketch() """ @@ -116,11 +117,13 @@ def is_static_mode(code): def run_code( sketch_path, + *, classpath=None, new_process=False, exit_if_error=False, py5_options=None, - sketch_args=None): + sketch_args=None, + block=True): sketch_path = Path(sketch_path) if not sketch_path.exists(): print(f'file {sketch_path} not found') @@ -137,7 +140,8 @@ def run_code( new_process, exit_if_error, py5_options, - sketch_args) + sketch_args, + block) else: _run_code( sketch_path, @@ -146,7 +150,8 @@ def run_code( exit_if_error, py5_options, sketch_args, - sketch_path) + sketch_path, + block) def _run_static_code( @@ -156,24 +161,32 @@ def _run_static_code( new_process, exit_if_error, py5_options, - sketch_args): - try: - from py5jupyter.kernels.py5bot import py5bot - except ImportError as e: - # TODO: deprecated - from .py5bot import py5bot - - py5bot_mgr = py5bot.Py5BotManager() - success, result = py5bot.check_for_problems(code, sketch_path) + sketch_args, + block): + success, result = parsing.check_for_problems(code, sketch_path) if success: - py5bot_globals, py5bot_settings, py5bot_setup = result - py5bot_mgr.write_code(py5bot_globals, py5bot_settings, py5bot_setup) - new_sketch_path = py5bot_mgr.tempdir / '_PY5_STATIC_FRAMEWORK_CODE_.py' + py5static_globals, py5static_settings, py5static_setup = result + + tempdir = Path(tempfile.TemporaryDirectory().name) + tempdir.mkdir(parents=True, exist_ok=True) + settings_filename = tempdir / '_PY5_STATIC_SETTINGS_CODE_.py' + setup_filename = tempdir / '_PY5_STATIC_SETUP_CODE_.py' + + with open(settings_filename, 'w') as f: + f.write('\n' * sum(c == '\n' for c in py5static_globals)) + f.write(py5static_settings) + + with open(setup_filename, 'w') as f: + f.write(py5static_globals) + f.write('\n' * sum(c == '\n' for c in py5static_settings)) + f.write(py5static_setup) + + new_sketch_path = tempdir / '_PY5_STATIC_FRAMEWORK_CODE_.py' new_sketch_code = _STATIC_CODE_FRAMEWORK.format( - py5bot_mgr.settings_filename.as_posix(), - py5bot_mgr.setup_filename.as_posix()) + settings_filename.as_posix(), setup_filename.as_posix()) with open(new_sketch_path, 'w') as f: f.write(new_sketch_code) + _run_code( new_sketch_path, classpath, @@ -181,7 +194,8 @@ def _run_static_code( exit_if_error, py5_options, sketch_args, - sketch_path) + sketch_path, + block) else: print(result, file=sys.stderr) @@ -193,7 +207,8 @@ def _run_code( exit_if_error, py5_options, sketch_args, - original_sketch_path): + original_sketch_path, + block): def _run_sketch(sketch_path, classpath, exit_if_error): if not jvm.is_jvm_running(): if classpath: @@ -222,7 +237,7 @@ def _run_sketch(sketch_path, classpath, exit_if_error): ast.parse(user_code, filename=sketch_path, mode='exec') # now do the real parsing sketch_code = _CODE_FRAMEWORK.format( - user_code, exit_if_error, py5_options_str, sketch_args_str) + user_code, exit_if_error, py5_options_str, sketch_args_str, block) sketch_ast = ast.parse( sketch_code, filename=sketch_path, mode='exec') except IndentationError as e: diff --git a/py5_tools/jvm.py b/py5_tools/jvm.py index f079814..b86d838 100644 --- a/py5_tools/jvm.py +++ b/py5_tools/jvm.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -44,12 +44,12 @@ def is_jvm_running() -> bool: ----- Determine if the Java Virtual Machine (JVM) is or is not running. When the py5 - library is imported it will start the JVM. Therefore this will be ``False`` - before ``import py5`` is executed and ``True`` afterwards. It should continue to - always be ``True`` unless somewhere there is some Java code that calls - ``System.exit()``. Calling ``System.exit()`` is not recommended. If for some - reason the JVM crashes (perhaps through a segmentation fault), the JVM will no - longer be running, but that crash will most likely also terminate the Python + library is imported it will start the JVM. Therefore this will be `False` + before `import py5` is executed and `True` afterwards. It should continue to + always be `True` unless somewhere there is some Java code that calls + `System.exit()`. Calling `System.exit()` is not recommended. If for some reason + the JVM crashes (perhaps through a segmentation fault), the JVM will no longer + be running, but that crash will most likely also terminate the Python interpreter.""" return jpype.isJVMStarted() @@ -75,8 +75,8 @@ def add_options(*options: list[str]) -> None: memory size, for example. After the JVM has started, new options cannot be added. This function will throw - a ``RuntimeError`` if it is called after the JVM has already started. Use - ``py5_tools.is_jvm_running()`` to first determine if the JVM is running.""" + a `RuntimeError` if it is called after the JVM has already started. Use + `py5_tools.is_jvm_running()` to first determine if the JVM is running.""" _check_jvm_running() _options.extend(options) @@ -88,10 +88,10 @@ def get_classpath() -> str: ----- Get the Java classpath. If the JVM has not yet started, this will list the jars - that have been added with ``py5_tools.add_classpath()`` and - ``py5_tools.add_jars()``. After the JVM has started, the classpath cannot be - changed and the aformentioned functions would throw a ``RuntimeError``. Use - ``py5_tools.is_jvm_running()`` to first determine if the JVM is running.""" + that have been added with `py5_tools.add_classpath()` and + `py5_tools.add_jars()`. After the JVM has started, the classpath cannot be + changed and the aformentioned functions would throw a `RuntimeError`. Use + `py5_tools.is_jvm_running()` to first determine if the JVM is running.""" if jpype.isJVMStarted(): return jpype.getClassPath() else: @@ -114,8 +114,8 @@ def add_classpath(classpath: Union[Path, str]) -> None: relative. After the JVM has started, the classpath cannot be changed. This function will - throw a ``RuntimeError`` if it is called after the JVM has already started. Use - ``py5_tools.is_jvm_running()`` to first determine if the JVM is running.""" + throw a `RuntimeError` if it is called after the JVM has already started. Use + `py5_tools.is_jvm_running()` to first determine if the JVM is running.""" _check_jvm_running() if not isinstance(classpath, Path): classpath = Path(classpath) @@ -139,13 +139,13 @@ def add_jars(path: Union[Path, str]) -> None: the classpath. The path can be absolute or relative. If the directory does does not exist, it will be ignored. - When ``import py5`` is executed, ``add_jars('jars')`` is called for you to + When `import py5` is executed, `add_jars('jars')` is called for you to automatically add jar files contained in a subdirectory called jars. This is similar to functionality provided by the Processing IDE. After the JVM has started, the classpath cannot be changed. This function will - throw a ``RuntimeError`` if it is called after the JVM has already started. Use - ``py5_tools.is_jvm_running()`` to first determine if the JVM is running.""" + throw a `RuntimeError` if it is called after the JVM has already started. Use + `py5_tools.is_jvm_running()` to first determine if the JVM is running.""" _check_jvm_running() if not isinstance(path, Path): path = Path(path) @@ -161,9 +161,8 @@ def get_jvm_debug_info() -> dict[str, Any]: ----- Get Java Virtual Machine debug information. The py5 library requires Java 17 or - greater to be installed and the ``$JAVA_HOME`` environment variable to be - properly set. If one or both of these conditions are not true, py5 will not - work. + greater to be installed and the `$JAVA_HOME` environment variable to be properly + set. If one or both of these conditions are not true, py5 will not work. If the Java Virtual Machine cannot start, py5 will include this debug information in the error message. If that doesn't help the user figure out the diff --git a/py5_tools/kernel/__init__.py b/py5_tools/kernel/__init__.py deleted file mode 100644 index 2739374..0000000 --- a/py5_tools/kernel/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# ***************************************************************************** -# -# Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz -# -# This library is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# -# ***************************************************************************** -from .kernel import Py5Kernel # noqa diff --git a/py5_tools/kernel/__main__.py b/py5_tools/kernel/__main__.py deleted file mode 100644 index 93a9a4d..0000000 --- a/py5_tools/kernel/__main__.py +++ /dev/null @@ -1,22 +0,0 @@ -# ***************************************************************************** -# -# Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz -# -# This library is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# -# ***************************************************************************** -from .kernel import Py5App - -Py5App.launch_instance() diff --git a/py5_tools/kernel/install.py b/py5_tools/kernel/install.py deleted file mode 100644 index 21d8893..0000000 --- a/py5_tools/kernel/install.py +++ /dev/null @@ -1,89 +0,0 @@ -# ***************************************************************************** -# -# Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz -# -# This library is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# -# ***************************************************************************** -import os -import sys -import shutil -from pathlib import Path -import argparse -import json - -from jupyter_client.kernelspec import KernelSpecManager -from IPython.utils.tempdir import TemporaryDirectory - - -kernel_json = { - "argv": [ - sys.executable, - "-m", - "py5_tools.kernel", - "-f", - "{connection_file}"], - "display_name": "py5", - "language": "python", -} - - -def install_py5_kernel_spec(user=True, prefix=None): - with TemporaryDirectory() as td: - os.chmod(td, 0o755) # Starts off as 700, not user readable - with open(Path(td) / 'kernel.json', 'w') as f: - json.dump(kernel_json, f, sort_keys=True) - - # Copy any resources - for file in (Path(__file__).parent / 'resources').glob('*'): - shutil.copy(file, Path(td) / file.name) - - print('Installing py5 Jupyter kernel spec') - KernelSpecManager().install_kernel_spec( - td, 'py5', user=user, prefix=prefix) - - -def _is_root(): - try: - return os.geteuid() == 0 - except AttributeError: - return False # assume not an admin on non-Unix platforms - - -def main(argv=None): - ap = argparse.ArgumentParser() - ap.add_argument( - '--user', - action='store_true', - help="Install to the per-user kernels registry. Default if not root.") - ap.add_argument( - '--sys-prefix', - action='store_true', - help="Install to sys.prefix (e.g. a virtualenv or conda env)") - ap.add_argument( - '--prefix', help="Install to the given prefix. " - "Kernelspec will be installed in {PREFIX}/share/jupyter/kernels/") - args = ap.parse_args(argv) - - if args.sys_prefix: - args.prefix = sys.prefix - if not args.prefix and not _is_root(): - args.user = True - - install_py5_kernel_spec(user=args.user, prefix=args.prefix) - - -if __name__ == '__main__': - main() diff --git a/py5_tools/kernel/kernel.py b/py5_tools/kernel/kernel.py deleted file mode 100644 index b9f4738..0000000 --- a/py5_tools/kernel/kernel.py +++ /dev/null @@ -1,99 +0,0 @@ -# ***************************************************************************** -# -# Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz -# -# This library is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# -# ***************************************************************************** -import sys - -from ipykernel.ipkernel import IPythonKernel -from ipykernel.zmqshell import ZMQInteractiveShell -from IPython.core.interactiveshell import InteractiveShellABC -from ipykernel.kernelapp import IPKernelApp - -from traitlets import Type, Instance, Unicode, List - -from ..parsing import TransformDynamicVariablesToCalls, Py5CodeValidation - - -_PY5_HELP_LINKS = [ - { - 'text': 'py5 Documentation', - 'url': 'http://py5coding.org/' - }, - { - 'text': 'py5 Function Reference', - 'url': 'http://py5coding.org/reference/sketch.html' - }, -] - -_MACOSX_PRE_STARTUP = """ -get_ipython().run_line_magic('gui', 'osx') -""" - -_DEFAULT_STARTUP = """ -import py5_tools -py5_tools.set_imported_mode(True) -from py5 import * -from py5_tools import sketch_portal -""" - -_KERNEL_STARTUP = (_MACOSX_PRE_STARTUP if sys.platform == - 'darwin' else "") + _DEFAULT_STARTUP - - -class Py5Shell(ZMQInteractiveShell): - - ast_transformers = List( - [TransformDynamicVariablesToCalls(), Py5CodeValidation()]).tag(config=True) - - banner2 = Unicode("Activating py5 imported mode").tag(config=True) - - def run_cell(self, *args, **kwargs): - # TODO: deprecated - self.log.warning("This kernel is deprecated. Uninstall it with `jupyter kernelspec uninstall py5`, install the new py5jupyter package, and then install the kernel with `python -m py5jupyter.kernels.py5.install --sys-prefix`.") - return super(Py5Shell, self).run_cell(*args, **kwargs) - - -InteractiveShellABC.register(Py5Shell) - - -class Py5Kernel(IPythonKernel): - shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', - allow_none=True) - shell_class = Type(Py5Shell) - - help_links = List([*IPythonKernel.help_links.default(), - *_PY5_HELP_LINKS]).tag(config=True) - - implementation = 'py5' - implementation_version = '0.8.3a1' - - -class Py5App(IPKernelApp): - name = 'py5-kernel' - - kernel_class = Type('py5_tools.kernel.Py5Kernel', - klass='ipykernel.kernelbase.Kernel').tag(config=True) - - exec_lines = List(Unicode(), [ - _KERNEL_STARTUP - ]).tag(config=True) - - extensions = List( - Unicode(), [ - 'py5_tools.magics', 'py5_tools.magics.py5bot']).tag( - config=True) diff --git a/py5_tools/kernel/resources/logo-32x32.png b/py5_tools/kernel/resources/logo-32x32.png deleted file mode 100644 index de39f2fdae1e18512197777c5cdcef30b66850ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2643 zcmV-Z3as^sP)1Sxl!)D6xQ$G|7hShJ@@rclX}S%iepQen>V&L9}1` z%eRbOAPFgERN-@bhf z9UUEKVzC&dYieqWlF1|)h9M2ZkjZ3{rlzK5ug79B>geb=vv1$N1^{4;p}xLe`A*_Z zO-%{_IGxUt*4EY|x~>xuk!hN?5F!nX!9Y$76E*QuqY z(~BP@lBgH1v@)C`)7nxnx@&Brcol1Aj`5SnM{%pf?}~4X_`ht2-0<(;_*1e z<8jh;oit6e4a2aAh&nqv`|9fIYHn$wv9Xae#;|SMwiR7nU1LNE>y&Q4rfJmP z(M|({VX{)zY|CxSCet);YDx%^A|g6>?p&;{uC9hLhQ`K5euFp>@uH%l!qcZuhtuNe zMTm&n+fGqUu$uf{AJr@iQtdsp^!QUd=(mSoqtDt;Q6w56Y0FttR>~s7Fh~eNqobo1 z5m6`<3Kta>6%r9on_vJyL<(cfZfa_3t*@`&tn0eP7*jJdGr+lug9l&4+wZ&wp5?@b z^5uB?`#;9#7ygcmgO_n(=u1S65u{Wb{<1IS76@U`S2AKfO8JRFs$6% zT(!BmxwWC8p)RedHa0e@oO5gM-o0DzzyJQt$z;+3pgJ553=Ku`qwSBNr!R`%{pl3m zdg~Xc^jv9}jW`mX$(0nZVGsC@x>=!52N}aipyYZzNuWBPRou3o5aA*%IvB zxl?sG9M*mJ-M3}$-o0Bn=N~jRH7V)6&OiP1)3fW>uV1F?x|C8XUauGXo_`L%I{XJL zTV4%2Ie~%jC9JDlg)OT$p~4?PnXeRXXC73=0mc{@1BeJy))W-R(be0H$6kLL(by1L z{?dZYTQ=LAbAIB)iSrvaYzPvOR2gHmYuB#z!C-KCGMSW|bA@R7%;>#*30t4pk9FI& z}Z0nT|*XEQJ!CdMWvNk9$13;CG%12Ekd5tg`@xc3g;qe!Mq*M~7DTBe_vR%7&tz(QGQvsm1w)Tf!ub1NSxMYlR#yKp@!tlr_7OyRY z>c~KG#e8IEW@FEe18}*#7>PwOI2=Y#_#!U#U%<(eXJ90Bc(QU(;3~l7E9dd@4<5yq zWvj6IH+xZ9Tms9oAf=REua~V`x31yPp+m=10BS`=#a%?ih=>D#swmKP9WgzD{Ngf5 zNf-|IB0~bi7(^llXI2iX76fto($(OMV{&Q&vG^Ez1~22qLqEmwT`wS5y&7lEgn;Z! z_*&KxKTN8ji$ib_ktIfs-IilVSoDuvwKT<4lKYXaQk@whWHGeJah=1c%% z4B>%(WVs8Fk(muCC1TM*6#GiQ`5Y&}p*k=;7DZuBE*zQJ00Dj1t|Cwo`07uIWL8!d zJRXmm->}Zi4(RLegS)U4imJl4EW}5mC@Cz5ZQEcsnc@V3!c{~@hEVRw2NV^M76$b( z%$+lL`Z2K^@8d!UePUt)jIpnn2@iykUm5@y!{oS$q!xqUSBjLCx&=iLu3n2^PC*gC z8RX<7Mv?~RR0L)_J7a`TPEJAyq4Q8E6iy@(;|_-dL`3OlH59!HUughjTSyvlsJ4xY z@_7IeKm=Rbu%!(m2?BwE!LlvHv=Pkp6#)Qr(|}1f%FD`;no5B&1|lMd!+}I1F&+wq z!o0h?J1m6gS5*~6M2e!oFbs@o0^Y)6Was5UAC2PLl`wh-Eq@U@>D%s;YxW zh6a&LNdy+JK->H8;KScGV$mHd@#e>eF{PVuXSs1(VE_x}F2VeY#V9Wcz+X@dVdzj~ z3JZ(N!5ByQ+9-1KJ@B~QNSY=X=KvrXV{BkxpaX!V0>H_WC!02G*zkm^s$5l73`Zl7 zii*D;K8Q=9qu9CUXIOdndL$DGjE!E!mHuAzeR%ZC*V~ig=cI@oE_ujiyN-0}E`bc^3 zfd}9(F2_8T|aEgU~b$oO9dlcJmV_PW)?j7&SLHGsc*8{P^+xt5&UgKQl9vR@T&D|Ni|r zf8he&{^g5EPENs7Sd8-dm6*49DFX8<;V&scj>`p4z7KhBFIL@k55`6{)VLhj^W>wb z-ToBj-d>F-9^ZlS@o{j@;cz%8kw~ylKKZ1PF=ih)a6tV!kbGEQU%w>{4^m2ujg6tN zw-?>r=Ww>`EG}NUgy_`~*j$0zUx>hhMX0D;fT}xIq8QdM=3@_jz44%X1AwsuNWu@GXG3s0XueFKusRvJp{>gsCFojVu1 z9!iA}q-h$(VlfgzkZGD^+4g_=&$4JR9H#d6cG5I$HXB?IrCnWJV-G#_Q1wlrG+k+A zuB)r7>Fn(6BO)>k!_qX({yKJl-BdD}B+IfWkw}oHX{2eIZJK6k2Fv?5ZQ2yPUgI0< z`e4%1(lQ%N48yQ>T~7%iY$3!A!9>$E8H>eiAw2!X#V3Mx?XEgh+ z;gmo7?6conyLRo?;^N}99*^gy;WQqP_YVyXb+om$eemk5uO0=a$IGq4>8%U^xOqIU ztgM`~apT6ayu3UQ=bVHPdRtrDmG18D0sN2g{6E`{qnf^<{B{5U002ovPDHLkV1iEU B{*C|u diff --git a/py5_tools/libraries.py b/py5_tools/libraries.py index 40a249f..5090568 100644 --- a/py5_tools/libraries.py +++ b/py5_tools/libraries.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -21,11 +21,8 @@ import io import zipfile import requests -from functools import reduce from pathlib import Path -import pandas as pd - PROCESSING_LIBRARY_URL = 'http://download.processing.org/contribs' @@ -47,48 +44,43 @@ def _load_data(self): blocks = [b for b in response.text.split( '\n\n') if b.startswith('library')] - block_lines = [dict([line.split('=', 1) - for line in block.splitlines() - if line != "library"]) - for block in blocks] - df = pd.DataFrame.from_dict(block_lines, dtype="string") - # lastUpdated is supposed to be the last column - df = df.iloc[:, :(df.columns.get_loc('lastUpdated') + 1)] - df.astype({'id': int, 'minRevision': int, 'maxRevision': int}) - df['id'] = df['id'].astype(int) - df['minRevision'] = df['minRevision'].astype(int) - df['maxRevision'] = df['maxRevision'].astype(int) - df['categories'] = df['categories'].apply(lambda x: x.split(',')) - # get paragraph values from raw data because they could be on more than one - # line or the paragraph could be missing - df['paragraph'] = [PARAGRAPH_REGEX.findall(b) for b in blocks] - df['paragraph'] = df['paragraph'].apply( - lambda x: x[0] if x else '').astype('string') - - self._data = df - self.categories = sorted( - reduce( - lambda x, - y: x | set(y), - df['categories'], - set())) - self.names = sorted(df['name']) + data = [dict([line.split('=', 1) + for line in block.splitlines() + if line != "library"]) + for block in blocks] + + categories = set() + names = list() + for i, libinfo in enumerate(data): + libinfo['id'] = int(libinfo['id']) + libinfo['minRevision'] = int(libinfo['minRevision']) + libinfo['maxRevision'] = int(libinfo['maxRevision']) + libinfo['categories'] = libinfo['categories'].split(',') + paragraph = PARAGRAPH_REGEX.findall(blocks[i]) + libinfo['paragraph'] = paragraph[0] if paragraph else '' + + categories.update(libinfo['categories']) + names.append(libinfo['name']) + + self.categories = sorted(categories) + self.names = sorted(names) + self._data = data def get_library_info( self, category=None, library_name=None, library_id=None): + # TODO: also make sure minRevision < version < maxRevision, but how? info = self._data - # TODO: also make sure minRevision < version < maxRevision if category: - info = info[info['categories'].apply(lambda x: category in x)] + info = filter(lambda x: category in x.get('categories', []), info) if library_name: - info = info[info['name'] == library_name] + info = filter(lambda x: x.get('name') == library_name, info) if library_id: - info = info[info['id'] == library_id] + info = filter(lambda x: x.get('id') == int(library_id), info) - return info + return list(info) def download_zip(self, dest, library_name=None, library_id=None): info = self.get_library_info( @@ -96,11 +88,13 @@ def download_zip(self, dest, library_name=None, library_id=None): library_id=library_id) if len(info) == 0: - raise RuntimeError(f'library not found') + raise RuntimeError('There are no libraries named ' + library_name) if len(info) > 1: - raise RuntimeError(f'more than one library') + raise RuntimeError( + 'Multiple libraries found named ' + + library_name) - info = info.T.to_dict()[info.index[0]] + info = info[0] download_url = info['download'] response = requests.get(download_url) @@ -111,8 +105,7 @@ def download_zip(self, dest, library_name=None, library_id=None): jars = [] for name in zf.namelist(): path = Path(name) - if len( - path.parts) > 2 and path.parts[1] == 'library' and path.suffix == '.jar': + if len(path.parts) > 2 and path.parts[1] == 'library': jars.append(name) zf.extractall(dest, jars) diff --git a/py5_tools/magics/__init__.py b/py5_tools/magics/__init__.py index 60d240c..f286fe9 100644 --- a/py5_tools/magics/__init__.py +++ b/py5_tools/magics/__init__.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by diff --git a/py5_tools/magics/drawing.py b/py5_tools/magics/drawing.py index 93dd5f2..889c699 100644 --- a/py5_tools/magics/drawing.py +++ b/py5_tools/magics/drawing.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -31,10 +31,11 @@ import stackprinter import PIL -from .util import CellMagicHelpFormatter, filename_check, variable_name_check from .. import imported from .. import parsing +from .util import CellMagicHelpFormatter, filename_check, variable_name_check + _CODE_FRAMEWORK_BEGIN = """ import py5 @@ -244,11 +245,11 @@ def py5drawpdf(self, line, cell): Create a PDF with py5. For users who are familiar with Processing and py5 programming, you can pretend - the code in this cell will be executed in a Sketch with no ``draw()`` function - and your code in the ``setup()`` function. It will use the ``PDF`` renderer. + the code in this cell will be executed in a Sketch with no `draw()` function and + your code in the `setup()` function. It will use the `PDF` renderer. - As this is creating a PDF, you cannot do operations on the ``pixels[]`` or - ``np_pixels[]`` arrays. Use ``%%py5draw`` instead. + As this is creating a PDF, you cannot do operations on the `pixels[]` or + `np_pixels[]` arrays. Use `%%py5draw` instead. Code used in this cell can reference functions and variables defined in other cells because a copy of the user namespace is provided during execution. By @@ -257,7 +258,7 @@ def py5drawpdf(self, line, cell): namespace, however, can be altered and those changes will persist elsewhere in the notebook. - If you understand the risks, you can use the ``--unsafe`` argument so that + If you understand the risks, you can use the `--unsafe` argument so that variables and functions created in this cell are stored in the user namespace instead of a copy, making them available in other notebook cells. This may be very useful to you, but be aware that using py5 objects in a different notebook @@ -289,11 +290,11 @@ def py5drawsvg(self, line, cell): Create a SVG drawing with py5 and embed the result in the notebook. For users who are familiar with Processing and py5 programming, you can pretend - the code in this cell will be executed in a Sketch with no ``draw()`` function - and your code in the ``setup()`` function. It will use the ``SVG`` renderer. + the code in this cell will be executed in a Sketch with no `draw()` function and + your code in the `setup()` function. It will use the `SVG` renderer. - As this is creating a SVG drawing, you cannot do operations on the ``pixels[]`` - or ``np_pixels[]`` arrays. Use ``%%py5draw`` instead. + As this is creating a SVG drawing, you cannot do operations on the `pixels[]` or + `np_pixels[]` arrays. Use `%%py5draw` instead. Code used in this cell can reference functions and variables defined in other cells because a copy of the user namespace is provided during execution. By @@ -302,7 +303,7 @@ def py5drawsvg(self, line, cell): namespace, however, can be altered and those changes will persist elsewhere in the notebook. - If you understand the risks, you can use the ``--unsafe`` argument so that + If you understand the risks, you can use the `--unsafe` argument so that variables and functions created in this cell are stored in the user namespace instead of a copy, making them available in other notebook cells. This may be very useful to you, but be aware that using py5 objects in a different notebook @@ -338,8 +339,8 @@ def py5draw(self, line, cell): Create a PNG image with py5 and embed the result in the notebook. For users who are familiar with Processing and py5 programming, you can pretend - the code in this cell will be executed in a Sketch with no ``draw()`` function - and your code in the ``setup()`` function. By default it will use the default + the code in this cell will be executed in a Sketch with no `draw()` function and + your code in the `setup()` function. By default it will use the default Processing renderer. On OSX, only the default renderer is currently supported. Other platforms @@ -347,8 +348,8 @@ def py5draw(self, line, cell): Internally this magic command creates a static Sketch using the user provided code. The static Sketch drawing surface does not allow transparency. If you want - to quickly create an image that has transparency, consider using ``@render()`` - or ``render_frame()`` with the ``use_py5graphics`` parameter. + to quickly create an image that has transparency, consider using `@render()` or + `render_frame()` with the `use_py5graphics` parameter. Code used in this cell can reference functions and variables defined in other cells because a copy of the user namespace is provided during execution. By @@ -357,7 +358,7 @@ def py5draw(self, line, cell): namespace, however, can be altered and those changes will persist elsewhere in the notebook. - If you understand the risks, you can use the ``--unsafe`` argument so that + If you understand the risks, you can use the `--unsafe` argument so that variables and functions created in this cell are stored in the user namespace instead of a copy, making them available in other notebook cells. This may be very useful to you, but be aware that using py5 objects in a different notebook @@ -424,8 +425,8 @@ def py5drawdxf(self, line, cell): Create a DXF file with py5. For users who are familiar with Processing and py5 programming, you can pretend - the code in this cell will be executed in a Sketch with no ``draw()`` function - and your code in the ``setup()`` function. It will use the ``DXF`` renderer. + the code in this cell will be executed in a Sketch with no `draw()` function and + your code in the `setup()` function. It will use the `DXF` renderer. As this is creating a DXF file, your code will be limited to the capabilities of that renderer. @@ -439,7 +440,7 @@ def py5drawdxf(self, line, cell): namespace, however, can be altered and those changes will persist elsewhere in the notebook. - If you understand the risks, you can use the ``--unsafe`` argument so that + If you understand the risks, you can use the `--unsafe` argument so that variables and functions created in this cell are stored in the user namespace instead of a copy, making them available in other notebook cells. This may be very useful to you, but be aware that using py5 objects in a different notebook diff --git a/py5_tools/magics/py5bot.py b/py5_tools/magics/py5bot.py index ccfb6a3..c3d45d2 100644 --- a/py5_tools/magics/py5bot.py +++ b/py5_tools/magics/py5bot.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -23,14 +23,12 @@ from IPython.core.magic import Magics, magics_class, cell_magic from IPython.core.magic_arguments import parse_argstring, argument, magic_arguments, kwds +from py5jupyter.kernels.py5bot.py5bot import Py5BotManager + from .. import split_setup -from .util import CellMagicHelpFormatter, filename_check, variable_name_check +from ..parsing import check_for_problems -try: - from py5jupyter.kernels.py5bot.py5bot import Py5BotManager, check_for_problems -except ImportError: - # TODO: deprecated - from ..py5bot.py5bot import Py5BotManager, check_for_problems +from .util import CellMagicHelpFormatter, filename_check, variable_name_check @magics_class @@ -53,20 +51,20 @@ def py5bot(self, line, cell): This cell magic uses the same rendering mechanism as the py5bot kernel. For users who are familiar with Processing and py5 programming, you can pretend the - code in this cell will be executed as a static Sketch with no ``draw()`` - function and your code in the ``setup()`` function. The first line in the cell - should be a call to ``size()``. - - This magic is similar to ``%%py5draw`` in that both can be used to create a - static Sketch. One key difference is that ``%%py5bot`` requires the user to - begin the code with a call to ``size()``, while ``%%py5draw`` calls ``size()`` - for you based on the magic's arguments. - - This magic supports the default renderer and the ``P2D`` and ``P3D`` renderers. - Note that both of the OpenGL renderers will briefly open a window on your - screen. This magic is only available when using the py5 kernel and coding in - imported mode. The ``P2D`` and ``P3D`` renderers are not available when the py5 - kernel is hosted on an OSX computer. + code in this cell will be executed as a static Sketch with no `draw()` function + and your code in the `setup()` function. The first line in the cell should be a + call to `size()`. + + This magic is similar to `%%py5draw` in that both can be used to create a static + Sketch. One key difference is that `%%py5bot` requires the user to begin the + code with a call to `size()`, while `%%py5draw` calls `size()` for you based on + the magic's arguments. + + This magic supports the default renderer and the `P2D` and `P3D` renderers. Note + that both of the OpenGL renderers will briefly open a window on your screen. + This magic is only available when using the py5 kernel and coding in imported + mode. The `P2D` and `P3D` renderers are not available when the py5 kernel is + hosted on an OSX computer. Code used in this cell can reference functions and variables defined in other cells because a copy of the user namespace is provided during execution. diff --git a/py5_tools/magics/util.py b/py5_tools/magics/util.py index 97f5240..04a9244 100644 --- a/py5_tools/magics/util.py +++ b/py5_tools/magics/util.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by diff --git a/py5_tools/parsing.py b/py5_tools/parsing.py index 0267bd1..f35a263 100644 --- a/py5_tools/parsing.py +++ b/py5_tools/parsing.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by @@ -19,8 +19,12 @@ # ***************************************************************************** import sys import ast +import re + +import stackprinter from . import reference as ref +from . import split_setup try: from IPython.core.error import InputRejected @@ -132,3 +136,71 @@ def check_reserved_words(code, code_ast): def transform_py5_code(code_ast: ast.Module): transformer = TransformDynamicVariablesToCalls() return ast.fix_missing_locations(transformer.visit(code_ast)) + + +def check_for_problems(code, filename, *, tool=None): + # if the code contains a setup() or a draw() function, the user could be + # confused about static mode + if (ms := re.findall( + r"^def (setup|draw)\([^\)]*\):", code, flags=re.MULTILINE)): + msg = 'Your code contains ' + \ + (f'a {ms[0]}() function.' if len(ms) == 1 else 'setup() and draw() functions.') + if tool: + msg += f' When using {tool}, your code is written in static mode, without defining a setup() function or a draw() function.' + else: + msg += 'When coding in static mode, your code should not define a setup() function or draw() function.' + return False, msg + + # does the code parse? if not, return an error message + try: + sketch_ast = ast.parse(code, filename=filename, mode='exec') + except IndentationError as e: + msg = f'There is an indentation problem with your code on line {e.lineno}:\n' + arrow_msg = f'--> {e.lineno} ' + msg += f'{arrow_msg}{e.text}' + msg += ' ' * (len(arrow_msg) + e.offset) + '^' + return False, msg + except Exception as e: + msg = stackprinter.format(e) + m = re.search(r'^SyntaxError:', msg, flags=re.MULTILINE) + if m: + msg = msg[m.start(0):] + msg = 'There is a problem with your code:\n' + msg + return False, msg + + # check for assignments to or deletions of reserved words + problems = check_reserved_words(code, sketch_ast) + if problems: + msg = 'There ' + ('is a problem' if len(problems) == + 1 else f'are {len(problems)} problems') + ' with your code.\n' + msg += '=' * len(msg) + '\n' + '\n'.join(problems) + return False, msg + + cutoff1, cutoff2 = split_setup.find_cutoffs( + code, 'imported', static_mode=True) + lines = code.splitlines(keepends=True) + py5static_globals = ''.join(lines[:cutoff1]) + py5static_settings = ''.join(lines[cutoff1:cutoff2]) + py5static_setup = ''.join(lines[cutoff2:]) + + # check for calls to size, etc, that were not at the beginning of the code + problems = split_setup.check_for_special_functions( + py5static_setup, 'imported') + if problems: + msg = 'There ' + ('is a problem' if len(problems) == + 1 else f'are {len(problems)} problems') + ' with your code.\n' + msg += 'The function ' + \ + ('call' if len(problems) == 1 else 'calls') + ' to ' + problems = [ + f'{name} (on line {i + cutoff2 + 1})' for i, + name in problems] + if len(problems) == 1: + msg += problems[0] + elif len(problems) == 2: + msg += f'{problems[0]} and {problems[1]}' + else: + msg += ', and '.join(', '.join(problems).rsplit(', ', maxsplit=1)) + msg += ' must be moved to the beginning of your code, before any other code.' + return False, msg + + return True, (py5static_globals, py5static_settings, py5static_setup) diff --git a/py5_tools/printstreams.py b/py5_tools/printstreams.py index a9ed3e2..463509a 100644 --- a/py5_tools/printstreams.py +++ b/py5_tools/printstreams.py @@ -1,7 +1,7 @@ # ***************************************************************************** # # Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz +# Copyright (C) 2020-2023 Jim Schmitz # # This library is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by diff --git a/py5_tools/py5bot/__init__.py b/py5_tools/py5bot/__init__.py deleted file mode 100644 index 707457d..0000000 --- a/py5_tools/py5bot/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# ***************************************************************************** -# -# Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz -# -# This library is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# -# ***************************************************************************** -from .kernel import Py5BotKernel # noqa diff --git a/py5_tools/py5bot/__main__.py b/py5_tools/py5bot/__main__.py deleted file mode 100644 index 11f06f4..0000000 --- a/py5_tools/py5bot/__main__.py +++ /dev/null @@ -1,22 +0,0 @@ -# ***************************************************************************** -# -# Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz -# -# This library is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# -# ***************************************************************************** -from .kernel import Py5BotApp - -Py5BotApp.launch_instance() diff --git a/py5_tools/py5bot/install.py b/py5_tools/py5bot/install.py deleted file mode 100644 index 46cef77..0000000 --- a/py5_tools/py5bot/install.py +++ /dev/null @@ -1,89 +0,0 @@ -# ***************************************************************************** -# -# Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz -# -# This library is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# -# ***************************************************************************** -import os -import sys -import shutil -from pathlib import Path -import argparse -import json - -from jupyter_client.kernelspec import KernelSpecManager -from IPython.utils.tempdir import TemporaryDirectory - - -kernel_json = { - "argv": [ - sys.executable, - "-m", - "py5_tools.py5bot", - "-f", - "{connection_file}"], - "display_name": "py5bot", - "language": "python", -} - - -def install_py5bot_kernel_spec(user=True, prefix=None): - with TemporaryDirectory() as td: - os.chmod(td, 0o755) # Starts off as 700, not user readable - with open(Path(td) / 'kernel.json', 'w') as f: - json.dump(kernel_json, f, sort_keys=True) - - # Copy any resources - for file in (Path(__file__).parent / 'resources').glob('*'): - shutil.copy(file, Path(td) / file.name) - - print('Installing py5bot Jupyter kernel spec') - KernelSpecManager().install_kernel_spec( - td, 'py5bot', user=user, prefix=prefix) - - -def _is_root(): - try: - return os.geteuid() == 0 - except AttributeError: - return False # assume not an admin on non-Unix platforms - - -def main(argv=None): - ap = argparse.ArgumentParser() - ap.add_argument( - '--user', - action='store_true', - help="Install to the per-user kernels registry. Default if not root.") - ap.add_argument( - '--sys-prefix', - action='store_true', - help="Install to sys.prefix (e.g. a virtualenv or conda env)") - ap.add_argument( - '--prefix', help="Install to the given prefix. " - "Kernelspec will be installed in {PREFIX}/share/jupyter/kernels/") - args = ap.parse_args(argv) - - if args.sys_prefix: - args.prefix = sys.prefix - if not args.prefix and not _is_root(): - args.user = True - - install_py5bot_kernel_spec(user=args.user, prefix=args.prefix) - - -if __name__ == '__main__': - main() diff --git a/py5_tools/py5bot/kernel.py b/py5_tools/py5bot/kernel.py deleted file mode 100644 index 7fc0230..0000000 --- a/py5_tools/py5bot/kernel.py +++ /dev/null @@ -1,101 +0,0 @@ -# ***************************************************************************** -# -# Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz -# -# This library is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# -# ***************************************************************************** -import sys - -from ipykernel.zmqshell import ZMQInteractiveShell -from IPython.core.interactiveshell import InteractiveShellABC -from ipykernel.kernelapp import IPKernelApp - -from traitlets import Type, Instance, Unicode, List - -from ..kernel.kernel import Py5Kernel -from .. import split_setup -from . import py5bot -from ..parsing import TransformDynamicVariablesToCalls, Py5CodeValidation - - -class Py5BotShell(ZMQInteractiveShell): - - # needed to make sure code using the %%python bypass gets transformed - ast_transformers = List( - [TransformDynamicVariablesToCalls(), Py5CodeValidation()]).tag(config=True) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._py5bot_mgr = py5bot.Py5BotManager() - - banner2 = Unicode("Activating py5bot").tag(config=True) - - def run_cell(self, raw_cell, *args, **kwargs): - # TODO: deprecated - self.log.warning("This kernel is deprecated. Uninstall it with `jupyter kernelspec uninstall py5bot`, install the new py5jupyter package, and then install the kernel with `python -m py5jupyter.kernels.py5bot.install --sys-prefix`.") - - # check for special code that should bypass py5bot processing - if raw_cell.strip().startswith('%%python\n'): - return super( - Py5BotShell, - self).run_cell( - raw_cell.replace( - '%%python\n', - ''), - * - args, - **kwargs) - - success, result = py5bot.check_for_problems(raw_cell, "") - if success: - py5bot_globals, py5bot_settings, py5bot_setup = result - if split_setup.count_noncomment_lines(py5bot_settings) == 0: - py5bot_settings = 'size(100, 100, HIDDEN)' - self._py5bot_mgr.write_code( - py5bot_globals, py5bot_settings, py5bot_setup) - - return super( - Py5BotShell, - self).run_cell( - self._py5bot_mgr.run_code, - *args, - **kwargs) - else: - print(result, file=sys.stderr) - return super(Py5BotShell, self).run_cell('None', *args, **kwargs) - - -InteractiveShellABC.register(Py5BotShell) - - -class Py5BotKernel(Py5Kernel): - shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', - allow_none=True) - shell_class = Type(Py5BotShell) - - implementation = 'py5bot' - implementation_version = '0.8.3a1' - - -class Py5BotApp(IPKernelApp): - name = 'py5bot-kernel' - - kernel_class = Type('py5_tools.py5bot.Py5BotKernel', - klass='ipykernel.kernelbase.Kernel').tag(config=True) - - exec_lines = List(Unicode(), [ - '%%python\n' + py5bot.PY5BOT_CODE_STARTUP - ]).tag(config=True) diff --git a/py5_tools/py5bot/py5bot.py b/py5_tools/py5bot/py5bot.py deleted file mode 100644 index ddd8e8b..0000000 --- a/py5_tools/py5bot/py5bot.py +++ /dev/null @@ -1,219 +0,0 @@ -# ***************************************************************************** -# -# Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz -# -# This library is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# -# ***************************************************************************** -import ast -import re -from pathlib import Path -import tempfile - -import stackprinter - -from .. import parsing -from .. import split_setup - - -PY5BOT_CODE_STARTUP = """ -import functools -import ast as _PY5BOT_ast - -from IPython.display import SVG as _PY5BOT_SVG - -import py5_tools -py5_tools.set_imported_mode(True) -from py5 import * -from py5 import _prepare_dynamic_variables as _PY5BOT_PREPARE_DYNAMIC_VARIABLES -import py5_tools.parsing as _PY5BOT_parsing - - -@functools.wraps(size) -def _PY5BOT_altered_size(*args): - import sys - if len(args) == 2: - args = *args, HIDDEN - elif len(args) >= 3 and isinstance(renderer := args[2], str): - renderer_name = {SVG: 'SVG', PDF: 'PDF', DXF: 'DXF', P2D: 'P2D', P3D: 'P3D', HIDDEN: 'HIDDEN', JAVA2D: 'JAVA2D'}.get(renderer, renderer) - if renderer in [SVG, PDF]: - if not (len(args) >= 4 and isinstance(args[3], str)): - print(f'If you want to use the {renderer_name} renderer, the 4th parameter to size() must be a filename to save the {renderer_name} to.') - args = *args[:2], HIDDEN, *args[3:] - else: - renderers = [HIDDEN, JAVA2D] if sys.platform == 'darwin' else [HIDDEN, JAVA2D, P2D, P3D] - if renderer not in renderers: - print(f'Sorry, py5bot does not support the {renderer_name} renderer' + (' on OSX.' if sys.platform == 'darwin' else '.'), file=sys.stderr) - args = *args[:2], HIDDEN, *args[3:] - if renderer == JAVA2D: - args = *args[:2], HIDDEN, *args[3:] - size(*args) - - -del functools -""" - - -PY5BOT_CODE = """ -_PY5BOT_OUTPUT_ = None -reset_py5() -_PY5_NS_ = locals().copy() -_PY5_NS_['size'] = _PY5BOT_altered_size -_PY5BOT_PREPARE_DYNAMIC_VARIABLES(_PY5_NS_, _PY5_NS_) - - -def _py5bot_settings(): - with open('{0}', 'r') as f: - exec( - compile( - _PY5BOT_parsing.transform_py5_code( - _PY5BOT_ast.parse(f.read(), filename='{0}', mode='exec'), - ), - filename='{0}', - mode='exec' - ), - _PY5_NS_ - ) - - -def _py5bot_setup(): - global _PY5BOT_OUTPUT_ - - with open('{1}', 'r') as f: - exec( - compile( - _PY5BOT_parsing.transform_py5_code( - _PY5BOT_ast.parse(f.read(), filename='{1}', mode='exec'), - ), - filename='{1}', - mode='exec' - ), - _PY5_NS_ - ) - - sketch_renderer = get_current_sketch()._instance.sketchRenderer() - if sketch_renderer == SVG: - _PY5BOT_OUTPUT_ = _PY5BOT_SVG() - elif sketch_renderer != PDF: - from PIL import Image - load_np_pixels() - _PY5BOT_OUTPUT_ = Image.fromarray(np_pixels()[:, :, 1:]) - - exit_sketch() - - -run_sketch(sketch_functions=dict(settings=_py5bot_settings, setup=_py5bot_setup), block=True, _osx_alt_run_method=False) -if is_dead_from_error: - exit_sketch() - -if isinstance(_PY5BOT_OUTPUT_, _PY5BOT_SVG): - try: - with open(str(get_current_sketch()._instance.sketchOutputPath()), 'r') as f: - _PY5BOT_OUTPUT_.data = f.read() - except: - pass - -del _PY5_NS_, _py5bot_settings, _py5bot_setup - -_PY5BOT_OUTPUT_ -""" - - -def check_for_problems(code, filename): - # if the code contains a setup() or a draw() function, the user could be - # confused about static mode - if (ms := re.findall( - r"^def (setup|draw)\([^\)]*\):", code, flags=re.MULTILINE)): - msg = 'Your code contains ' + \ - (f'a {ms[0]}() function.' if len(ms) == 1 else 'setup() and draw() functions.') - msg += ' When using py5bot, your code is written in static mode, without defining a setup() function or a draw() function.' - return False, msg - - # does the code parse? if not, return an error message - try: - sketch_ast = ast.parse(code, filename=filename, mode='exec') - except IndentationError as e: - msg = f'There is an indentation problem with your code on line {e.lineno}:\n' - arrow_msg = f'--> {e.lineno} ' - msg += f'{arrow_msg}{e.text}' - msg += ' ' * (len(arrow_msg) + e.offset) + '^' - return False, msg - except Exception as e: - msg = stackprinter.format(e) - m = re.search(r'^SyntaxError:', msg, flags=re.MULTILINE) - if m: - msg = msg[m.start(0):] - msg = 'There is a problem with your code:\n' + msg - return False, msg - - # check for assignments to or deletions of reserved words - problems = parsing.check_reserved_words(code, sketch_ast) - if problems: - msg = 'There ' + ('is a problem' if len(problems) == - 1 else f'are {len(problems)} problems') + ' with your code.\n' - msg += '=' * len(msg) + '\n' + '\n'.join(problems) - return False, msg - - cutoff1, cutoff2 = split_setup.find_cutoffs( - code, 'imported', static_mode=True) - lines = code.splitlines(keepends=True) - py5bot_globals = ''.join(lines[:cutoff1]) - py5bot_settings = ''.join(lines[cutoff1:cutoff2]) - py5bot_setup = ''.join(lines[cutoff2:]) - - # check for calls to size, etc, that were not at the beginning of the code - problems = split_setup.check_for_special_functions( - py5bot_setup, 'imported') - if problems: - msg = 'There ' + ('is a problem' if len(problems) == - 1 else f'are {len(problems)} problems') + ' with your code.\n' - msg += 'The function ' + \ - ('call' if len(problems) == 1 else 'calls') + ' to ' - problems = [ - f'{name} (on line {i + cutoff2 + 1})' for i, - name in problems] - if len(problems) == 1: - msg += problems[0] - elif len(problems) == 2: - msg += f'{problems[0]} and {problems[1]}' - else: - msg += ', and '.join(', '.join(problems).rsplit(', ', maxsplit=1)) - msg += ' must be moved to the beginning of your code, before any other code.' - return False, msg - - return True, (py5bot_globals, py5bot_settings, py5bot_setup) - - -class Py5BotManager: - - def __init__(self): - self.tempdir = Path(tempfile.TemporaryDirectory().name) - self.tempdir.mkdir(parents=True, exist_ok=True) - self.settings_filename = self.tempdir / '_PY5_STATIC_SETTINGS_CODE_.py' - self.setup_filename = self.tempdir / '_PY5_STATIC_SETUP_CODE_.py' - self.startup_code = PY5BOT_CODE_STARTUP - self.run_code = PY5BOT_CODE.format( - self.settings_filename.as_posix(), - self.setup_filename.as_posix()) - - def write_code(self, global_code, settings_code, setup_code): - with open(self.settings_filename, 'w') as f: - f.write('\n' * sum(c == '\n' for c in global_code)) - f.write(settings_code) - - with open(self.setup_filename, 'w') as f: - f.write(global_code) - f.write('\n' * sum(c == '\n' for c in settings_code)) - f.write(setup_code) diff --git a/py5_tools/py5bot/resources/logo-32x32.png b/py5_tools/py5bot/resources/logo-32x32.png deleted file mode 100644 index 1a3e992c125f5448ce68b28ff2121b2779b725e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2541 zcmV{+P)GD zleQV#$uu9;=-B?K(@lyRCTWJTnu&afskKTvfq)1b`3M5{-rc*G-Mx43=?``ZDET@w z@6679?>*-^=Y8I@=VAB~3j_kfmMvQni9{mxNGL8Y&Mhr1UEuL}+@@)=P$(ofHa7Nm zcX#&!NC1E!2sn1^m{3_+nfN^40KmRzkBAs!%ml#p?Adc~X=!OiR#w(svu4f8b2uCh zyWI}P7-F#)B9TZ$mgU}|p`oUxrl$HAUwrWt0F#I~V~haMmnA!Ce!pK}Yyw+NO-*HU zbMuAK(NUVg%xE-fs;Wxk$xK2FcS@LS3&D5CF{+(*BD=$G{1 zJ>RFz>&j`1|3TXK)IK_N^mRJh+C-lWd_r+Oo**KFi0J(J^HzLw16R>` ztqYxlUFZ)F!S1#rBF0g+z6?Kp_+i6tw~OuV?NUum&ANt$hKtWW`z+tTf4_;T!HI}x zW@cuzwzdX|h$KnUB}pP8qJyu!N`-gdM-Tt}d0Kc|5v^Xfl6HRQCsg;)FX+vu|3a5v zYNoNj^-=uzC`I2KrdNOV63ug@)4DZl$S@2V9T_o*h+0}&f|;3_8AQZuYis#r1&Bys zj3okrK!e}!-=rvt!8sQV!+_W8MQzP97@S>%dw=vpyu52GHsyZ{7Kam^SK9IE^#Q0M z3AYf#t#fi9YhhSP!u^FMXcSc(_~Rd-C<+*3hTH8H-+1GVhRVvy@>EQ*wzgK}oEz2E z)fF2yY}lk}n!y+oQ|twRq3a{C=elvde-wtIV9BD}k&(FotBUV}X_^RWA%s*JjprIM z+;<-D?0*gQZ@&pgh8v7A5D_@%qNZuah7B9OS6y9Q!8xxF1Ofto?z!g@L?oB+9I-7wI5ts8UG9N zRaI*kVWACrgeY1-bVFlf42m*> zh3RvESQL^T#r%2MFbsVv02qd0dc9s+vt~^t0B`_eZf@>fM8t@QPX!=~77Pv!g4<`o zY7?PcA4K-t`4B`ACYeZ>37Dn{5TF|dBC3Sk*%=@;jHtknk&yvi*Qeo3#$egm*>?jF z#p2@Pg>JVyFZpM~rUKv$=)ZOiX`VT7c{zr9KE~|04Qg0{)8>NJW`k*((DfLidJOt_ z7+LOg43CX~IqgVydtm6FRUlQXk}_d0{{SnpAKVgUIC81 z@Oy;&I?yvO8?}d@hJ)LY<;g9<11Hjvhgs=EAB_#;lILaPs7NkgXr(; zL0@+lE?wzDQ&TI#BNE1fS8(uOZ(;D0AUwr+lUMLYBO=pgvvH5d;}&n)O&aGMhGF2& zJHCkz+blYu-a@8Ef&1}j{uaj@8FVp1xK4t;oa)D zq3b$0zbU6_Cd#s`M59qS9FA#ka?YV?8g}g1iLG0=qNlqHot>TN=;%cE`;BO-ABDj< z>~1d#miy4x-G%Od{}-$7S&RRi{{Z><`G`a!GXh|Y@mMSdS(X*CrKKep4u{9Hva;;) zc$}v4fH4MD4TE!zg2E+OR=j-Di7bsF*cU{{M<1cHs|$iO4F6Ae;;E;egqcV{Rn=){ zKc)O+u~=9*93F3JX$gw$?d?HXmU~4}T#AXQWg2Bu8APK|3=It-BO?RjO zu-xZMIR;}4{nz^8bU9}Xp28pq0#g*Fx4peR$N?Aw0|QL}C^>%JWTt7t>2zY(t}4{k z{R&>M7gnnki~+G&6q=@iF^1~uXRu@EF1TE-iT*HyF~&^B81?n_H3Kk20C?}c_X1^Q zWjm}^D>n?|#(N6@h{xl2<&{6-jyqPuX0yTXe*mf)0RT804xBh~0*4MA#)S)Qh{xlf zmpw#LmOL9$r-qF!X$)RS_kD@3PiA3~JC`8rO)fJ2})YjIDsVWEn5C{a`A|jGy zSxxeN%`T0wzzWxMl+x7?noB&SSwmm}i^(QDle+eL znx;`I8CjNfBBDSb&@eS7faxPyOG`^IInf%a?2jBdN=cH^_U(_-#Gv`XWX9*ue?UY; z+qXYTDGhMs$kE9vNRp%z5w*6q-ZYX;1Hl+Wd3kxs<;$1HQgdO71CKrSMDm>H(B8dI z(ux(Uh;xxR7iqe)9 zZEaVHh(e)|5sgL@0|SG^`7JZ>VEW?x78)2Bq-Zpn2#3Qu5m8%PTkpn=8+}t_e6CFu zCMQpxoD?SUcsz0N;32)Fq$E*PRBRR&E~A2irBqO`lnM)%QBhH`SyEDxIC$`o9*@Tp zL_~_BP(wq*@wBwGuO>`VcB3?FZEc+<&EoMGX_`i=s+y{*nwq9jEEb#G|2op_tBO;; zZ{NOeuUxsZA}1&3ZjZ;4=X5$9R;v{NCdH{FNxi{fu=(7%bM*%f9B9Nu>;FP=`b7W$ z%q-6rFJ7EiR#rAYJw4r%B&%}f%$aLlU0r?nn)3Yr43#SQkm^GA00000NkvXXu0mjf D;Fi1} diff --git a/py5_tools/py5bot/resources/logo-64x64.png b/py5_tools/py5bot/resources/logo-64x64.png deleted file mode 100644 index dad6ad24d9f811e070ad1e6ed986a930d57f6c67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6819 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 py5 py5-processing4 - 0.8.3a1 + 0.9.0a0 system ${{jarlocation}}/core.jar py5 py5-jogl - 0.8.3a1 + 0.9.0a0 system ${{jarlocation}}/jogl-all.jar py5 py5 - 0.8.3a1 + 0.9.0a0 system ${{jarlocation}}/py5.jar @@ -133,14 +136,23 @@ def generate_utilities_framework(output_dir=None): java_dir.mkdir(parents=True, exist_ok=True) jars_dir.mkdir(exist_ok=True) - with open(java_dir / 'pom.xml', 'w') as f: - f.write(POM_TEMPLATE.format(classpath=py5_classpath)) + pom_filename = java_dir / 'pom.xml' + if pom_filename.exists(): + print(f"Skipping {pom_filename}: file already exists", file=sys.stderr) + else: + with open(pom_filename, 'w') as f: + f.write(POM_TEMPLATE.format(classpath=py5_classpath)) utils_filename = java_dir / \ Path('src/main/java/py5utils/Py5Utilities.java') - utils_filename.parent.mkdir(parents=True, exist_ok=True) - with open(utils_filename, 'w') as f: - f.write(PY5_UTILITIES_CLASS) + if utils_filename.exists(): + print( + f"Skipping {utils_filename}: file already exists", + file=sys.stderr) + else: + utils_filename.parent.mkdir(parents=True, exist_ok=True) + with open(utils_filename, 'w') as f: + f.write(PY5_UTILITIES_CLASS) __all__ = ['generate_utilities_framework'] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4250343 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,71 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "py5" +dynamic = ["version"] +description = "Processing for CPython" +readme = "README.md" +license = "" +requires-python = ">3.8" +authors = [ + { name = "Jim Schmitz", email = "jim@ixora.io" }, +] +keywords = [ + "IPython", + "Jupyter", + "Processing", + "Widgets", +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Intended Audience :: Education", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)", + "Programming Language :: Java", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Topic :: Artistic Software", + "Topic :: Multimedia :: Graphics", +] +dependencies = [ + "autopep8>=2.0", + "jpype1>=1.4", + "line_profiler>=4.0", + "numpy>=1.23", + "pillow>=9.2", + "pyobjc>=9.0;sys_platform==\"darwin\"", + "requests>=2.28", + "stackprinter>=0.2.4", +] + +[project.optional-dependencies] +jupyter = [ + "py5jupyter>=0.2.0a0", +] + +[project.scripts] +py5cmd = "py5_tools.tools.py5cmd:main" +py5translate-imported2module = "py5_tools.tools.py5translate_imported2module:main" +py5translate-module2imported = "py5_tools.tools.py5translate_module2imported:main" +py5translate-processingpy2imported = "py5_tools.tools.py5translate_processingpy2imported:main" +py5utils = "py5_tools.tools.py5utils:main" +run_sketch = "py5_tools.tools.run_sketch:main" + +[project.urls] +"Bug Tracker" = "https://github.com/py5coding/py5generator/issues" +Documentation = "https://py5coding.org/" +Download = "https://pypi.org/project/py5" +Homepage = "https://py5coding.org/" +"Source Code" = "https://github.com/py5coding/py5" + +[tool.hatch.version] +path = "py5/__init__.py" + +[tool.hatch.build] +packages = [ + "/py5", + "/py5_tools", +] diff --git a/setup.py b/setup.py index 1567f9f..b6c6681 100644 --- a/setup.py +++ b/setup.py @@ -1,105 +1,2 @@ -# ***************************************************************************** -# -# Part of the py5 library -# Copyright (C) 2020-2022 Jim Schmitz -# -# This library is free software: you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# -# ***************************************************************************** -import os -from setuptools import setup - -with open('README.md') as f: - README = f.read() - -VERSION = '0.8.3a1' - -INSTALL_REQUIRES = [ - 'autopep8>=1.5', - 'ipykernel>=5.3', - 'ipython>=7.22', - 'ipywidgets>=7.6', - 'jpype1>=1.3', - 'line_profiler>=2.1.2', - 'numpy>=1.22', - 'pandas>=1.0', - 'pillow>=8.1', - 'pyobjc>=7.3;sys_platform=="darwin"', - 'requests>=2.25', - 'stackprinter>=0.2.4', - 'traitlets>=5.0', -] - -pjoin = os.path.join -here = os.path.abspath(os.path.dirname(__file__)) - -packages = [] -for d, _, _ in [*os.walk(pjoin(here, 'py5')), * - os.walk(pjoin(here, 'py5_tools'))]: - if os.path.exists(pjoin(d, '__init__.py')): - packages.append(d[len(here)+1:].replace(os.path.sep, '.')) - -setup_args = dict( - name='py5', - version=VERSION, - packages=packages, - package_data={ - "py5": ['jars/*.jar', 'jars/*/*.jar', 'natives/*/*.dll', 'natives/*/*.so', 'natives/*/*.dylib'], - "py5_tools": ['kernel/resources/*.png', 'py5bot/resources/*.png'], - }, - python_requires='>3.8', - install_requires=INSTALL_REQUIRES, - extras_require={ - 'jupyter': ['py5jupyter>=0.1.2a1'], - }, - description='Processing for CPython', - long_description=README, - long_description_content_type='text/markdown', - url='https://py5coding.org/', - author='Jim Schmitz', - author_email='jim@ixora.io', - download_url='https://pypi.org/project/py5', - project_urls={ - "Bug Tracker": 'https://github.com/py5coding/py5generator/issues', - "Documentation": 'https://py5coding.org/', - "Source Code": 'https://github.com/py5coding/py5', - }, - platforms=["Windows", "Linux", "Mac OS-X"], - keywords=['Jupyter', 'Widgets', 'IPython', 'Processing'], - entry_points={ - 'console_scripts': [ - 'run_sketch = py5_tools.tools.run_sketch:main', - 'py5cmd = py5_tools.tools.py5cmd:main', - 'py5utils = py5_tools.tools.py5utils:main', - 'py5translate-module2imported = py5_tools.tools.py5translate_module2imported:main', - 'py5translate-imported2module = py5_tools.tools.py5translate_imported2module:main', - 'py5translate-processingpy2imported = py5_tools.tools.py5translate_processingpy2imported:main', - ], - }, - classifiers=[ - 'Intended Audience :: Developers', - 'Intended Audience :: Education', - 'Intended Audience :: Science/Research', - 'Topic :: Artistic Software', - 'Topic :: Multimedia :: Graphics', - 'Development Status :: 3 - Alpha', - 'License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Java', - ], -) - -if __name__ == '__main__': - setup(**setup_args) +# setup.py shim for use with applications that require it. +__import__("setuptools").setup()