diff --git a/docs/html b/docs/html deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/requirements.txt b/docs/requirements.txt index 5b607e9c8b..d0a2410c8b 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,4 +4,5 @@ sphinx>=7.3 sphinx-copybutton sphinxext-opengraph sphinx-design +sphinx-togglebutton sphinx-reredirects diff --git a/docs/rtd-requirements.txt b/docs/rtd-requirements.txt index 3220975d34..083a9af9a7 100644 --- a/docs/rtd-requirements.txt +++ b/docs/rtd-requirements.txt @@ -1,2 +1,3 @@ jupyterlab sphinxcontrib-programoutput +sphinx-design diff --git a/docs/skip-manim b/docs/skip-manim deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/source/_static/AdventureManim.png b/docs/source/_static/AdventureManim.png new file mode 100644 index 0000000000..754145a9a8 Binary files /dev/null and b/docs/source/_static/AdventureManim.png differ diff --git a/docs/source/adventure/basics.rst b/docs/source/adventure/basics.rst new file mode 100644 index 0000000000..cfd5088605 --- /dev/null +++ b/docs/source/adventure/basics.rst @@ -0,0 +1,696 @@ +****************************************************** +An Adventure through Manim's Features and Capabilities +****************************************************** + +.. image:: ../_static/AdventureManim.png + :align: center + + +**Authors:** `Tristan Schulz `__ and `Aarush Deshpande `__ + +.. note:: This is a work in progress guide and might not be complete at this point + +############## +What to expect +############## +This guide will take you on a Tour through the features and capabilities of Manim. The goal is to give you a good overview of what Manim can do and how to use it. It is not meant to be a complete reference, but rather a starting point for your own explorations. + +The goal of this guide is to give you a clear path from the basics of Manim to a finished animation. It will not go into detail about the inner workings of Manim, but rather focus on the practical aspects of using it. +At the end of this guide you should be able to create your own animations and have a good understanding of how to use Manim. + +.. warning:: + Please note that this guide is only for Manim and expects basic knowledge about programming with Python. If you are new to Python you should first learn the basics of Python before you start with Manim. + You can find a full introduction to Python here: https://docs.python.org/3/tutorial/ + + You can still follow this guide with basic knowledge of Python, but you will have to learn some Python basics along the way in order to understand the code examples. + +################# +What are Mobjects +################# + +Mobjects are the basic building blocks of Manim. They are the objects that are animated and displayed on the screen. +Mobjects can be anything from simple shapes to complex 3D objects. They can be animated, moved, rotated, scaled and much more. +In this guide we will focus on the 2D Mobjects, but the same principles apply to 3D Mobjects as well. + +.. manim:: MobjectsFloating + :hide_source: + + class MobjectsFloating(Scene): + def construct(self): + c = Circle() + s = Square() + t = Triangle() + c.shift(UP) + t.shift(LEFT*3+DOWN) + s.shift(RIGHT*3+DOWN) + self.add(c, s, t) + timer = ValueTracker(0) + c.add_updater(lambda m: m.move_to(UP+0.2*DOWN*np.sin(timer.get_value()+1))) + s.add_updater(lambda m: m.move_to(RIGHT*3+DOWN+0.3*DOWN*np.sin(timer.get_value()+2))) + t.add_updater(lambda m: m.move_to(LEFT*3+DOWN+0.3*DOWN*np.sin(timer.get_value()+4))) + self.add(timer) + self.play(timer.animate.set_value(2*np.pi), run_time=5, rate_func=linear) + + + +For a list of all Mobjects you can look at the :doc:`/reference_index/mobjects` Documentation Page. There are many more to explore and you can even create your own Mobjects, which we will cover later. + + +.. manim:: PredefinedMobjects + :save_last_frame: + :hide_source: + + class PredefinedMobjects(Scene): + def construct(self): + c = Circle() + s = Square().set_color(GREEN) + t = Triangle() + graph = FunctionGraph(lambda x: np.sin(x)) + axis = Axes() + par = ParametricFunction(lambda t: np.array([np.cos(3*t), np.sin(2*t), 0]), [0, 2*np.pi]) + mat = Matrix([["\\pi", 0], [0, 1]]) + chart = BarChart( + values=[-5, 40, -10, 20, -3], + bar_names=["one", "two", "three", "four", "five"], + y_range=[-20, 50, 10], + y_length=6, + x_length=10, + x_axis_config={"font_size": 36}, + ).shift(RIGHT/2) + func = lambda pos: ((pos[0] * UR + pos[1] * LEFT) - pos) / 3 + vecfield = ArrowVectorField(func,x_range=[-3,3],y_range=[-3,3]) + cross = VGroup( + Line(UP + LEFT, DOWN + RIGHT), + Line(UP + RIGHT, DOWN + LEFT)) + a = Circle().set_color(RED).scale(0.5) + b = cross.set_color(BLUE).scale(0.5) + t3 = MobjectTable( + [[a.copy(),b.copy(),a.copy()], + [b.copy(),a.copy(),a.copy()], + [a.copy(),b.copy(),b.copy()]]) + t3.add(Line( + t3.get_corner(DL), t3.get_corner(UR) + ).set_color(RED)) + + group = [c, s, t, graph, axis, par, mat, chart, vecfield, t3] + names = ["Circle", "Square", "Triangle", "FunctionGraph", "Axes", "ParametricFunction", "Matrix", "BarChart" ,"ArrowVectorField", "MobjectTable"] + zipped = zip(group, names) + combined = [] + for mob, name in zipped: + square = Square() + name = Text(name).scale(0.5) + mob.scale_to_fit_width(square.get_width()) + square.scale(1.2) + name.next_to(square, DOWN) + group = VGroup(mob, name, square) + combined.append(group) + + all = VGroup(*combined).arrange_in_grid(buff=1,rows=2).scale(0.8).to_edge(UP) + dots = MathTex("\\dots").next_to(all, DOWN, buff=1) + self.add(all, dots) + +.. note:: + The type of Mobject that is used most of the time is the `VMobject`. This is a Mobject that is made up of `VectorizedPoints`. These are points that are defined by their coordinates and can be connected by lines or curves. + Every time we talk about Mobjects in this guide we mean VMobjects, unless we state otherwise. + +============================= +Mobjects and their Attributes +============================= + +In order to display Mobjects in your animations you need to add them to the scene. You can do this by calling ``self.add(mobject)`` in the ``construct`` method of your scene. +This tells Manim that you want to display the Mobject in your scene. + +.. manim:: CreatingMobjects + :save_last_frame: + + class CreatingMobjects(Scene): + def construct(self): + c = Circle() + self.add(c) + +This will be the basic structure of all your animations. You will create Mobjects and add them to the scene. Then you can animate them and change their properties. +Try the "Make Interactive" Button and see if you can create a `Square` instead of a `Circle`. + +The first line is the name of your scene, in this case it is ``CreatingMobjects``. It inherits from ``Scene``: as we explore later, you'll find examples where we inherit from +class other than ``Scene`` to gain access to more specialized methods. Your animation must take place in the ``construct`` method of your scene, otherwise it will not render. + +You can run this scene on your local machine by saving it in a file called ``my_first_scene.py`` and running ``manim -pqm my_first_scene.py`` in the terminal. + +------------------ +Mobject Attributes +------------------ + +Mobjects also posses many attributes that you can change. For example you can change the color of a Mobject by calling ``mobject.set_color(color)`` or scale it by calling ``mobject.scale(factor)``. + +The basic attributes are the ``points``, ``fill_color``, ``fill_opacity``, ``stroke_color``, ``stroke_opacity``, ``stroke_width``. +The ``points`` define the outline of the Mobject, whereas the color attributes define how this outline is displayed. + +A full list of the attributes of :class:`VMobject` can be found in the :doc:`../reference/manim.mobject.types.vectorized_mobject.VMobject` Documentation Page. Please note that depending +on the type of Mobject you are using, there might be additional attributes, which are listed on the corresponding documentation page. + +------------------- +Changing the Points +------------------- + +Most of the function that you will use in Manim will be functions that change the points of a Mobject. For example ``mobject.shift(direction)`` will move the Mobject in the given direction. +On the other hand, ``mobject.rotate(angle)`` will rotate the Mobject by the given angle. + +.. manim:: MobjectPoints + :save_last_frame: + + class MobjectPoints(Scene): + def construct(self): + c = Circle() + s = Square() + t = Triangle() + + c.shift(3*LEFT) + s.rotate(PI/4) + t.shift(3*RIGHT) + + self.add(c, s, t) + +------------------ +Changing the Color +------------------ + +Changing the color works in the same way but instead of modifying it you can set it to a new value. For example ``mobject.set_fill(color=color)`` will set the fill color of the Mobject to the given color. + +You can also pass in attributes through the constructor of the Mobject. For example ``Circle(fill_color=RED)`` will create a circle with a red fill color. +For a list of parameters that you can pass you can always visit the corresponding Documentation Page in the Reference Manual. + +.. manim:: MobjectColor + :save_last_frame: + + class MobjectColor(Scene): + def construct(self): + c = Circle(fill_color=YELLOW).shift(3*LEFT) + s = Square() + t = Triangle().shift(3*RIGHT) + + c.set_fill(color=RED).set_opacity(1) + s.set_stroke(color=GREEN) + t.set_color(color=BLUE).set_opacity(0.5) + + self.add(c, s, t) + + +------------------- +Test your Knowledge +------------------- + +Now that you saw the basic ways to change Mobjects, try to reproduce the following Image. You can use the "Make Interactive" Button of the above Scene to get started. + +.. manim:: TestYourKnowledge1 + :save_last_frame: + :hide_source: + + class TestYourKnowledge1(Scene): + def construct(self): + c = Circle(fill_color=RED,stroke_color=GREEN).shift(3*LEFT) + s = Square(fill_color=GREEN,stroke_color=BLUE).set_opacity(0.2) + t = Triangle(fill_color=RED,stroke_opacity=0).shift(RIGHT) + + c.set_fill(color=RED).set_opacity(1) + s.set_stroke(color=GREEN) + t.set_color(color=BLUE).set_opacity(0.5) + + self.add(c, s, t) + + +################### +Animations in Manim +################### + +Now that we looked long enough at static Images, let's get to the fun part of Manim. Animations! +Animations are at the core of Manim and are what makes it so powerful. You can animate almost anything in Manim and you can do it in many different ways. +In this section we will look at the different ways to animate Mobjects and how to control the animations. + +.. manim:: Manimations1 + :hide_source: + + class Manimations1(Scene): + def construct(self): + c = Circle().shift(UP).set_color(RED) + s = Square().shift(LEFT*3) + t = Triangle().shift(RIGHT*3) + l = MathTex(r"\mathbf{M}").shift(DOWN).set_fill(opacity=0).set_stroke(color=WHITE, opacity=1, width=5).scale(4) + self.play(AnimationGroup(Create(c), GrowFromCenter(s), Write(l), FadeIn(t), lag_ratio=0.2)) + group = VGroup(l,c, s, t) + self.play(group.animate.arrange(RIGHT)) + self.play(group.animate.arrange(DOWN)) + self.play(group.animate.arrange_in_grid(buff=1,rows=2)) + self.play(Unwrite(group)) + + + +================================ +Introduction to Basic Animations +================================ + +There are multiple ways to animate the addition and removal of mobjects from the scene. The most common ways to introduce mobjects is with ``FadeIn`` or ``Create``, +and the most common ways to remove objects from the scene are their counterparts: ``FadeOut`` and ``Uncreate``. + +.. manim:: BasicAnimations + + class BasicAnimations(Scene): + def construct(self): + c1 = Circle().shift(2*LEFT) + c2 = Circle().shift(2*RIGHT) + self.play(FadeIn(c1), Create(c2)) + self.play(FadeOut(c1), Uncreate(c2)) + +-------- +Runtimes +-------- + +You can adjust the duration of each animation individually, or you can set a duration for all in animations in a ``Scene.play`` call. + +.. manim:: AnimationRuntimes + + class AnimationRuntimes(Scene): + def construct(self): + c = Circle().shift(2*LEFT) + s = Square().shift(2*RIGHT) + # set animation runtimes individually + self.play(Create(c, run_time=2), Create(s, run_time=1)) + # in this call, the individual runtimes of each animation + # are overridden by the runtime in the self.play call + self.play(FadeOut(c, run_time=2), FadeOut(s, run_time=1), run_time=1.5) + +-------------- +Rate Functions +-------------- +A rate function allows you to adjust the speed at an animation proceeds. + +.. manim:: RateFunctionsExample + + class RateFunctionsExample(Scene): + def construct(self): + c1 = Circle().shift(2*LEFT) + c2 = Circle().shift(2*RIGHT) + self.play( + Create(c1, rate_func=rate_functions.linear), + Create(c2, rate_func=rate_functions.ease_in_sine), + run_time=5 + ) + +You can see all of the current ones below: + +.. manim:: AllRateFunctions + :hide_source: + + class AllRateFunctions(Scene): + def construct(self): + time_progress = ValueTracker(0) + func_grid = VGroup() + exclude = ["wraps", "bezier", "sigmoid", "unit_interval", "zero", "not_quite_there", "squish_rate_func"] + rate_funcs = list(filter( + lambda t: str(t[1])[:10] == "`__ and `Aarush Deshpande `__ + +.. note:: This is a work in progress guide and might not be complete at this point + +############ +Introduction +############ +Throughout this guide, we'll walk you through how to create a simple 30 second video about vector addition. If you don't +already know what that is, it's recommended you watch `this `_ video +by the original creator of manim, 3Blue1Brown. + +The next step is figuring out how the project should look: what content should it cover, in what order, etc. In this +tutorial, we'll focus on two parts of vector addition: the algebraic way, and the geometric way. For the algebraic way, +we'll show two vectors (as matrices) being added, and give a short explanation. After that we'll show the typical tip-to-tail +method for adding vectors graphically. Of course, choosing good examples is very important to help the viewer understand. +In our case, we'll use the two vectors :math:`v_1\equiv\langle 2, 1\rangle` and :math:`v_2\equiv\langle 0,-3 \rangle`. + +################ +Vector Addition +################ + +We'll start with the basic setup needed for every manim video. +To do this, we can use the manim cli to speed stuff up. In the terminal, +run:: + + manim init project VectorAddition + +This should create a folder called ``VectorAddition`` with the basic setup. + +.. hint:: + + You may want to open this folder in your IDE (like VS Code, or PyCharm). + +You will have a ``manim.cfg`` file, where you configuration will be stored, and a ``main.py`` script. +The ``main.py`` script is where you will write your scenes. + +If you did it correctly, running the python file with ``manim -p main.py`` should render a scene +with a circle being created: + +.. manim:: CreateCircle + :hide_source: + + class CreateCircle(Scene): + def construct(self): + circle = Circle() + circle.set_fill(PINK, opacity=0.5) + + square = Square() + square.flip(RIGHT) + square.rotate(-3 * TAU / 8) + + self.play(Create(square)) + self.play(Transform(square, circle)) + self.play(FadeOut(square)) + +============ +Introduction +============ +First we need to introduce the viewer to what we're going to talk about. Ideally, +it would be an interesting hook, but for the sake of learning the library we will +stick with a simple text-based intro. Try to recreate the following: + +.. manim:: AdventureIntro + :hide_source: + :ref_classes: Tex Text Write Unwrite Create + + class AdventureIntro(Scene): + def construct(self): + intro = Text("Let's try to add two vectors!") + # put an r"" instead of a normal string so we don't have any special characters like \n + vec_txts = Tex(r"We'll use $\boldsymbol{\vec{v}_1}=(2, 2)$ and $\boldsymbol{\vec{v}_2}=(0, -3)$") + self.play(Create(intro)) + self.wait(1) + # "grey out" the intro and shift it upwards as we write the second line + self.play(intro.animate.shift(2*UP).set_opacity(0.5), Write(vec_txts)) + self.wait(1) + self.play(Unwrite(intro), Unwrite(vec_txts), run_time=.5) + self.wait(0.2) + + +.. admonition:: Authors solution + :class: dropdown + + .. code-block:: python + + class AdventureIntro(Scene): + def construct(self): + intro = Text("Let's try to add two vectors!") + # put an r"" instead of a normal string so we don't have any special characters like \n + vec_txts = Tex( + r"We'll use $\boldsymbol{\vec{v}_1}=(2, 2)$ and $\boldsymbol{\vec{v}_2}=(0, -3)$" + ) + self.play(Create(intro)) + self.wait(1) + # "grey out" the intro and shift it upwards as we write the second line + self.play(intro.animate.shift(2 * UP).set_opacity(0.5), Write(vec_txts)) + self.wait(1) + self.play(Unwrite(intro), Unwrite(vec_txts), run_time=0.5) + self.wait(0.2) + +============================ +Algebraic vector addition +============================ + +Then, let's show the viewer how vector addition between two vectors is done algebraically. +Once again, try to recreate the following: + + +.. manim:: AlgebraicAddition + :hide_source: + :ref_classes: Title MathTex Paragraph Tex Text Write Unwrite Create FadeIn + + class AlgebraicAddition(Scene): + + def construct(self): + title = Title("Vector Addition Algebraically") + + v1x, v1y = (2, 2) + v2x, v2y = (0, -3) + math = MathTex(r""" + \begin{bmatrix} %(v1x)d \\ %(v1y)d \end{bmatrix} + +\begin{bmatrix} %(v2x)d \\ %(v2y)d \end{bmatrix} + """ % { + 'v1x': v1x, + 'v2x': v2x, + 'v1y': v1y, + 'v2y': v2y + }).shift(DOWN) + + resultant_vector = r"=\begin{bmatrix} %(x)d \\ %(y)d \end{bmatrix}" % { + 'x': v1x+v2x, + 'y': v1y+v2y + } + math_with_answer = MathTex( + math.get_tex_string()+resultant_vector + ).move_to(math.get_center()) + + self.play(Write(math), FadeIn(title)) + self.wait(2) + self.play( + math.animate.shift(2*UP).set_opacity(0.5), + Write(math_with_answer) + ) + conclusion = Paragraph("As you can see,\nYou add each component individually").to_edge(DOWN) + self.play(Write(conclusion)) + self.wait(2) + self.play(Unwrite(math), Unwrite(math_with_answer), Unwrite(conclusion), Unwrite(title)) + +Hints +----- + +Use :class:`.Title` to display the title at the top of the Scene. + +Use :class:`.MathTex` to represent the matrices, and try not to hardcode the values into the LaTeX string. Instead, you can use python string formatting and numpy vector addition, which will make it easier to change the vectors later if we need to. + +.. code-block:: python + + v1x, v1y = (2, 2) + v2x, v2y = ... + math = MathTex(r""" + ... %(v1x)d \\ %(v1y)d ... + + ... %(v2x)d \\ %(v2y)d ... + """ % { + 'v1x': v1x, + 'v2x': v2x, + 'v1y': v1y, + 'v2y': v2y + }) + +.. admonition:: Authors solution + :class: dropdown + + .. code-block:: python + + class AlgebraicAddition(Scene): + + def construct(self): + title = Title("Vector Addition Algebraically") + + v1x, v1y = (2, 2) + v2x, v2y = (0, -3) + math = MathTex(r""" + \begin{bmatrix} %(v1x)d \\ %(v1y)d \end{bmatrix} + +\begin{bmatrix} %(v2x)d \\ %(v2y)d \end{bmatrix} + """ % { + 'v1x': v1x, + 'v2x': v2x, + 'v1y': v1y, + 'v2y': v2y + }).shift(DOWN) + + resultant_vector = r"=\begin{bmatrix} %(x)d \\ %(y)d \end{bmatrix}" % { + 'x': v1x+v2x, + 'y': v1y+v2y + } + math_with_answer = MathTex( + math.get_tex_string()+resultant_vector + ).move_to(math.get_center()) + + self.play(Write(math), FadeIn(title)) + self.wait(2) + self.play( + math.animate.shift(2*UP).set_opacity(0.5), + Write(math_with_answer) + ) + conclusion = Paragraph("As you can see,\nYou add each component individually").to_edge(DOWN) + self.play(Write(conclusion)) + self.wait(2) + self.play(Unwrite(math), Unwrite(math_with_answer), Unwrite(conclusion), Unwrite(title)) + +============================ +Geometric vector addition +============================ + +Lastly, let's show the vector addition geometrically. Try your best to reconstruct the following: + +.. manim:: GeometricAddition + :hide_source: + :ref_classes: Title MathTex Paragraph Tex Text Write Unwrite Create FadeIn NumberPlane Arrow AnimationGroup ReplacementTransform VGroup + + class VectorGroup(VGroup): + def __init__( + self, start, end, labelname: str, + vector_color: ParsableManimColor, direction = RIGHT, + plane: NumberPlane | None = None, **kwargs + ) -> None: + if plane is not None: + # if using a plane convert from plane units + # to Munits + start = plane.c2p(*start) + end = plane.c2p(*end) + + self.vector = Arrow( + start, + end, + color=vector_color, + buff=0 + ) + self.label = MathTex(labelname, color=vector_color) + + def label_updater(m: MathTex, d=direction): + m.next_to(self.vector, direction=d, **kwargs) + + self.label.add_updater(label_updater, call_updater=True) + super().__init__(self.vector, self.label, **kwargs) + + @override_animation(Create) + def _create_vec_write_label(self) -> AnimationGroup: + return AnimationGroup( + Create(self.vector), + Write(self.label), + lag_ratio=0 + ) + + @override_animation(Uncreate) + def _uncreate_vec_unwrite_label(self) -> AnimationGroup: + return AnimationGroup( + Uncreate(self.vector), + Unwrite(self.label), + lag_ratio=0 + ) + + class GeometricAddition(Scene): + def construct(self): + title = Text("Now let's take a look at it geometrically") + self.play(Write(title)) + self.wait(2) + self.play(Unwrite(title)) + + plane = NumberPlane() + + sum_point = (2, -1, 0) + + v1 = VectorGroup( + ORIGIN, + (2, 2, 0), + r"\boldsymbol{\vec{v}_1}", + RED, + direction=UP, + plane=plane + ) + + v2 = VectorGroup( + ORIGIN, + (0, -3, 0), + r"\boldsymbol{\vec{v}_2}", + YELLOW, + direction=LEFT, + plane=plane + ) + + v1moved = VectorGroup( + (0, -3, 0), + sum_point, + r"\boldsymbol{\vec{v}_1}", + v1.vector.get_color(), + plane=plane + ) + + v2moved = VectorGroup( + (2, 2, 0), + sum_point, + r"\boldsymbol{\vec{v}_2}", + v2.vector.get_color(), + plane=plane + ) + + sum_vec = VectorGroup( + ORIGIN, + sum_point, + r"\boldsymbol{\vec{v}_1}+\boldsymbol{\vec{v}_2}", + ORANGE, + direction=DOWN, + plane=plane + ) + + self.play(Create(plane), Create(v1)) + self.wait(0.5) + self.play(Create(v2)) + self.wait() + + # animate movement of vectors + self.play( + Succession( + ReplacementTransform(v1.copy(), v1moved), + ReplacementTransform(v2.copy(), v2moved) + ) + ) + self.wait() + # draw sum vector + self.play(Create(sum_vec)) + self.wait() + self.play(*[ + Uncreate(x) + for x in ( + plane, + v1, + v2, + v1moved, + v2moved, + sum_vec + ) + ]) + +Hints +----- + +Use :class:`.NumberPlane` to define the cartesian plane. + +Use :class:`.Arrow` for the vectors.: + +To make sure the label of the vector and the vector shift together, you can define a custom :class:`.VGroup` subclass. +Take a look at the decorator :func:`.override_animation` to override the :class:`.Create` and :class:`.Uncreate` animations, it will come in handy when animating the subclass. + +.. code-block:: python + + class VectorGroup(VGroup): + def __init__( + ... + ) -> None: + ... + + @override_animation(Create) + def _create_vec_write_label(self) -> AnimationGroup: + return AnimationGroup( + ... + ) + + @override_animation(Uncreate) + def _uncreate_vec_unwrite_label(self) -> AnimationGroup: + return AnimationGroup( + ... + ) + +.. admonition:: Authors solution + :class: dropdown + + .. code-block:: python + + class VectorGroup(VGroup): + def __init__( + self, start, end, labelname: str, + vector_color: ParsableManimColor, direction = RIGHT, + plane: NumberPlane | None = None, **kwargs + ) -> None: + if plane is not None: + # if using a plane convert from plane units + # to Munits + start = plane.c2p(*start) + end = plane.c2p(*end) + + self.vector = Arrow( + start, + end, + color=vector_color, + buff=0 + ) + self.label = MathTex(labelname, color=vector_color) + + def label_updater(m: MathTex, d=direction): + m.next_to(self.vector, direction=d, **kwargs) + + self.label.add_updater(label_updater, call_updater=True) + super().__init__(self.vector, self.label, **kwargs) + + @override_animation(Create) + def _create_vec_write_label(self) -> AnimationGroup: + return AnimationGroup( + Create(self.vector), + Write(self.label), + lag_ratio=0 + ) + + @override_animation(Uncreate) + def _uncreate_vec_unwrite_label(self) -> AnimationGroup: + return AnimationGroup( + Uncreate(self.vector), + Unwrite(self.label), + lag_ratio=0 + ) + + class GeometricAddition(Scene): + def construct(self): + title = Text("Now let's take a look at it geometrically") + self.play(Write(title)) + self.wait(2) + self.play(Unwrite(title)) + + plane = NumberPlane() + + sum_point = (2, -1, 0) + + v1 = VectorGroup( + ORIGIN, + (2, 2, 0), + r"\boldsymbol{\vec{v}_1}", + RED, + direction=UP, + plane=plane + ) + + v2 = VectorGroup( + ORIGIN, + (0, -3, 0), + r"\boldsymbol{\vec{v}_2}", + YELLOW, + direction=LEFT, + plane=plane + ) + + v1moved = VectorGroup( + (0, -3, 0), + sum_point, + r"\boldsymbol{\vec{v}_1}", + v1.vector.get_color(), + plane=plane + ) + + v2moved = VectorGroup( + (2, 2, 0), + sum_point, + r"\boldsymbol{\vec{v}_2}", + v2.vector.get_color(), + plane=plane + ) + + sum_vec = VectorGroup( + ORIGIN, + sum_point, + r"\boldsymbol{\vec{v}_1}+\boldsymbol{\vec{v}_2}", + ORANGE, + direction=DOWN, + plane=plane + ) + + self.play(Create(plane), Create(v1)) + self.wait(0.5) + self.play(Create(v2)) + self.wait() + + # animate movement of vectors + self.play( + Succession( + ReplacementTransform(v1.copy(), v1moved), + ReplacementTransform(v2.copy(), v2moved) + ) + ) + self.wait() + # draw sum vector + self.play(Create(sum_vec)) + self.wait() + self.play(*[ + Uncreate(x) + for x in ( + plane, + v1, + v2, + v1moved, + v2moved, + sum_vec + ) + ]) + + + +################ +The Final Result +################ +Putting it all together, we can render the final result. + +.. include:: vector_addition.rst diff --git a/docs/source/adventure/vector_addition.rst b/docs/source/adventure/vector_addition.rst new file mode 100644 index 0000000000..7a4293e4e7 --- /dev/null +++ b/docs/source/adventure/vector_addition.rst @@ -0,0 +1,179 @@ +.. manim:: Adventure + :hide_source: + + class VectorGroup(VGroup): + def __init__( + self, start, end, labelname: str, + vector_color: ParsableManimColor, direction = RIGHT, + plane: NumberPlane | None = None, **kwargs + ) -> None: + if plane is not None: + # if using a plane convert from plane units + # to Munits + start = plane.c2p(*start) + end = plane.c2p(*end) + + self.vector = Arrow( + start, + end, + color=vector_color, + buff=0 + ) + self.label = MathTex(labelname, color=vector_color) + + def label_updater(m: MathTex, d=direction): + m.next_to(self.vector, direction=d, **kwargs) + + self.label.add_updater(label_updater, call_updater=True) + super().__init__(self.vector, self.label, **kwargs) + + @override_animation(Create) + def _create_vec_write_label(self) -> AnimationGroup: + return AnimationGroup( + Create(self.vector), + Write(self.label), + lag_ratio=0 + ) + + @override_animation(Uncreate) + def _uncreate_vec_unwrite_label(self) -> AnimationGroup: + return AnimationGroup( + Uncreate(self.vector), + Unwrite(self.label), + lag_ratio=0 + ) + class Adventure(Scene): + """Goal: Make an example showcasing manim's features""" + + def construct(self) -> None: + intro = Text("Let's try to add two vectors!") + vec_txts = Tex(r"We'll use $\boldsymbol{\vec{v}_1}=(2, 2)$ and $\boldsymbol{\vec{v}_2}=(0, -3)$") + self.play(Create(intro)) + self.wait(1) + self.play(intro.animate.shift(2*UP).set_opacity(0.5), Write(vec_txts)) + self.wait(1) + self.play(Unwrite(intro), Unwrite(vec_txts), run_time=.5) + self.wait(0.2) + + self.show_addition_math() + self.wait(0.2) + self.show_vector_addition() + + outro = Text("Thanks for watching!") + self.play(Create(outro)) + self.wait() + + def show_addition_math(self) -> None: + title = Title("Vector Addition Algebraically") + + v1x, v1y = (2, 2) + v2x, v2y = (0, -3) + math = MathTex(r""" + \begin{bmatrix} %(v1x)d \\ %(v1y)d \end{bmatrix} + +\begin{bmatrix} %(v2x)d \\ %(v2y)d \end{bmatrix} + """ % { + 'v1x': v1x, + 'v2x': v2x, + 'v1y': v1y, + 'v2y': v2y + }).shift(DOWN) + + resultant_vector = r"=\begin{bmatrix} %(x)d \\ %(y)d \end{bmatrix}" % { + 'x': v1x+v2x, + 'y': v1y+v2y + } + math_with_answer = MathTex( + math.get_tex_string()+resultant_vector + ).move_to(math.get_center()) + + self.play(Write(math), FadeIn(title)) + self.wait(2) + self.play( + math.animate.shift(2*UP).set_opacity(0.5), + Write(math_with_answer) + ) + conclusion = Paragraph("As you can see,\nYou add each component individually").to_edge(DOWN) + self.play(Write(conclusion)) + self.wait(2) + self.play(Unwrite(math), Unwrite(math_with_answer), Unwrite(conclusion), Unwrite(title)) + + def show_vector_addition(self) -> None: + title = Text("Now let's take a look at it geometrically") + self.play(Write(title)) + self.wait(2) + self.play(Unwrite(title)) + + plane = NumberPlane() + + sum_point = (2, -1, 0) + + v1 = VectorGroup( + ORIGIN, + (2, 2, 0), + r"\boldsymbol{\vec{v}_1}", + RED, + direction=UP, + plane=plane + ) + + v2 = VectorGroup( + ORIGIN, + (0, -3, 0), + r"\boldsymbol{\vec{v}_2}", + YELLOW, + direction=LEFT, + plane=plane + ) + + v1moved = VectorGroup( + (0, -3, 0), + sum_point, + r"\boldsymbol{\vec{v}_1}", + v1.vector.get_color(), + plane=plane + ) + + v2moved = VectorGroup( + (2, 2, 0), + sum_point, + r"\boldsymbol{\vec{v}_2}", + v2.vector.get_color(), + plane=plane + ) + + sum_vec = VectorGroup( + ORIGIN, + sum_point, + r"\boldsymbol{\vec{v}_1}+\boldsymbol{\vec{v}_2}", + ORANGE, + direction=DOWN, + plane=plane + ) + + self.play(Create(plane), Create(v1)) + self.wait(0.5) + self.play(Create(v2)) + self.wait() + + # animate movement of vectors + self.play( + Succession( + ReplacementTransform(v1.copy(), v1moved), + ReplacementTransform(v2.copy(), v2moved) + ) + ) + self.wait() + # draw sum vector + self.play(Create(sum_vec)) + self.wait() + self.play(*[ + Uncreate(x) + for x in ( + plane, + v1, + v2, + v1moved, + v2moved, + sum_vec + ) + ]) diff --git a/docs/source/conf.py b/docs/source/conf.py index a4a092441d..f8bde72f7b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -51,6 +51,7 @@ "sphinx.ext.inheritance_diagram", "sphinxcontrib.programoutput", "myst_parser", + "sphinx_togglebutton", "sphinx_design", "sphinx_reredirects", ] diff --git a/docs/source/contributing/docs/admonitions.rst b/docs/source/contributing/docs/admonitions.rst index c1b66bc258..8300afc817 100644 --- a/docs/source/contributing/docs/admonitions.rst +++ b/docs/source/contributing/docs/admonitions.rst @@ -85,4 +85,22 @@ Attention .. attention:: A attention +Dropdown +~~~~~~~~~ + +.. code-block:: rest + + .. admonition:: A dropdown + :class: dropdown + + A dropdown + +Make sure you leave a line between ":class:" and the text below, otherwise the dropdown won't render. + +.. admonition:: A dropdown + :class: dropdown + + A dropdown + + You can find further information about Admonitions here: https://pradyunsg.me/furo/reference/admonitions/ diff --git a/docs/source/tutorials_guides.rst b/docs/source/tutorials_guides.rst index 05b318230b..276bb489ab 100644 --- a/docs/source/tutorials_guides.rst +++ b/docs/source/tutorials_guides.rst @@ -7,4 +7,5 @@ Tutorials & Guides tutorials/index guides/index + adventure/index faq/index diff --git a/poetry.lock b/poetry.lock index 576d568faf..82e4824646 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "alabaster" version = "0.7.16" description = "A light, configurable Sphinx theme" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -16,7 +15,6 @@ files = [ name = "anyio" version = "4.8.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" -category = "main" optional = true python-versions = ">=3.9" files = [ @@ -39,7 +37,6 @@ trio = ["trio (>=0.26.1)"] name = "appnope" version = "0.1.4" description = "Disable App Nap on macOS >= 10.9" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -51,7 +48,6 @@ files = [ name = "argon2-cffi" version = "23.1.0" description = "Argon2 for Python" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -72,7 +68,6 @@ typing = ["mypy"] name = "argon2-cffi-bindings" version = "21.2.0" description = "Low-level CFFI bindings for Argon2" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -110,7 +105,6 @@ tests = ["pytest"] name = "arrow" version = "1.3.0" description = "Better dates & times for Python" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -124,13 +118,12 @@ types-python-dateutil = ">=2.8.10" [package.extras] doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] -test = ["dateparser (>=1.0.0,<2.0.0)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (>=3.0.0,<4.0.0)"] +test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] [[package]] name = "asttokens" version = "3.0.0" description = "Annotate AST trees with source code positions" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -146,7 +139,6 @@ test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"] name = "async-lru" version = "2.0.4" description = "Simple LRU cache for asyncio" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -161,7 +153,6 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} name = "attrs" version = "24.3.0" description = "Classes Without Boilerplate" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -181,7 +172,6 @@ tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] name = "audioop-lts" version = "0.2.1" description = "LTS Port of Python audioop" -category = "main" optional = false python-versions = ">=3.13" files = [ @@ -224,7 +214,6 @@ files = [ name = "av" version = "13.1.0" description = "Pythonic bindings for FFmpeg's libraries." -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -277,7 +266,6 @@ files = [ name = "babel" version = "2.16.0" description = "Internationalization utilities" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -292,7 +280,6 @@ dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] name = "beautifulsoup4" version = "4.12.3" description = "Screen-scraping library" -category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -314,7 +301,6 @@ lxml = ["lxml"] name = "bleach" version = "6.2.0" description = "An easy safelist-based HTML-sanitizing tool." -category = "main" optional = true python-versions = ">=3.9" files = [ @@ -333,7 +319,6 @@ css = ["tinycss2 (>=1.1.0,<1.5)"] name = "certifi" version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -345,7 +330,6 @@ files = [ name = "cffi" version = "1.17.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -425,7 +409,6 @@ pycparser = "*" name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -437,7 +420,6 @@ files = [ name = "charset-normalizer" version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -539,7 +521,6 @@ files = [ name = "click" version = "8.1.8" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -554,7 +535,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "cloup" version = "3.0.5" description = "Adds features to Click: option groups, constraints, subcommand sections and help themes." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -569,7 +549,6 @@ click = ">=8.0,<9.0" name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -581,7 +560,6 @@ files = [ name = "comm" version = "0.2.2" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -599,7 +577,6 @@ test = ["pytest"] name = "contourpy" version = "1.3.0" description = "Python library for calculating contours of 2D quadrilateral grids" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -684,7 +661,6 @@ test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist" name = "coverage" version = "7.6.10" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -762,7 +738,6 @@ toml = ["tomli"] name = "cryptography" version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -812,7 +787,6 @@ test-randomorder = ["pytest-randomly"] name = "cycler" version = "0.12.1" description = "Composable style cycles" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -828,7 +802,6 @@ tests = ["pytest", "pytest-cov", "pytest-xdist"] name = "cython" version = "3.0.11" description = "The Cython compiler for writing C extensions in the Python language." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ @@ -904,7 +877,6 @@ files = [ name = "dearpygui" version = "2.0.0" description = "DearPyGui: A simple Python GUI Toolkit" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -936,7 +908,6 @@ files = [ name = "debugpy" version = "1.8.12" description = "An implementation of the Debug Adapter Protocol for Python" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -972,7 +943,6 @@ files = [ name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -984,7 +954,6 @@ files = [ name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" -category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -996,7 +965,6 @@ files = [ name = "deprecated" version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ @@ -1014,7 +982,6 @@ dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", " name = "distlib" version = "0.3.9" description = "Distribution utilities" -category = "dev" optional = false python-versions = "*" files = [ @@ -1026,7 +993,6 @@ files = [ name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1038,7 +1004,6 @@ files = [ name = "exceptiongroup" version = "1.2.2" description = "Backport of PEP 654 (exception groups)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1053,7 +1018,6 @@ test = ["pytest (>=6)"] name = "execnet" version = "2.1.1" description = "execnet: rapid multi-Python deployment" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1068,7 +1032,6 @@ testing = ["hatch", "pre-commit", "pytest", "tox"] name = "executing" version = "2.1.0" description = "Get the currently executing AST node of a frame, and other information" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1083,7 +1046,6 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth name = "fastjsonschema" version = "2.21.1" description = "Fastest Python implementation of JSON schema" -category = "main" optional = true python-versions = "*" files = [ @@ -1098,7 +1060,6 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc name = "filelock" version = "3.16.1" description = "A platform independent file lock." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1115,7 +1076,6 @@ typing = ["typing-extensions (>=4.12.2)"] name = "fonttools" version = "4.55.3" description = "Tools to manipulate font files" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1189,7 +1149,6 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "fqdn" version = "1.4.0" description = "Validate fully-qualified domain names compliant to RFC 1035 and the preferred form in RFC 3686 s. 2." -category = "main" optional = true python-versions = "*" files = [ @@ -1201,7 +1160,6 @@ files = [ name = "furo" version = "2023.9.10" description = "A clean customisable Sphinx documentation theme." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1219,7 +1177,6 @@ sphinx-basic-ng = "*" name = "gitdb" version = "4.0.12" description = "Git Object Database" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1234,7 +1191,6 @@ smmap = ">=3.0.1,<6" name = "gitpython" version = "3.1.44" description = "GitPython is a Python library used to interact with Git repositories" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1253,7 +1209,6 @@ test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", name = "glcontext" version = "3.0.0" description = "Portable Headless OpenGL Context" -category = "main" optional = false python-versions = "*" files = [ @@ -1327,7 +1282,6 @@ files = [ name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1339,7 +1293,6 @@ files = [ name = "httpcore" version = "1.0.7" description = "A minimal low-level HTTP client." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1354,14 +1307,13 @@ h11 = ">=0.13,<0.15" [package.extras] asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" version = "0.28.1" description = "The next generation HTTP client." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1372,21 +1324,20 @@ files = [ [package.dependencies] anyio = "*" certifi = "*" -httpcore = ">=1.0.0,<2.0.0" +httpcore = "==1.*" idna = "*" [package.extras] brotli = ["brotli", "brotlicffi"] -cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "identify" version = "2.6.5" description = "File identification library for Python" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -1401,7 +1352,6 @@ license = ["ukkonen"] name = "idna" version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1416,7 +1366,6 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2 name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1428,7 +1377,6 @@ files = [ name = "importlib-metadata" version = "8.5.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1452,7 +1400,6 @@ type = ["pytest-mypy"] name = "importlib-resources" version = "6.5.2" description = "Read resources from Python packages" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -1475,7 +1422,6 @@ type = ["pytest-mypy"] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1487,7 +1433,6 @@ files = [ name = "ipykernel" version = "6.29.5" description = "IPython Kernel for Jupyter" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1501,7 +1446,7 @@ comm = ">=0.1.1" debugpy = ">=1.6.5" ipython = ">=7.23.1" jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" @@ -1521,7 +1466,6 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio name = "ipython" version = "8.18.1" description = "IPython: Productive Interactive Computing" -category = "main" optional = true python-versions = ">=3.9" files = [ @@ -1559,7 +1503,6 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pa name = "isoduration" version = "20.11.0" description = "Operations with ISO 8601 durations" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1574,7 +1517,6 @@ arrow = ">=0.15.0" name = "isort" version = "5.13.2" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -1589,7 +1531,6 @@ colors = ["colorama (>=0.4.6)"] name = "isosurfaces" version = "0.1.2" description = "Construct isolines/isosurfaces over a 2D/3D scalar field defined by a function (not a uniform grid)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1604,7 +1545,6 @@ numpy = "*" name = "jedi" version = "0.19.2" description = "An autocompletion tool for Python that can be used for text editors." -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -1624,7 +1564,6 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"] name = "jinja2" version = "3.1.5" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1642,7 +1581,6 @@ i18n = ["Babel (>=2.7)"] name = "json5" version = "0.10.0" description = "A Python implementation of the JSON5 data format." -category = "main" optional = true python-versions = ">=3.8.0" files = [ @@ -1657,7 +1595,6 @@ dev = ["build (==1.2.2.post1)", "coverage (==7.5.3)", "mypy (==1.13.0)", "pip (= name = "jsonpointer" version = "3.0.0" description = "Identify specific nodes in a JSON document (RFC 6901)" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1669,7 +1606,6 @@ files = [ name = "jsonschema" version = "4.23.0" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1699,7 +1635,6 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jsonschema-specifications" version = "2024.10.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -category = "main" optional = true python-versions = ">=3.9" files = [ @@ -1714,7 +1649,6 @@ referencing = ">=0.31.0" name = "jupyter-client" version = "8.6.3" description = "Jupyter protocol implementation and client libraries" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1724,7 +1658,7 @@ files = [ [package.dependencies] importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" tornado = ">=6.2" @@ -1738,7 +1672,6 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt name = "jupyter-core" version = "5.7.2" description = "Jupyter core package. A base package on which Jupyter projects rely." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1759,7 +1692,6 @@ test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout" name = "jupyter-events" version = "0.11.0" description = "Jupyter Event System library" -category = "main" optional = true python-versions = ">=3.9" files = [ @@ -1785,7 +1717,6 @@ test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "p name = "jupyter-lsp" version = "2.2.5" description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1801,7 +1732,6 @@ jupyter-server = ">=1.1.2" name = "jupyter-server" version = "2.15.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." -category = "main" optional = true python-versions = ">=3.9" files = [ @@ -1814,7 +1744,7 @@ anyio = ">=3.1.0" argon2-cffi = ">=21.1" jinja2 = ">=3.0.3" jupyter-client = ">=7.4.4" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" jupyter-events = ">=0.11.0" jupyter-server-terminals = ">=0.4.4" nbconvert = ">=6.4.4" @@ -1838,7 +1768,6 @@ test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0,<9)", "pytest-console name = "jupyter-server-terminals" version = "0.5.3" description = "A Jupyter Server Extension Providing Terminals." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1858,7 +1787,6 @@ test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (> name = "jupyterlab" version = "4.3.4" description = "JupyterLab computational environment" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1894,7 +1822,6 @@ upgrade-extension = ["copier (>=9,<10)", "jinja2-time (<0.3)", "pydantic (<3.0)" name = "jupyterlab-pygments" version = "0.3.0" description = "Pygments theme using JupyterLab CSS variables" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1906,7 +1833,6 @@ files = [ name = "jupyterlab-server" version = "2.27.3" description = "A set of server components for JupyterLab and JupyterLab like applications." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1933,7 +1859,6 @@ test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-v name = "kiwisolver" version = "1.4.7" description = "A fast implementation of the Cassowary constraint solver" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2057,7 +1982,6 @@ files = [ name = "manimpango" version = "0.6.0" description = "Bindings for Pango for using with Manim." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2088,7 +2012,6 @@ files = [ name = "mapbox-earcut" version = "1.0.3" description = "Python bindings for the mapbox earcut C++ polygon triangulation library" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -2140,7 +2063,6 @@ numpy = "*" name = "markdown-it-py" version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2165,7 +2087,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -2236,7 +2157,6 @@ files = [ name = "matplotlib" version = "3.9.4" description = "Python plotting package" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -2302,7 +2222,6 @@ dev = ["meson-python (>=0.13.1,<0.17.0)", "numpy (>=1.25)", "pybind11 (>=2.6,!=2 name = "matplotlib-inline" version = "0.1.7" description = "Inline Matplotlib backend for Jupyter" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -2317,7 +2236,6 @@ traitlets = "*" name = "mdit-py-plugins" version = "0.4.2" description = "Collection of plugins for markdown-it-py" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2337,7 +2255,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2349,7 +2266,6 @@ files = [ name = "mistune" version = "3.1.0" description = "A sane and fast Markdown parser with useful plugins and renderers" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -2364,7 +2280,6 @@ typing-extensions = {version = "*", markers = "python_version < \"3.11\""} name = "moderngl" version = "5.12.0" description = "ModernGL: High performance rendering for Python 3" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2429,7 +2344,6 @@ headless = ["glcontext (>=3.0.0)"] name = "moderngl-window" version = "3.1.1" description = "A cross platform helper library for ModernGL making window creation and resource loading simple" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -2465,7 +2379,6 @@ trimesh = ["trimesh (>=3.2.6)"] name = "myst-parser" version = "2.0.0" description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2492,7 +2405,6 @@ testing-docutils = ["pygments", "pytest (>=7,<8)", "pytest-param-files (>=0.3.4, name = "nbclient" version = "0.10.2" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -category = "main" optional = true python-versions = ">=3.9.0" files = [ @@ -2502,7 +2414,7 @@ files = [ [package.dependencies] jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" nbformat = ">=5.1" traitlets = ">=5.4" @@ -2515,7 +2427,6 @@ test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>= name = "nbconvert" version = "7.16.5" description = "Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script. nbconvert can be used both as a Python library (`import nbconvert`) or as a command line tool (invoked as `jupyter nbconvert ...`)." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -2553,7 +2464,6 @@ webpdf = ["playwright"] name = "nbformat" version = "5.10.4" description = "The Jupyter Notebook format" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -2564,7 +2474,7 @@ files = [ [package.dependencies] fastjsonschema = ">=2.15" jsonschema = ">=2.6" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" traitlets = ">=5.1" [package.extras] @@ -2575,7 +2485,6 @@ test = ["pep440", "pre-commit", "pytest", "testpath"] name = "nest-asyncio" version = "1.6.0" description = "Patch asyncio to allow nested event loops" -category = "main" optional = true python-versions = ">=3.5" files = [ @@ -2587,7 +2496,6 @@ files = [ name = "networkx" version = "3.2.1" description = "Python package for creating and manipulating graphs and networks" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -2606,7 +2514,6 @@ test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] name = "nodeenv" version = "1.9.1" description = "Node.js virtual environment builder" -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -2618,7 +2525,6 @@ files = [ name = "notebook" version = "7.3.2" description = "Jupyter Notebook - A web-based notebook environment for interactive computing" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -2642,7 +2548,6 @@ test = ["importlib-resources (>=5.0)", "ipykernel", "jupyter-server[test] (>=2.4 name = "notebook-shim" version = "0.2.4" description = "A shim layer for notebook traits and config" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -2660,7 +2565,6 @@ test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync" name = "numpy" version = "2.0.2" description = "Fundamental package for array computing in Python" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -2715,7 +2619,6 @@ files = [ name = "numpy" version = "2.2.2" description = "Fundamental package for array computing in Python" -category = "main" optional = false python-versions = ">=3.10" files = [ @@ -2780,7 +2683,6 @@ files = [ name = "overrides" version = "7.7.0" description = "A decorator to automatically detect mismatch when overriding a method." -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -2792,7 +2694,6 @@ files = [ name = "packaging" version = "24.2" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2804,7 +2705,6 @@ files = [ name = "pandocfilters" version = "1.5.1" description = "Utilities for writing pandoc filters in python" -category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2816,7 +2716,6 @@ files = [ name = "parso" version = "0.8.4" description = "A Python Parser" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -2832,7 +2731,6 @@ testing = ["docopt", "pytest"] name = "pexpect" version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." -category = "main" optional = true python-versions = "*" files = [ @@ -2847,7 +2745,6 @@ ptyprocess = ">=0.5" name = "pillow" version = "11.1.0" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -2936,7 +2833,6 @@ xmp = ["defusedxml"] name = "platformdirs" version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2953,7 +2849,6 @@ type = ["mypy (>=1.11.2)"] name = "pluggy" version = "1.5.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2969,7 +2864,6 @@ testing = ["pytest", "pytest-benchmark"] name = "pre-commit" version = "3.8.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -2988,7 +2882,6 @@ virtualenv = ">=20.10.0" name = "prometheus-client" version = "0.21.1" description = "Python client for the Prometheus monitoring system." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -3001,14 +2894,13 @@ twisted = ["twisted"] [[package]] name = "prompt-toolkit" -version = "3.0.48" +version = "3.0.49" description = "Library for building powerful interactive command lines in Python" -category = "main" optional = true -python-versions = ">=3.7.0" +python-versions = ">=3.8.0" files = [ - {file = "prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e"}, - {file = "prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90"}, + {file = "prompt_toolkit-3.0.49-py3-none-any.whl", hash = "sha256:03b25a442496d1aeabcb4b8b8e94563ac6a8eff56467837367206a733c61c2de"}, + {file = "prompt_toolkit-3.0.49.tar.gz", hash = "sha256:372cfcbff483cd5fac6f7870d21face30f1e2f217c6906721616fb1be778774d"}, ] [package.dependencies] @@ -3018,7 +2910,6 @@ wcwidth = "*" name = "psutil" version = "5.9.8" description = "Cross-platform lib for process and system monitoring in Python." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -3047,7 +2938,6 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "psutil-wheels" version = "5.8.0" description = "Cross-platform lib for process and system monitoring in Python." -category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3073,7 +2963,6 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "unittest2", "wmi"] name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" -category = "main" optional = true python-versions = "*" files = [ @@ -3085,7 +2974,6 @@ files = [ name = "pure-eval" version = "0.2.3" description = "Safely evaluate AST nodes without side effects" -category = "main" optional = true python-versions = "*" files = [ @@ -3100,7 +2988,6 @@ tests = ["pytest"] name = "py" version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -3112,7 +2999,6 @@ files = [ name = "pycairo" version = "1.27.0" description = "Python interface for cairo" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -3133,7 +3019,6 @@ files = [ name = "pycparser" version = "2.22" description = "C parser in Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3145,7 +3030,6 @@ files = [ name = "pydub" version = "0.25.1" description = "Manipulate audio with an simple and easy high level interface" -category = "main" optional = false python-versions = "*" files = [ @@ -3157,7 +3041,6 @@ files = [ name = "pygithub" version = "2.5.0" description = "Use the full Github API v3" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3175,21 +3058,19 @@ urllib3 = ">=1.26.0" [[package]] name = "pyglet" -version = "2.1.0" +version = "2.1.1" description = "pyglet is a cross-platform games and multimedia package." -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "pyglet-2.1.0-py3-none-any.whl", hash = "sha256:ed2ff5b9eeacf845d019f9768b01c811ebe167372dcb699146e59da2c4666e0b"}, - {file = "pyglet-2.1.0.tar.gz", hash = "sha256:50c5a82203f1ffd56990d225315035b37aacba7510f8f65c4b10a7301be788c8"}, + {file = "pyglet-2.1.1-py3-none-any.whl", hash = "sha256:30562bfe9971a9ebeb6bb826f2c0d1649dd3d41bc8109ecc103425621f54c802"}, + {file = "pyglet-2.1.1.tar.gz", hash = "sha256:47f49890a00e9fefc4d0ea74dc5b9d6b9be1c5455bb5746b2df118012cfa3124"}, ] [[package]] name = "pyglm" version = "2.7.3" description = "OpenGL Mathematics library for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -3280,7 +3161,6 @@ files = [ name = "pygments" version = "2.19.1" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3295,7 +3175,6 @@ windows-terminal = ["colorama (>=0.4.6)"] name = "pyjwt" version = "2.10.1" description = "JSON Web Token implementation in Python" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -3316,7 +3195,6 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "pynacl" version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3343,7 +3221,6 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] name = "pyobjc-core" version = "11.0" description = "Python<->ObjC Interoperability Module" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3360,7 +3237,6 @@ files = [ name = "pyobjc-framework-cocoa" version = "11.0" description = "Wrappers for the Cocoa frameworks on macOS" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -3380,7 +3256,6 @@ pyobjc-core = ">=11.0" name = "pyparsing" version = "3.2.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -3395,7 +3270,6 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pytest" version = "8.3.4" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3418,7 +3292,6 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3437,7 +3310,6 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-forked" version = "1.6.0" description = "run tests in isolated forked subprocesses" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3453,7 +3325,6 @@ pytest = ">=3.10" name = "pytest-xdist" version = "2.5.0" description = "pytest xdist plugin for distributed testing and loop-on-failing modes" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3475,7 +3346,6 @@ testing = ["filelock"] name = "python-dateutil" version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -3490,7 +3360,6 @@ six = ">=1.5" name = "python-json-logger" version = "3.2.1" description = "JSON Log Formatter for the Python Logging Package" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -3508,7 +3377,6 @@ dev = ["backports.zoneinfo", "black", "build", "freezegun", "mdx_truly_sane_list name = "pywin32" version = "308" description = "Python for Window Extensions" -category = "main" optional = true python-versions = "*" files = [ @@ -3536,7 +3404,6 @@ files = [ name = "pywinpty" version = "2.0.14" description = "Pseudo terminal support for Windows from Python." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -3552,7 +3419,6 @@ files = [ name = "pyyaml" version = "6.0.2" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3615,7 +3481,6 @@ files = [ name = "pyzmq" version = "26.2.0" description = "Python bindings for 0MQ" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -3737,7 +3602,6 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} name = "referencing" version = "0.36.1" description = "JSON Referencing + Python" -category = "main" optional = true python-versions = ">=3.9" files = [ @@ -3754,7 +3618,6 @@ typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.13\""} name = "requests" version = "2.32.3" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3776,7 +3639,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "rfc3339-validator" version = "0.1.4" description = "A pure python RFC3339 validator" -category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -3791,7 +3653,6 @@ six = "*" name = "rfc3986-validator" version = "0.1.1" description = "Pure python rfc3986 validator" -category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -3803,7 +3664,6 @@ files = [ name = "rich" version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "main" optional = false python-versions = ">=3.8.0" files = [ @@ -3823,7 +3683,6 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] name = "rpds-py" version = "0.22.3" description = "Python bindings to Rust's persistent data structures (rpds)" -category = "main" optional = true python-versions = ">=3.9" files = [ @@ -3936,7 +3795,6 @@ files = [ name = "ruff" version = "0.9.2" description = "An extremely fast Python linter and code formatter, written in Rust." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3964,7 +3822,6 @@ files = [ name = "scipy" version = "1.13.1" description = "Fundamental algorithms for scientific computing in Python" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -4007,7 +3864,6 @@ test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "po name = "scipy" version = "1.15.1" description = "Fundamental algorithms for scientific computing in Python" -category = "main" optional = false python-versions = ">=3.10" files = [ @@ -4065,7 +3921,6 @@ test = ["Cython", "array-api-strict (>=2.0,<2.1.1)", "asv", "gmpy2", "hypothesis name = "screeninfo" version = "0.7" description = "Fetch location and size of physical screens." -category = "main" optional = false python-versions = "*" files = [ @@ -4080,7 +3935,6 @@ pyobjc-framework-Cocoa = {version = "*", markers = "sys_platform == \"darwin\""} name = "send2trash" version = "1.8.3" description = "Send file to trash natively under Mac OS X, Windows and Linux" -category = "main" optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -4097,8 +3951,7 @@ win32 = ["pywin32"] name = "setuptools" version = "75.8.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" -optional = true +optional = false python-versions = ">=3.9" files = [ {file = "setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3"}, @@ -4112,13 +3965,12 @@ cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.14.0,<1.15.0)", "pytest-mypy"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"] [[package]] name = "six" version = "1.17.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -4130,7 +3982,6 @@ files = [ name = "skia-pathops" version = "0.8.0.post2" description = "Python access to operations on paths using the Skia library" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4189,7 +4040,6 @@ testing = ["coverage", "pytest", "pytest-randomly", "pytest-xdist"] name = "smmap" version = "5.0.2" description = "A pure Python implementation of a sliding window memory map manager" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4201,7 +4051,6 @@ files = [ name = "sniffio" version = "1.3.1" description = "Sniff out which async library your code is running under" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -4213,7 +4062,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" optional = false python-versions = "*" files = [ @@ -4225,7 +4073,6 @@ files = [ name = "soupsieve" version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4237,7 +4084,6 @@ files = [ name = "sphinx" version = "7.4.7" description = "Python documentation generator" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -4274,7 +4120,6 @@ test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools name = "sphinx-basic-ng" version = "1.0.0b2" description = "A modern skeleton for Sphinx themes." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4292,7 +4137,6 @@ docs = ["furo", "ipython", "myst-parser", "sphinx-copybutton", "sphinx-inline-ta name = "sphinx-copybutton" version = "0.5.2" description = "Add a copy button to each of your code cells." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4311,7 +4155,6 @@ rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] name = "sphinx-design" version = "0.6.1" description = "A sphinx extension for designing beautiful, view size responsive web components." -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -4337,7 +4180,6 @@ theme-sbt = ["sphinx-book-theme (>=1.1,<2.0)"] name = "sphinx-reredirects" version = "0.1.5" description = "Handles redirects for moved pages in Sphinx documentation projects" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -4348,11 +4190,30 @@ files = [ [package.dependencies] sphinx = ">=7.1" +[[package]] +name = "sphinx-togglebutton" +version = "0.3.2" +description = "Toggle page content and collapse admonitions in Sphinx." +optional = false +python-versions = "*" +files = [ + {file = "sphinx-togglebutton-0.3.2.tar.gz", hash = "sha256:ab0c8b366427b01e4c89802d5d078472c427fa6e9d12d521c34fa0442559dc7a"}, + {file = "sphinx_togglebutton-0.3.2-py3-none-any.whl", hash = "sha256:9647ba7874b7d1e2d43413d8497153a85edc6ac95a3fea9a75ef9c1e08aaae2b"}, +] + +[package.dependencies] +docutils = "*" +setuptools = "*" +sphinx = "*" +wheel = "*" + +[package.extras] +sphinx = ["matplotlib", "myst-nb", "numpy", "sphinx-book-theme", "sphinx-design", "sphinx-examples"] + [[package]] name = "sphinxcontrib-applehelp" version = "2.0.0" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -4369,7 +4230,6 @@ test = ["pytest"] name = "sphinxcontrib-devhelp" version = "2.0.0" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -4386,7 +4246,6 @@ test = ["pytest"] name = "sphinxcontrib-htmlhelp" version = "2.1.0" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -4403,7 +4262,6 @@ test = ["html5lib", "pytest"] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -4418,7 +4276,6 @@ test = ["flake8", "mypy", "pytest"] name = "sphinxcontrib-programoutput" version = "0.17" description = "Sphinx extension to include program output" -category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -4433,7 +4290,6 @@ Sphinx = ">=1.7.0" name = "sphinxcontrib-qthelp" version = "2.0.0" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -4450,7 +4306,6 @@ test = ["defusedxml (>=0.7.1)", "pytest"] name = "sphinxcontrib-serializinghtml" version = "2.0.0" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -4467,7 +4322,6 @@ test = ["pytest"] name = "sphinxext-opengraph" version = "0.9.1" description = "Sphinx Extension to enable OGP support" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4482,7 +4336,6 @@ sphinx = ">=4.0" name = "srt" version = "3.5.3" description = "A tiny library for parsing, modifying, and composing SRT files." -category = "main" optional = false python-versions = ">=2.7" files = [ @@ -4493,7 +4346,6 @@ files = [ name = "stack-data" version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" -category = "main" optional = true python-versions = "*" files = [ @@ -4513,7 +4365,6 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "svgelements" version = "1.9.6" description = "Svg Elements Parsing" -category = "main" optional = false python-versions = "*" files = [ @@ -4525,7 +4376,6 @@ files = [ name = "terminado" version = "0.18.1" description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -4547,7 +4397,6 @@ typing = ["mypy (>=1.6,<2.0)", "traitlets (>=5.11.1)"] name = "tinycss2" version = "1.4.0" description = "A tiny CSS parser" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -4566,7 +4415,6 @@ test = ["pytest", "ruff"] name = "tomli" version = "2.2.1" description = "A lil' TOML parser" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4608,7 +4456,6 @@ files = [ name = "tornado" version = "6.4.2" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -4629,7 +4476,6 @@ files = [ name = "tqdm" version = "4.67.1" description = "Fast, Extensible Progress Meter" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4651,7 +4497,6 @@ telegram = ["requests"] name = "traitlets" version = "5.14.3" description = "Traitlets Python configuration system" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -4667,7 +4512,6 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, name = "types-decorator" version = "0.1.7" description = "Typing stubs for decorator" -category = "dev" optional = false python-versions = "*" files = [ @@ -4679,7 +4523,6 @@ files = [ name = "types-docutils" version = "0.21.0.20241128" description = "Typing stubs for docutils" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4691,7 +4534,6 @@ files = [ name = "types-pillow" version = "10.2.0.20240822" description = "Typing stubs for Pillow" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4703,7 +4545,6 @@ files = [ name = "types-pygments" version = "2.19.0.20250107" description = "Typing stubs for Pygments" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4719,7 +4560,6 @@ types-setuptools = "*" name = "types-python-dateutil" version = "2.9.0.20241206" description = "Typing stubs for python-dateutil" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -4731,7 +4571,6 @@ files = [ name = "types-setuptools" version = "75.8.0.20250110" description = "Typing stubs for setuptools" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4743,7 +4582,6 @@ files = [ name = "typing-extensions" version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4755,7 +4593,6 @@ files = [ name = "uri-template" version = "1.3.0" description = "RFC 6570 URI Template Processor" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -4770,7 +4607,6 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake name = "urllib3" version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -4788,7 +4624,6 @@ zstd = ["zstandard (>=0.18.0)"] name = "virtualenv" version = "20.29.1" description = "Virtual Python Environment builder" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4809,7 +4644,6 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "watchdog" version = "6.0.0" description = "Filesystem events monitoring" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -4852,7 +4686,6 @@ watchmedo = ["PyYAML (>=3.10)"] name = "wcwidth" version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" -category = "main" optional = true python-versions = "*" files = [ @@ -4864,7 +4697,6 @@ files = [ name = "webcolors" version = "24.11.1" description = "A library for working with the color formats defined by HTML and CSS." -category = "main" optional = true python-versions = ">=3.9" files = [ @@ -4876,7 +4708,6 @@ files = [ name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" -category = "main" optional = true python-versions = "*" files = [ @@ -4888,7 +4719,6 @@ files = [ name = "websocket-client" version = "1.8.0" description = "WebSocket client for Python with low level API options" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -4901,11 +4731,24 @@ docs = ["Sphinx (>=6.0)", "myst-parser (>=2.0.0)", "sphinx-rtd-theme (>=1.1.0)"] optional = ["python-socks", "wsaccel"] test = ["websockets"] +[[package]] +name = "wheel" +version = "0.45.1" +description = "A built-package format for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248"}, + {file = "wheel-0.45.1.tar.gz", hash = "sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729"}, +] + +[package.extras] +test = ["pytest (>=6.0.0)", "setuptools (>=65)"] + [[package]] name = "wrapt" version = "1.17.2" description = "Module for decorators, wrappers and monkey patching." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4994,7 +4837,6 @@ files = [ name = "zipp" version = "3.21.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -5017,4 +4859,4 @@ jupyterlab = ["jupyterlab", "notebook"] [metadata] lock-version = "2.0" python-versions = ">=3.9" -content-hash = "8be7f23224cbc3e1f01562c0a17e83deb11c7146862e332cd0d8f0dff54becde" +content-hash = "6e501589f64dd263e44daa5c72e251ad8abc0cf1ce0bea8cbf667a316bb0d21f" diff --git a/pyproject.toml b/pyproject.toml index 9b2360f236..096c24d767 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,6 +92,7 @@ Sphinx = "^7.2.6" sphinx-copybutton = "^0.5.2" sphinxcontrib-programoutput = "^0.17" sphinxext-opengraph = "^0.9.1" +sphinx-togglebutton = "^0.3.2" types-decorator = "^0.1.7" types-Pillow = "^10.1.0.2" types-Pygments = "^2.17.0.0"