# Auto-generated by `python -m gen` — do not edit manually.

from typing import TYPE_CHECKING, Generic, Literal

import bpy

from ...builder import BaseNode, SocketAccessor, Socket

from ...types import (
    InputBoolean,
    InputBundle,
    InputClosure,
    InputCollection,
    InputColor,
    InputFloat,
    InputFont,
    InputGeometry,
    InputImage,
    InputInteger,
    InputMaterial,
    InputMatrix,
    InputMenu,
    InputObject,
    InputRotation,
    InputSound,
    InputString,
    InputVector,
    InputAny,
)

from ...builder.socket import (
    BooleanSocket,
    BundleSocket,
    ClosureSocket,
    CollectionSocket,
    ColorSocket,
    FloatSocket,
    FontSocket,
    GeometrySocket,
    ImageSocket,
    IntegerSocket,
    MaterialSocket,
    MatrixSocket,
    MenuSocket,
    ObjectSocket,
    RotationSocket,
    SoundSocket,
    StringSocket,
    VectorSocket,
    StringSocketList,
    _T,
    _S,
)

from ...types import _AttributeDomains

from ...builder.items import _infer_value_type

from .._mixins import _FieldToListMixin

from .._mixins import _FormatStringMixin


class AccumulateField(BaseNode, Generic[_T]):
    """
    Add the values of an evaluated field together and output the running total for each element

    Parameters
    ----------
    value : InputFloat
        Value
    group_index : InputInteger
        Group ID

    Inputs
    ------
    i.value : FloatSocket
        Value
    i.group_index : IntegerSocket
        Group ID

    Outputs
    -------
    o.leading : FloatSocket
        Leading
    o.trailing : FloatSocket
        Trailing
    o.total : FloatSocket
        Total
    """

    _bl_idname = "GeometryNodeAccumulateField"
    node: bpy.types.GeometryNodeAccumulateField

    class _Inputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""
        group_index: IntegerSocket
        """Group ID"""

    class _Outputs(SocketAccessor, Generic[_S]):
        leading: _S
        """Leading"""
        trailing: _S
        """Trailing"""
        total: _S
        """Total"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        value: InputAny = 1.0,
        group_index: InputInteger = 0,
        *,
        data_type: Literal["FLOAT", "INT", "FLOAT_VECTOR", "TRANSFORM"] = "FLOAT",
        domain: Literal[
            "POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"
        ] = "POINT",
    ):
        super().__init__()
        key_args = {"Value": value, "Group Index": group_index}
        self.data_type = data_type
        self.domain = domain
        self._establish_links(**key_args)

    @classmethod
    def face_corner(
        cls, value: InputFloat = 1.0, group_index: InputInteger = 0
    ) -> "AccumulateField[FloatSocket]":
        """Create Accumulate Field with operation 'Face Corner'. Attribute on mesh face corner"""
        return AccumulateField(domain="CORNER", value=value, group_index=group_index)

    @property
    def data_type(self) -> Literal["FLOAT", "INT", "FLOAT_VECTOR", "TRANSFORM"]:
        return self.node.data_type

    @data_type.setter
    def data_type(self, value: Literal["FLOAT", "INT", "FLOAT_VECTOR", "TRANSFORM"]):
        self.node.data_type = value

    @property
    def domain(
        self,
    ) -> Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"]:
        return self.node.domain

    @domain.setter
    def domain(
        self,
        value: Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"],
    ):
        self.node.domain = value

    class _AccumulateFieldDomainFactory:
        def __init__(self, domain: _AttributeDomains):
            self._domain = domain

        def float(
            self, value: InputFloat = None, group_index: InputInteger = 0
        ) -> "AccumulateField[FloatSocket]":
            """Create 'AccumulateField' on this domain with 'FLOAT' data type."""
            return AccumulateField(
                value, group_index, domain=self._domain, data_type="FLOAT"
            )

        def integer(
            self, value: InputInteger = None, group_index: InputInteger = 0
        ) -> "AccumulateField[IntegerSocket]":
            """Create 'AccumulateField' on this domain with 'INT' data type."""
            return AccumulateField(
                value, group_index, domain=self._domain, data_type="INT"
            )

        def vector(
            self, value: InputVector = None, group_index: InputInteger = 0
        ) -> "AccumulateField[VectorSocket]":
            """Create 'AccumulateField' on this domain with 'FLOAT_VECTOR' data type."""
            return AccumulateField(
                value, group_index, domain=self._domain, data_type="FLOAT_VECTOR"
            )

        def transform(
            self, value: InputMatrix = None, group_index: InputInteger = 0
        ) -> "AccumulateField[MatrixSocket]":
            """Create 'AccumulateField' on this domain with 'TRANSFORM' data type."""
            return AccumulateField(
                value, group_index, domain=self._domain, data_type="TRANSFORM"
            )

    point = _AccumulateFieldDomainFactory("POINT")
    edge = _AccumulateFieldDomainFactory("EDGE")
    face = _AccumulateFieldDomainFactory("FACE")
    corner = _AccumulateFieldDomainFactory("CORNER")
    spline = _AccumulateFieldDomainFactory("CURVE")
    instance = _AccumulateFieldDomainFactory("INSTANCE")
    layer = _AccumulateFieldDomainFactory("LAYER")


class AlignRotationToVector(BaseNode):
    """
    Orient a rotation along the given direction

    Parameters
    ----------
    rotation : InputRotation
        Rotation
    factor : InputFloat
        Factor
    vector : InputVector
        Vector

    Inputs
    ------
    i.rotation : RotationSocket
        Rotation
    i.factor : FloatSocket
        Factor
    i.vector : VectorSocket
        Vector

    Outputs
    -------
    o.rotation : RotationSocket
        Rotation
    """

    _bl_idname = "FunctionNodeAlignRotationToVector"
    node: bpy.types.FunctionNodeAlignRotationToVector

    class _Inputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""
        factor: FloatSocket
        """Factor"""
        vector: VectorSocket
        """Vector"""

    class _Outputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        rotation: InputRotation = None,
        factor: InputFloat = 1.0,
        vector: InputVector = None,
        *,
        axis: Literal["X", "Y", "Z"] = "Z",
        pivot_axis: Literal["AUTO", "X", "Y", "Z"] = "AUTO",
    ):
        super().__init__()
        key_args = {"Rotation": rotation, "Factor": factor, "Vector": vector}
        self.axis = axis
        self.pivot_axis = pivot_axis
        self._establish_links(**key_args)

    @property
    def axis(self) -> Literal["X", "Y", "Z"]:
        return self.node.axis

    @axis.setter
    def axis(self, value: Literal["X", "Y", "Z"]):
        self.node.axis = value

    @property
    def pivot_axis(self) -> Literal["AUTO", "X", "Y", "Z"]:
        return self.node.pivot_axis

    @pivot_axis.setter
    def pivot_axis(self, value: Literal["AUTO", "X", "Y", "Z"]):
        self.node.pivot_axis = value


class AxesToRotation(BaseNode):
    """
    Create a rotation from a primary and (ideally orthogonal) secondary axis

    Parameters
    ----------
    primary_axis : InputVector
        Primary Axis
    secondary_axis : InputVector
        Secondary Axis

    Inputs
    ------
    i.primary_axis : VectorSocket
        Primary Axis
    i.secondary_axis : VectorSocket
        Secondary Axis

    Outputs
    -------
    o.rotation : RotationSocket
        Rotation
    """

    _bl_idname = "FunctionNodeAxesToRotation"
    node: bpy.types.FunctionNodeAxesToRotation

    class _Inputs(SocketAccessor):
        primary_axis: VectorSocket
        """Primary Axis"""
        secondary_axis: VectorSocket
        """Secondary Axis"""

    class _Outputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        primary_axis: InputVector = None,
        secondary_axis: InputVector = None,
        *,
        primary: Literal["X", "Y", "Z"] = "Z",
        secondary: Literal["X", "Y", "Z"] = "X",
    ):
        super().__init__()
        key_args = {"Primary Axis": primary_axis, "Secondary Axis": secondary_axis}
        self.primary = primary
        self.secondary = secondary
        self._establish_links(**key_args)

    @property
    def primary(self) -> Literal["X", "Y", "Z"]:
        return self.node.primary_axis

    @primary.setter
    def primary(self, value: Literal["X", "Y", "Z"]):
        self.node.primary_axis = value

    @property
    def secondary(self) -> Literal["X", "Y", "Z"]:
        return self.node.secondary_axis

    @secondary.setter
    def secondary(self, value: Literal["X", "Y", "Z"]):
        self.node.secondary_axis = value


class AxisAngleToRotation(BaseNode):
    """
    Build a rotation from an axis and a rotation around that axis

    Parameters
    ----------
    axis : InputVector
        Axis
    angle : InputFloat
        Angle

    Inputs
    ------
    i.axis : VectorSocket
        Axis
    i.angle : FloatSocket
        Angle

    Outputs
    -------
    o.rotation : RotationSocket
        Rotation
    """

    _bl_idname = "FunctionNodeAxisAngleToRotation"
    node: bpy.types.FunctionNodeAxisAngleToRotation

    class _Inputs(SocketAccessor):
        axis: VectorSocket
        """Axis"""
        angle: FloatSocket
        """Angle"""

    class _Outputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        axis: InputVector = None,
        angle: InputFloat = 0.0,
    ):
        super().__init__()
        key_args = {"Axis": axis, "Angle": angle}

        self._establish_links(**key_args)


class BitMath(BaseNode):
    """
    Perform bitwise operations on 32-bit integers

    Parameters
    ----------
    a : InputInteger
        A
    b : InputInteger
        B
    shift : InputInteger
        Shift

    Inputs
    ------
    i.a : IntegerSocket
        A
    i.b : IntegerSocket
        B
    i.shift : IntegerSocket
        Shift

    Outputs
    -------
    o.value : IntegerSocket
        Value
    """

    _bl_idname = "FunctionNodeBitMath"
    node: bpy.types.FunctionNodeBitMath

    class _Inputs(SocketAccessor):
        a: IntegerSocket
        """A"""
        b: IntegerSocket
        """B"""
        shift: IntegerSocket
        """Shift"""

    class _Outputs(SocketAccessor):
        value: IntegerSocket
        """Value"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        a: InputInteger = 0,
        b: InputInteger = 0,
        shift: InputInteger = 0,
        *,
        operation: Literal["AND", "OR", "XOR", "NOT", "SHIFT", "ROTATE"] = "AND",
    ):
        super().__init__()
        key_args = {"A": a, "B": b, "Shift": shift}
        self.operation = operation
        self._establish_links(**key_args)

    @classmethod
    def l_and(cls, a: InputInteger = 0, b: InputInteger = 0) -> "BitMath":
        """Create Bit Math with operation 'And'. Returns a value where the bits of A and B are both set"""
        return cls(operation="AND", a=a, b=b)

    @classmethod
    def l_or(cls, a: InputInteger = 0, b: InputInteger = 0) -> "BitMath":
        """Create Bit Math with operation 'Or'. Returns a value where the bits of either A or B are set"""
        return cls(operation="OR", a=a, b=b)

    @classmethod
    def exclusive_or(cls, a: InputInteger = 0, b: InputInteger = 0) -> "BitMath":
        """Create Bit Math with operation 'Exclusive Or'. Returns a value where only one bit from A and B is set"""
        return cls(operation="XOR", a=a, b=b)

    @classmethod
    def l_not(cls, a: InputInteger = 0) -> "BitMath":
        """Create Bit Math with operation 'Not'. Returns the opposite bit value of A, in decimal it is equivalent of A = -A - 1"""
        return cls(operation="NOT", a=a)

    @classmethod
    def shift(cls, a: InputInteger = 0, shift: InputInteger = 0) -> "BitMath":
        """Create Bit Math with operation 'Shift'. Shifts the bit values of A by the specified Shift amount. Positive values shift left, negative values shift right."""
        return cls(operation="SHIFT", a=a, shift=shift)

    @classmethod
    def rotate(cls, a: InputInteger = 0, shift: InputInteger = 0) -> "BitMath":
        """Create Bit Math with operation 'Rotate'. Rotates the bit values of A by the specified Shift amount. Positive values rotate left, negative values rotate right."""
        return cls(operation="ROTATE", a=a, shift=shift)

    @property
    def operation(self) -> Literal["AND", "OR", "XOR", "NOT", "SHIFT", "ROTATE"]:
        return self.node.operation

    @operation.setter
    def operation(self, value: Literal["AND", "OR", "XOR", "NOT", "SHIFT", "ROTATE"]):
        self.node.operation = value


class Blackbody(BaseNode):
    """
    Convert a blackbody temperature to an RGB value

    Parameters
    ----------
    temperature : InputFloat
        Temperature

    Inputs
    ------
    i.temperature : FloatSocket
        Temperature

    Outputs
    -------
    o.color : ColorSocket
        Color
    """

    _bl_idname = "ShaderNodeBlackbody"
    node: bpy.types.ShaderNodeBlackbody

    class _Inputs(SocketAccessor):
        temperature: FloatSocket
        """Temperature"""

    class _Outputs(SocketAccessor):
        color: ColorSocket
        """Color"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, temperature: InputFloat = 6500.0):
        super().__init__()
        key_args = {"Temperature": temperature}

        self._establish_links(**key_args)


class BooleanMath(BaseNode):
    """
    Perform a logical operation on the given boolean inputs

    Parameters
    ----------
    boolean : InputBoolean
        Boolean
    boolean_001 : InputBoolean
        Boolean

    Inputs
    ------
    i.boolean : BooleanSocket
        Boolean
    i.boolean_001 : BooleanSocket
        Boolean

    Outputs
    -------
    o.boolean : BooleanSocket
        Boolean
    """

    _bl_idname = "FunctionNodeBooleanMath"
    node: bpy.types.FunctionNodeBooleanMath

    class _Inputs(SocketAccessor):
        boolean: BooleanSocket
        """Boolean"""
        boolean_001: BooleanSocket
        """Boolean"""

    class _Outputs(SocketAccessor):
        boolean: BooleanSocket
        """Boolean"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        boolean: InputBoolean = False,
        boolean_001: InputBoolean = False,
        *,
        operation: Literal[
            "AND", "OR", "NOT", "NAND", "NOR", "XNOR", "XOR", "IMPLY", "NIMPLY"
        ] = "AND",
    ):
        super().__init__()
        key_args = {"Boolean": boolean, "Boolean_001": boolean_001}
        self.operation = operation
        self._establish_links(**key_args)

    @classmethod
    def l_and(
        cls, boolean: InputBoolean = False, boolean_001: InputBoolean = False
    ) -> "BooleanMath":
        """Create Boolean Math with operation 'And'. True when both inputs are true"""
        return cls(operation="AND", boolean=boolean, boolean_001=boolean_001)

    @classmethod
    def l_or(
        cls, boolean: InputBoolean = False, boolean_001: InputBoolean = False
    ) -> "BooleanMath":
        """Create Boolean Math with operation 'Or'. True when at least one input is true"""
        return cls(operation="OR", boolean=boolean, boolean_001=boolean_001)

    @classmethod
    def l_not(cls, boolean: InputBoolean = False) -> "BooleanMath":
        """Create Boolean Math with operation 'Not'. Opposite of the input"""
        return cls(operation="NOT", boolean=boolean)

    @classmethod
    def not_and(
        cls, boolean: InputBoolean = False, boolean_001: InputBoolean = False
    ) -> "BooleanMath":
        """Create Boolean Math with operation 'Not And'. True when at least one input is false"""
        return cls(operation="NAND", boolean=boolean, boolean_001=boolean_001)

    @classmethod
    def nor(
        cls, boolean: InputBoolean = False, boolean_001: InputBoolean = False
    ) -> "BooleanMath":
        """Create Boolean Math with operation 'Nor'. True when both inputs are false"""
        return cls(operation="NOR", boolean=boolean, boolean_001=boolean_001)

    @classmethod
    def equal(
        cls, boolean: InputBoolean = False, boolean_001: InputBoolean = False
    ) -> "BooleanMath":
        """Create Boolean Math with operation 'Equal'. True when both inputs are equal (exclusive nor)"""
        return cls(operation="XNOR", boolean=boolean, boolean_001=boolean_001)

    @classmethod
    def not_equal(
        cls, boolean: InputBoolean = False, boolean_001: InputBoolean = False
    ) -> "BooleanMath":
        """Create Boolean Math with operation 'Not Equal'. True when both inputs are different (exclusive or)"""
        return cls(operation="XOR", boolean=boolean, boolean_001=boolean_001)

    @classmethod
    def imply(
        cls, boolean: InputBoolean = False, boolean_001: InputBoolean = False
    ) -> "BooleanMath":
        """Create Boolean Math with operation 'Imply'. True unless the first input is true and the second is false"""
        return cls(operation="IMPLY", boolean=boolean, boolean_001=boolean_001)

    @classmethod
    def subtract(
        cls, boolean: InputBoolean = False, boolean_001: InputBoolean = False
    ) -> "BooleanMath":
        """Create Boolean Math with operation 'Subtract'. True when the first input is true and the second is false (not imply)"""
        return cls(operation="NIMPLY", boolean=boolean, boolean_001=boolean_001)

    @property
    def operation(
        self,
    ) -> Literal["AND", "OR", "NOT", "NAND", "NOR", "XNOR", "XOR", "IMPLY", "NIMPLY"]:
        return self.node.operation

    @operation.setter
    def operation(
        self,
        value: Literal[
            "AND", "OR", "NOT", "NAND", "NOR", "XNOR", "XOR", "IMPLY", "NIMPLY"
        ],
    ):
        self.node.operation = value


class Clamp(BaseNode):
    """
    Clamp a value between a minimum and a maximum

    Parameters
    ----------
    value : InputFloat
        Value
    min : InputFloat
        Min
    max : InputFloat
        Max

    Inputs
    ------
    i.value : FloatSocket
        Value
    i.min : FloatSocket
        Min
    i.max : FloatSocket
        Max

    Outputs
    -------
    o.result : FloatSocket
        Result
    """

    _bl_idname = "ShaderNodeClamp"
    node: bpy.types.ShaderNodeClamp

    class _Inputs(SocketAccessor):
        value: FloatSocket
        """Value"""
        min: FloatSocket
        """Min"""
        max: FloatSocket
        """Max"""

    class _Outputs(SocketAccessor):
        result: FloatSocket
        """Result"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        value: InputFloat = 1.0,
        min: InputFloat = 0.0,
        max: InputFloat = 1.0,
        *,
        clamp_type: Literal["MINMAX", "RANGE"] = "MINMAX",
    ):
        super().__init__()
        key_args = {"Value": value, "Min": min, "Max": max}
        self.clamp_type = clamp_type
        self._establish_links(**key_args)

    @classmethod
    def min_max(
        cls, value: InputFloat = 1.0, min: InputFloat = 0.0, max: InputFloat = 1.0
    ) -> "Clamp":
        """Create Clamp with operation 'Min Max'. Constrain value between min and max"""
        return cls(clamp_type="MINMAX", value=value, min=min, max=max)

    @classmethod
    def range(
        cls, value: InputFloat = 1.0, min: InputFloat = 0.0, max: InputFloat = 1.0
    ) -> "Clamp":
        """Create Clamp with operation 'Range'. Constrain value between min and max, swapping arguments when min > max"""
        return cls(clamp_type="RANGE", value=value, min=min, max=max)

    @property
    def clamp_type(self) -> Literal["MINMAX", "RANGE"]:
        return self.node.clamp_type

    @clamp_type.setter
    def clamp_type(self, value: Literal["MINMAX", "RANGE"]):
        self.node.clamp_type = value


class ClosureToList(BaseNode):
    """
    Create a list of values

    Parameters
    ----------
    count : InputInteger
        Count
    closure : InputClosure
        Closure

    Inputs
    ------
    i.count : IntegerSocket
        Count
    i.closure : ClosureSocket
        Closure
    """

    _bl_idname = "GeometryNodeClosureToList"
    node: bpy.types.GeometryNodeClosureToList  # ty: ignore[unresolved-attribute]

    class _Inputs(SocketAccessor):
        count: IntegerSocket
        """Count"""
        closure: ClosureSocket
        """Closure"""

    class _Outputs(SocketAccessor):
        pass

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        count: InputInteger = 1,
        closure: InputClosure = None,
    ):
        super().__init__()
        key_args = {"Count": count, "Closure": closure}

        self._establish_links(**key_args)


class ClusterByConnected(BaseNode):
    """
    Group mesh vertices connected by edges when they are within a specified distance

    Parameters
    ----------
    selection : InputBoolean
        Selection
    position : InputVector
        Position
    distance : InputFloat
        Distance

    Inputs
    ------
    i.selection : BooleanSocket
        Selection
    i.position : VectorSocket
        Position
    i.distance : FloatSocket
        Distance

    Outputs
    -------
    o.cluster_id : IntegerSocket
        Cluster ID
    """

    _bl_idname = "GeometryNodeClusterByConnected"
    node: bpy.types.GeometryNodeClusterByConnected  # ty: ignore[unresolved-attribute]

    class _Inputs(SocketAccessor):
        selection: BooleanSocket
        """Selection"""
        position: VectorSocket
        """Position"""
        distance: FloatSocket
        """Distance"""

    class _Outputs(SocketAccessor):
        cluster_id: IntegerSocket
        """Cluster ID"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        selection: InputBoolean = True,
        position: InputVector = None,
        distance: InputFloat = 0.001,
    ):
        super().__init__()
        key_args = {"Selection": selection, "Position": position, "Distance": distance}

        self._establish_links(**key_args)


class ClusterByDistance(BaseNode):
    """
    Group elements into integer IDs based on proximity of vector values

    Parameters
    ----------
    selection : InputBoolean
        Selection
    group_id : InputInteger
        Group ID
    position : InputVector
        Position
    distance : InputFloat
        Distance

    Inputs
    ------
    i.selection : BooleanSocket
        Selection
    i.group_id : IntegerSocket
        Group ID
    i.position : VectorSocket
        Position
    i.distance : FloatSocket
        Distance

    Outputs
    -------
    o.cluster_id : IntegerSocket
        Cluster ID
    """

    _bl_idname = "GeometryNodeClusterByDistance"
    node: bpy.types.GeometryNodeClusterByDistance  # ty: ignore[unresolved-attribute]

    class _Inputs(SocketAccessor):
        selection: BooleanSocket
        """Selection"""
        group_id: IntegerSocket
        """Group ID"""
        position: VectorSocket
        """Position"""
        distance: FloatSocket
        """Distance"""

    class _Outputs(SocketAccessor):
        cluster_id: IntegerSocket
        """Cluster ID"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        position: InputVector = None,
        distance: InputFloat = 0.001,
    ):
        super().__init__()
        key_args = {
            "Selection": selection,
            "Group ID": group_id,
            "Position": position,
            "Distance": distance,
        }

        self._establish_links(**key_args)


class CombineBundle(BaseNode):
    """
    Combine multiple socket values into one.

    Outputs
    -------
    o.bundle : BundleSocket
        Bundle
    """

    _bl_idname = "NodeCombineBundle"
    node: bpy.types.NodeCombineBundle

    class _Inputs(SocketAccessor):
        pass

    class _Outputs(SocketAccessor):
        bundle: BundleSocket
        """Bundle"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    @property
    def define_signature(self) -> bool:
        return self.node.define_signature

    @define_signature.setter
    def define_signature(self, value: bool):
        self.node.define_signature = value

    def __init__(
        self,
        items: "dict[str, InputAny] | None" = None,
        *,
        define_signature: bool = False,
    ):
        super().__init__()
        for name, value in (items or {}).items():
            self._add_bundle_item(name, value)
        self.define_signature = define_signature

    def _add_bundle_item(self, name: str, value: InputAny) -> None:
        """Add a named bundle item from a value of any supported kind.

        - a socket-type string (``"GEOMETRY"``) declares an empty item;
        - a socket / node source is linked in via the ``__extend__`` virtual
          socket (Blender makes an item of the source's own type, then renamed);
        - any other value declares an item of the inferred type and sets its
          default.
        """
        if isinstance(value, str):
            self.node.bundle_items.new(value, name)  # ty: ignore[invalid-argument-type]
        elif isinstance(value, (BaseNode, Socket, bpy.types.NodeSocket)):
            extend = self.node.inputs[len(self.node.inputs) - 1]
            self.tree.link(self._source_socket(value), extend)
            # Re-fetch by index: the collection just grew, so any earlier item
            # reference is stale (see bpy collection invalidation).
            self.node.bundle_items[len(self.node.bundle_items) - 1].name = name
        else:
            socket_type = _infer_value_type(value)
            if socket_type is None:
                raise TypeError(f"Unsupported bundle item {name!r}: {value!r}")
            self.node.bundle_items.new(socket_type, name)  # ty: ignore[invalid-argument-type]
            self.node.inputs[name].default_value = value


class CombineColor(BaseNode):
    """
    Combine four channels into a single color, based on a particular color model

    Parameters
    ----------
    red : InputFloat
        Red
    green : InputFloat
        Green
    blue : InputFloat
        Blue
    alpha : InputFloat
        Alpha

    Inputs
    ------
    i.red : FloatSocket
        Red
    i.green : FloatSocket
        Green
    i.blue : FloatSocket
        Blue
    i.alpha : FloatSocket
        Alpha

    Outputs
    -------
    o.color : ColorSocket
        Color
    """

    _bl_idname = "FunctionNodeCombineColor"
    node: bpy.types.FunctionNodeCombineColor

    class _Inputs(SocketAccessor):
        red: FloatSocket
        """Red"""
        green: FloatSocket
        """Green"""
        blue: FloatSocket
        """Blue"""
        alpha: FloatSocket
        """Alpha"""

    class _Outputs(SocketAccessor):
        color: ColorSocket
        """Color"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        red: InputFloat = 0.0,
        green: InputFloat = 0.0,
        blue: InputFloat = 0.0,
        alpha: InputFloat = 1.0,
        *,
        mode: Literal["RGB", "HSV", "HSL"] = "RGB",
    ):
        super().__init__()
        key_args = {"Red": red, "Green": green, "Blue": blue, "Alpha": alpha}
        self.mode = mode
        self._establish_links(**key_args)

    @classmethod
    def rgb(
        cls,
        red: InputFloat = 0.0,
        green: InputFloat = 0.0,
        blue: InputFloat = 0.0,
        alpha: InputFloat = 1.0,
    ) -> "CombineColor":
        """Create Combine Color with operation 'RGB'. Use RGB (Red, Green, Blue) color processing"""
        return cls(mode="RGB", red=red, green=green, blue=blue, alpha=alpha)

    @classmethod
    def hsv(
        cls,
        red: InputFloat = 0.0,
        green: InputFloat = 0.0,
        blue: InputFloat = 0.0,
        alpha: InputFloat = 1.0,
    ) -> "CombineColor":
        """Create Combine Color with operation 'HSV'. Use HSV (Hue, Saturation, Value) color processing"""
        return cls(mode="HSV", red=red, green=green, blue=blue, alpha=alpha)

    @classmethod
    def hsl(
        cls,
        red: InputFloat = 0.0,
        green: InputFloat = 0.0,
        blue: InputFloat = 0.0,
        alpha: InputFloat = 1.0,
    ) -> "CombineColor":
        """Create Combine Color with operation 'HSL'. Use HSL (Hue, Saturation, Lightness) color processing"""
        return cls(mode="HSL", red=red, green=green, blue=blue, alpha=alpha)

    @property
    def mode(self) -> Literal["RGB", "HSV", "HSL"]:
        return self.node.mode

    @mode.setter
    def mode(self, value: Literal["RGB", "HSV", "HSL"]):
        self.node.mode = value


class CombineMatrix(BaseNode):
    """
    Construct a 4x4 matrix from its individual values

    Parameters
    ----------
    column_1_row_1 : InputFloat
        Column 1 Row 1
    column_1_row_2 : InputFloat
        Column 1 Row 2
    column_1_row_3 : InputFloat
        Column 1 Row 3
    column_1_row_4 : InputFloat
        Column 1 Row 4
    column_2_row_1 : InputFloat
        Column 2 Row 1
    column_2_row_2 : InputFloat
        Column 2 Row 2
    column_2_row_3 : InputFloat
        Column 2 Row 3
    column_2_row_4 : InputFloat
        Column 2 Row 4
    column_3_row_1 : InputFloat
        Column 3 Row 1
    column_3_row_2 : InputFloat
        Column 3 Row 2
    column_3_row_3 : InputFloat
        Column 3 Row 3
    column_3_row_4 : InputFloat
        Column 3 Row 4
    column_4_row_1 : InputFloat
        Column 4 Row 1
    column_4_row_2 : InputFloat
        Column 4 Row 2
    column_4_row_3 : InputFloat
        Column 4 Row 3
    column_4_row_4 : InputFloat
        Column 4 Row 4

    Inputs
    ------
    i.column_1_row_1 : FloatSocket
        Column 1 Row 1
    i.column_1_row_2 : FloatSocket
        Column 1 Row 2
    i.column_1_row_3 : FloatSocket
        Column 1 Row 3
    i.column_1_row_4 : FloatSocket
        Column 1 Row 4
    i.column_2_row_1 : FloatSocket
        Column 2 Row 1
    i.column_2_row_2 : FloatSocket
        Column 2 Row 2
    i.column_2_row_3 : FloatSocket
        Column 2 Row 3
    i.column_2_row_4 : FloatSocket
        Column 2 Row 4
    i.column_3_row_1 : FloatSocket
        Column 3 Row 1
    i.column_3_row_2 : FloatSocket
        Column 3 Row 2
    i.column_3_row_3 : FloatSocket
        Column 3 Row 3
    i.column_3_row_4 : FloatSocket
        Column 3 Row 4
    i.column_4_row_1 : FloatSocket
        Column 4 Row 1
    i.column_4_row_2 : FloatSocket
        Column 4 Row 2
    i.column_4_row_3 : FloatSocket
        Column 4 Row 3
    i.column_4_row_4 : FloatSocket
        Column 4 Row 4

    Outputs
    -------
    o.matrix : MatrixSocket
        Matrix
    """

    _bl_idname = "FunctionNodeCombineMatrix"
    node: bpy.types.FunctionNodeCombineMatrix

    class _Inputs(SocketAccessor):
        column_1_row_1: FloatSocket
        """Column 1 Row 1"""
        column_1_row_2: FloatSocket
        """Column 1 Row 2"""
        column_1_row_3: FloatSocket
        """Column 1 Row 3"""
        column_1_row_4: FloatSocket
        """Column 1 Row 4"""
        column_2_row_1: FloatSocket
        """Column 2 Row 1"""
        column_2_row_2: FloatSocket
        """Column 2 Row 2"""
        column_2_row_3: FloatSocket
        """Column 2 Row 3"""
        column_2_row_4: FloatSocket
        """Column 2 Row 4"""
        column_3_row_1: FloatSocket
        """Column 3 Row 1"""
        column_3_row_2: FloatSocket
        """Column 3 Row 2"""
        column_3_row_3: FloatSocket
        """Column 3 Row 3"""
        column_3_row_4: FloatSocket
        """Column 3 Row 4"""
        column_4_row_1: FloatSocket
        """Column 4 Row 1"""
        column_4_row_2: FloatSocket
        """Column 4 Row 2"""
        column_4_row_3: FloatSocket
        """Column 4 Row 3"""
        column_4_row_4: FloatSocket
        """Column 4 Row 4"""

    class _Outputs(SocketAccessor):
        matrix: MatrixSocket
        """Matrix"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        column_1_row_1: InputFloat = 1.0,
        column_1_row_2: InputFloat = 0.0,
        column_1_row_3: InputFloat = 0.0,
        column_1_row_4: InputFloat = 0.0,
        column_2_row_1: InputFloat = 0.0,
        column_2_row_2: InputFloat = 1.0,
        column_2_row_3: InputFloat = 0.0,
        column_2_row_4: InputFloat = 0.0,
        column_3_row_1: InputFloat = 0.0,
        column_3_row_2: InputFloat = 0.0,
        column_3_row_3: InputFloat = 1.0,
        column_3_row_4: InputFloat = 0.0,
        column_4_row_1: InputFloat = 0.0,
        column_4_row_2: InputFloat = 0.0,
        column_4_row_3: InputFloat = 0.0,
        column_4_row_4: InputFloat = 1.0,
    ):
        super().__init__()
        key_args = {
            "Column 1 Row 1": column_1_row_1,
            "Column 1 Row 2": column_1_row_2,
            "Column 1 Row 3": column_1_row_3,
            "Column 1 Row 4": column_1_row_4,
            "Column 2 Row 1": column_2_row_1,
            "Column 2 Row 2": column_2_row_2,
            "Column 2 Row 3": column_2_row_3,
            "Column 2 Row 4": column_2_row_4,
            "Column 3 Row 1": column_3_row_1,
            "Column 3 Row 2": column_3_row_2,
            "Column 3 Row 3": column_3_row_3,
            "Column 3 Row 4": column_3_row_4,
            "Column 4 Row 1": column_4_row_1,
            "Column 4 Row 2": column_4_row_2,
            "Column 4 Row 3": column_4_row_3,
            "Column 4 Row 4": column_4_row_4,
        }

        self._establish_links(**key_args)


class CombineTransform(BaseNode):
    """
    Combine a translation vector, a rotation, and a scale vector into a transformation matrix

    Parameters
    ----------
    translation : InputVector
        Translation
    rotation : InputRotation
        Rotation
    scale : InputVector
        Scale

    Inputs
    ------
    i.translation : VectorSocket
        Translation
    i.rotation : RotationSocket
        Rotation
    i.scale : VectorSocket
        Scale

    Outputs
    -------
    o.transform : MatrixSocket
        Transform
    """

    _bl_idname = "FunctionNodeCombineTransform"
    node: bpy.types.FunctionNodeCombineTransform

    class _Inputs(SocketAccessor):
        translation: VectorSocket
        """Translation"""
        rotation: RotationSocket
        """Rotation"""
        scale: VectorSocket
        """Scale"""

    class _Outputs(SocketAccessor):
        transform: MatrixSocket
        """Transform"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        translation: InputVector = None,
        rotation: InputRotation = None,
        scale: InputVector = None,
    ):
        super().__init__()
        key_args = {"Translation": translation, "Rotation": rotation, "Scale": scale}

        self._establish_links(**key_args)


class CombineXYZ(BaseNode):
    """
    Create a vector from X, Y, and Z components

    Parameters
    ----------
    x : InputFloat
        X
    y : InputFloat
        Y
    z : InputFloat
        Z

    Inputs
    ------
    i.x : FloatSocket
        X
    i.y : FloatSocket
        Y
    i.z : FloatSocket
        Z

    Outputs
    -------
    o.vector : VectorSocket
        Vector
    """

    _bl_idname = "ShaderNodeCombineXYZ"
    node: bpy.types.ShaderNodeCombineXYZ

    class _Inputs(SocketAccessor):
        x: FloatSocket
        """X"""
        y: FloatSocket
        """Y"""
        z: FloatSocket
        """Z"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        x: InputFloat = 0.0,
        y: InputFloat = 0.0,
        z: InputFloat = 0.0,
    ):
        super().__init__()
        key_args = {"X": x, "Y": y, "Z": z}

        self._establish_links(**key_args)


class EulerToRotation(BaseNode):
    """
    Build a rotation from separate angles around each axis

    Parameters
    ----------
    euler : InputVector
        Euler

    Inputs
    ------
    i.euler : VectorSocket
        Euler

    Outputs
    -------
    o.rotation : RotationSocket
        Rotation
    """

    _bl_idname = "FunctionNodeEulerToRotation"
    node: bpy.types.FunctionNodeEulerToRotation

    class _Inputs(SocketAccessor):
        euler: VectorSocket
        """Euler"""

    class _Outputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, euler: InputVector = None):
        super().__init__()
        key_args = {"Euler": euler}

        self._establish_links(**key_args)


class EvaluateAtIndex(BaseNode, Generic[_T]):
    """
    Retrieve data of other elements in the context's geometry

    Parameters
    ----------
    value : InputFloat
        Value
    index : InputInteger
        Index

    Inputs
    ------
    i.value : FloatSocket
        Value
    i.index : IntegerSocket
        Index

    Outputs
    -------
    o.value : FloatSocket
        Value
    """

    _bl_idname = "GeometryNodeFieldAtIndex"
    node: bpy.types.GeometryNodeFieldAtIndex

    class _Inputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""
        index: IntegerSocket
        """Index"""

    class _Outputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        value: InputAny = 0.0,
        index: InputInteger = 0,
        *,
        domain: Literal[
            "POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"
        ] = "POINT",
        data_type: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "FLOAT_VECTOR",
            "FLOAT_COLOR",
            "QUATERNION",
            "FLOAT4X4",
        ] = "FLOAT",
    ):
        super().__init__()
        key_args = {"Value": value, "Index": index}
        self.domain = domain
        self.data_type = data_type
        self._establish_links(**key_args)

    @classmethod
    def face_corner(
        cls, value: InputFloat = 0.0, index: InputInteger = 0
    ) -> "EvaluateAtIndex[FloatSocket]":
        """Create Evaluate at Index with operation 'Face Corner'. Attribute on mesh face corner"""
        return EvaluateAtIndex(domain="CORNER", value=value, index=index)

    @classmethod
    def input_4x4_matrix(
        cls, value: InputMatrix = None, index: InputInteger = 0
    ) -> "EvaluateAtIndex[MatrixSocket]":
        """Create Evaluate at Index with operation '4x4 Matrix'. Floating point matrix"""
        return EvaluateAtIndex(data_type="FLOAT4X4", value=value, index=index)

    @property
    def domain(
        self,
    ) -> Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"]:
        return self.node.domain

    @domain.setter
    def domain(
        self,
        value: Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"],
    ):
        self.node.domain = value

    @property
    def data_type(
        self,
    ) -> Literal[
        "FLOAT",
        "INT",
        "BOOLEAN",
        "FLOAT_VECTOR",
        "FLOAT_COLOR",
        "QUATERNION",
        "FLOAT4X4",
    ]:
        return self.node.data_type  # ty: ignore[invalid-return-type]

    @data_type.setter
    def data_type(
        self,
        value: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "FLOAT_VECTOR",
            "FLOAT_COLOR",
            "QUATERNION",
            "FLOAT4X4",
        ],
    ):
        self.node.data_type = value

    class _EvaluateAtIndexDomainFactory:
        def __init__(self, domain: _AttributeDomains):
            self._domain = domain

        def float(
            self, value: InputFloat = None, index: InputInteger = 0
        ) -> "EvaluateAtIndex[FloatSocket]":
            """Create 'EvaluateAtIndex' on this domain with 'FLOAT' data type."""
            return EvaluateAtIndex(value, index, domain=self._domain, data_type="FLOAT")

        def integer(
            self, value: InputInteger = None, index: InputInteger = 0
        ) -> "EvaluateAtIndex[IntegerSocket]":
            """Create 'EvaluateAtIndex' on this domain with 'INT' data type."""
            return EvaluateAtIndex(value, index, domain=self._domain, data_type="INT")

        def boolean(
            self, value: InputBoolean = None, index: InputInteger = 0
        ) -> "EvaluateAtIndex[BooleanSocket]":
            """Create 'EvaluateAtIndex' on this domain with 'BOOLEAN' data type."""
            return EvaluateAtIndex(
                value, index, domain=self._domain, data_type="BOOLEAN"
            )

        def vector(
            self, value: InputVector = None, index: InputInteger = 0
        ) -> "EvaluateAtIndex[VectorSocket]":
            """Create 'EvaluateAtIndex' on this domain with 'FLOAT_VECTOR' data type."""
            return EvaluateAtIndex(
                value, index, domain=self._domain, data_type="FLOAT_VECTOR"
            )

        def color(
            self, value: InputColor = None, index: InputInteger = 0
        ) -> "EvaluateAtIndex[ColorSocket]":
            """Create 'EvaluateAtIndex' on this domain with 'FLOAT_COLOR' data type."""
            return EvaluateAtIndex(
                value, index, domain=self._domain, data_type="FLOAT_COLOR"
            )

        def quaternion(
            self, value: InputRotation = None, index: InputInteger = 0
        ) -> "EvaluateAtIndex[RotationSocket]":
            """Create 'EvaluateAtIndex' on this domain with 'QUATERNION' data type."""
            return EvaluateAtIndex(
                value, index, domain=self._domain, data_type="QUATERNION"
            )

        def matrix(
            self, value: InputMatrix = None, index: InputInteger = 0
        ) -> "EvaluateAtIndex[MatrixSocket]":
            """Create 'EvaluateAtIndex' on this domain with 'FLOAT4X4' data type."""
            return EvaluateAtIndex(
                value, index, domain=self._domain, data_type="FLOAT4X4"
            )

    point = _EvaluateAtIndexDomainFactory("POINT")
    edge = _EvaluateAtIndexDomainFactory("EDGE")
    face = _EvaluateAtIndexDomainFactory("FACE")
    corner = _EvaluateAtIndexDomainFactory("CORNER")
    spline = _EvaluateAtIndexDomainFactory("CURVE")
    instance = _EvaluateAtIndexDomainFactory("INSTANCE")
    layer = _EvaluateAtIndexDomainFactory("LAYER")


class EvaluateOnDomain(BaseNode, Generic[_T]):
    """
    Retrieve values from a field on a different domain besides the domain from the context

    Parameters
    ----------
    value : InputFloat
        Value

    Inputs
    ------
    i.value : FloatSocket
        Value

    Outputs
    -------
    o.value : FloatSocket
        Value
    """

    _bl_idname = "GeometryNodeFieldOnDomain"
    node: bpy.types.GeometryNodeFieldOnDomain

    class _Inputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""

    class _Outputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        value: InputAny = 0.0,
        *,
        domain: Literal[
            "POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"
        ] = "POINT",
        data_type: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "FLOAT_VECTOR",
            "FLOAT_COLOR",
            "QUATERNION",
            "FLOAT4X4",
        ] = "FLOAT",
    ):
        super().__init__()
        key_args = {"Value": value}
        self.domain = domain
        self.data_type = data_type
        self._establish_links(**key_args)

    @classmethod
    def face_corner(cls, value: InputFloat = 0.0) -> "EvaluateOnDomain[FloatSocket]":
        """Create Evaluate on Domain with operation 'Face Corner'. Attribute on mesh face corner"""
        return EvaluateOnDomain(domain="CORNER", value=value)

    @classmethod
    def input_4x4_matrix(
        cls, value: InputMatrix = None
    ) -> "EvaluateOnDomain[MatrixSocket]":
        """Create Evaluate on Domain with operation '4x4 Matrix'. Floating point matrix"""
        return EvaluateOnDomain(data_type="FLOAT4X4", value=value)

    @property
    def domain(
        self,
    ) -> Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"]:
        return self.node.domain

    @domain.setter
    def domain(
        self,
        value: Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"],
    ):
        self.node.domain = value

    @property
    def data_type(
        self,
    ) -> Literal[
        "FLOAT",
        "INT",
        "BOOLEAN",
        "FLOAT_VECTOR",
        "FLOAT_COLOR",
        "QUATERNION",
        "FLOAT4X4",
    ]:
        return self.node.data_type  # ty: ignore[invalid-return-type]

    @data_type.setter
    def data_type(
        self,
        value: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "FLOAT_VECTOR",
            "FLOAT_COLOR",
            "QUATERNION",
            "FLOAT4X4",
        ],
    ):
        self.node.data_type = value

    class _EvaluateOnDomainDomainFactory:
        def __init__(self, domain: _AttributeDomains):
            self._domain = domain

        def float(self, value: InputFloat = None) -> "EvaluateOnDomain[FloatSocket]":
            """Create 'EvaluateOnDomain' on this domain with 'FLOAT' data type."""
            return EvaluateOnDomain(value, domain=self._domain, data_type="FLOAT")

        def integer(
            self, value: InputInteger = None
        ) -> "EvaluateOnDomain[IntegerSocket]":
            """Create 'EvaluateOnDomain' on this domain with 'INT' data type."""
            return EvaluateOnDomain(value, domain=self._domain, data_type="INT")

        def boolean(
            self, value: InputBoolean = None
        ) -> "EvaluateOnDomain[BooleanSocket]":
            """Create 'EvaluateOnDomain' on this domain with 'BOOLEAN' data type."""
            return EvaluateOnDomain(value, domain=self._domain, data_type="BOOLEAN")

        def vector(self, value: InputVector = None) -> "EvaluateOnDomain[VectorSocket]":
            """Create 'EvaluateOnDomain' on this domain with 'FLOAT_VECTOR' data type."""
            return EvaluateOnDomain(
                value, domain=self._domain, data_type="FLOAT_VECTOR"
            )

        def color(self, value: InputColor = None) -> "EvaluateOnDomain[ColorSocket]":
            """Create 'EvaluateOnDomain' on this domain with 'FLOAT_COLOR' data type."""
            return EvaluateOnDomain(value, domain=self._domain, data_type="FLOAT_COLOR")

        def quaternion(
            self, value: InputRotation = None
        ) -> "EvaluateOnDomain[RotationSocket]":
            """Create 'EvaluateOnDomain' on this domain with 'QUATERNION' data type."""
            return EvaluateOnDomain(value, domain=self._domain, data_type="QUATERNION")

        def matrix(self, value: InputMatrix = None) -> "EvaluateOnDomain[MatrixSocket]":
            """Create 'EvaluateOnDomain' on this domain with 'FLOAT4X4' data type."""
            return EvaluateOnDomain(value, domain=self._domain, data_type="FLOAT4X4")

    point = _EvaluateOnDomainDomainFactory("POINT")
    edge = _EvaluateOnDomainDomainFactory("EDGE")
    face = _EvaluateOnDomainDomainFactory("FACE")
    corner = _EvaluateOnDomainDomainFactory("CORNER")
    spline = _EvaluateOnDomainDomainFactory("CURVE")
    instance = _EvaluateOnDomainDomainFactory("INSTANCE")
    layer = _EvaluateOnDomainDomainFactory("LAYER")


class FieldAverage(BaseNode, Generic[_T]):
    """
    Calculate the mean and median of a given field

    Parameters
    ----------
    value : InputFloat
        Value
    group_index : InputInteger
        Group ID

    Inputs
    ------
    i.value : FloatSocket
        Value
    i.group_index : IntegerSocket
        Group ID

    Outputs
    -------
    o.mean : FloatSocket
        Mean
    o.median : FloatSocket
        Median
    """

    _bl_idname = "GeometryNodeFieldAverage"
    node: bpy.types.GeometryNodeFieldAverage

    class _Inputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""
        group_index: IntegerSocket
        """Group ID"""

    class _Outputs(SocketAccessor, Generic[_S]):
        mean: _S
        """Mean"""
        median: _S
        """Median"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        value: InputAny = 0.0,
        group_index: InputInteger = 0,
        *,
        data_type: Literal["FLOAT", "FLOAT_VECTOR"] = "FLOAT",
        domain: Literal[
            "POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"
        ] = "POINT",
    ):
        super().__init__()
        key_args = {"Value": value, "Group Index": group_index}
        self.data_type = data_type
        self.domain = domain
        self._establish_links(**key_args)

    @classmethod
    def face_corner(
        cls, value: InputFloat = 0.0, group_index: InputInteger = 0
    ) -> "FieldAverage[FloatSocket]":
        """Create Field Average with operation 'Face Corner'. Attribute on mesh face corner"""
        return FieldAverage(domain="CORNER", value=value, group_index=group_index)

    @property
    def data_type(self) -> Literal["FLOAT", "FLOAT_VECTOR"]:
        return self.node.data_type

    @data_type.setter
    def data_type(self, value: Literal["FLOAT", "FLOAT_VECTOR"]):
        self.node.data_type = value

    @property
    def domain(
        self,
    ) -> Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"]:
        return self.node.domain

    @domain.setter
    def domain(
        self,
        value: Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"],
    ):
        self.node.domain = value

    class _FieldAverageDomainFactory:
        def __init__(self, domain: _AttributeDomains):
            self._domain = domain

        def float(
            self, value: InputFloat = None, group_index: InputInteger = 0
        ) -> "FieldAverage[FloatSocket]":
            """Create 'FieldAverage' on this domain with 'FLOAT' data type."""
            return FieldAverage(
                value, group_index, domain=self._domain, data_type="FLOAT"
            )

        def vector(
            self, value: InputVector = None, group_index: InputInteger = 0
        ) -> "FieldAverage[VectorSocket]":
            """Create 'FieldAverage' on this domain with 'FLOAT_VECTOR' data type."""
            return FieldAverage(
                value, group_index, domain=self._domain, data_type="FLOAT_VECTOR"
            )

    point = _FieldAverageDomainFactory("POINT")
    edge = _FieldAverageDomainFactory("EDGE")
    face = _FieldAverageDomainFactory("FACE")
    corner = _FieldAverageDomainFactory("CORNER")
    spline = _FieldAverageDomainFactory("CURVE")
    instance = _FieldAverageDomainFactory("INSTANCE")
    layer = _FieldAverageDomainFactory("LAYER")


class FieldMinAndMax(BaseNode, Generic[_T]):
    """
    Calculate the minimum and maximum of a given field

    Parameters
    ----------
    value : InputFloat
        Value
    group_index : InputInteger
        Group ID

    Inputs
    ------
    i.value : FloatSocket
        Value
    i.group_index : IntegerSocket
        Group ID

    Outputs
    -------
    o.min : FloatSocket
        Min
    o.max : FloatSocket
        Max
    """

    _bl_idname = "GeometryNodeFieldMinAndMax"
    node: bpy.types.GeometryNodeFieldMinAndMax

    class _Inputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""
        group_index: IntegerSocket
        """Group ID"""

    class _Outputs(SocketAccessor, Generic[_S]):
        min: _S
        """Min"""
        max: _S
        """Max"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        value: InputAny = 0.0,
        group_index: InputInteger = 0,
        *,
        data_type: Literal["FLOAT", "INT", "FLOAT_VECTOR"] = "FLOAT",
        domain: Literal[
            "POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"
        ] = "POINT",
    ):
        super().__init__()
        key_args = {"Value": value, "Group Index": group_index}
        self.data_type = data_type
        self.domain = domain
        self._establish_links(**key_args)

    @classmethod
    def face_corner(
        cls, value: InputFloat = 0.0, group_index: InputInteger = 0
    ) -> "FieldMinAndMax[FloatSocket]":
        """Create Field Min & Max with operation 'Face Corner'. Attribute on mesh face corner"""
        return FieldMinAndMax(domain="CORNER", value=value, group_index=group_index)

    @property
    def data_type(self) -> Literal["FLOAT", "INT", "FLOAT_VECTOR"]:
        return self.node.data_type

    @data_type.setter
    def data_type(self, value: Literal["FLOAT", "INT", "FLOAT_VECTOR"]):
        self.node.data_type = value

    @property
    def domain(
        self,
    ) -> Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"]:
        return self.node.domain

    @domain.setter
    def domain(
        self,
        value: Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"],
    ):
        self.node.domain = value

    class _FieldMinAndMaxDomainFactory:
        def __init__(self, domain: _AttributeDomains):
            self._domain = domain

        def float(
            self, value: InputFloat = None, group_index: InputInteger = 0
        ) -> "FieldMinAndMax[FloatSocket]":
            """Create 'FieldMinAndMax' on this domain with 'FLOAT' data type."""
            return FieldMinAndMax(
                value, group_index, domain=self._domain, data_type="FLOAT"
            )

        def integer(
            self, value: InputInteger = None, group_index: InputInteger = 0
        ) -> "FieldMinAndMax[IntegerSocket]":
            """Create 'FieldMinAndMax' on this domain with 'INT' data type."""
            return FieldMinAndMax(
                value, group_index, domain=self._domain, data_type="INT"
            )

        def vector(
            self, value: InputVector = None, group_index: InputInteger = 0
        ) -> "FieldMinAndMax[VectorSocket]":
            """Create 'FieldMinAndMax' on this domain with 'FLOAT_VECTOR' data type."""
            return FieldMinAndMax(
                value, group_index, domain=self._domain, data_type="FLOAT_VECTOR"
            )

    point = _FieldMinAndMaxDomainFactory("POINT")
    edge = _FieldMinAndMaxDomainFactory("EDGE")
    face = _FieldMinAndMaxDomainFactory("FACE")
    corner = _FieldMinAndMaxDomainFactory("CORNER")
    spline = _FieldMinAndMaxDomainFactory("CURVE")
    instance = _FieldMinAndMaxDomainFactory("INSTANCE")
    layer = _FieldMinAndMaxDomainFactory("LAYER")


class FieldVariance(BaseNode, Generic[_T]):
    """
    Calculate the standard deviation and variance of a given field

    Parameters
    ----------
    value : InputFloat
        Value
    group_index : InputInteger
        Group ID

    Inputs
    ------
    i.value : FloatSocket
        Value
    i.group_index : IntegerSocket
        Group ID

    Outputs
    -------
    o.standard_deviation : FloatSocket
        Standard Deviation
    o.variance : FloatSocket
        Variance
    """

    _bl_idname = "GeometryNodeFieldVariance"
    node: bpy.types.GeometryNodeFieldVariance

    class _Inputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""
        group_index: IntegerSocket
        """Group ID"""

    class _Outputs(SocketAccessor, Generic[_S]):
        standard_deviation: _S
        """Standard Deviation"""
        variance: _S
        """Variance"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        value: InputAny = 0.0,
        group_index: InputInteger = 0,
        *,
        data_type: Literal["FLOAT", "FLOAT_VECTOR"] = "FLOAT",
        domain: Literal[
            "POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"
        ] = "POINT",
    ):
        super().__init__()
        key_args = {"Value": value, "Group Index": group_index}
        self.data_type = data_type
        self.domain = domain
        self._establish_links(**key_args)

    @classmethod
    def face_corner(
        cls, value: InputFloat = 0.0, group_index: InputInteger = 0
    ) -> "FieldVariance[FloatSocket]":
        """Create Field Variance with operation 'Face Corner'. Attribute on mesh face corner"""
        return FieldVariance(domain="CORNER", value=value, group_index=group_index)

    @property
    def data_type(self) -> Literal["FLOAT", "FLOAT_VECTOR"]:
        return self.node.data_type

    @data_type.setter
    def data_type(self, value: Literal["FLOAT", "FLOAT_VECTOR"]):
        self.node.data_type = value

    @property
    def domain(
        self,
    ) -> Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"]:
        return self.node.domain

    @domain.setter
    def domain(
        self,
        value: Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"],
    ):
        self.node.domain = value

    class _FieldVarianceDomainFactory:
        def __init__(self, domain: _AttributeDomains):
            self._domain = domain

        def float(
            self, value: InputFloat = None, group_index: InputInteger = 0
        ) -> "FieldVariance[FloatSocket]":
            """Create 'FieldVariance' on this domain with 'FLOAT' data type."""
            return FieldVariance(
                value, group_index, domain=self._domain, data_type="FLOAT"
            )

        def vector(
            self, value: InputVector = None, group_index: InputInteger = 0
        ) -> "FieldVariance[VectorSocket]":
            """Create 'FieldVariance' on this domain with 'FLOAT_VECTOR' data type."""
            return FieldVariance(
                value, group_index, domain=self._domain, data_type="FLOAT_VECTOR"
            )

    point = _FieldVarianceDomainFactory("POINT")
    edge = _FieldVarianceDomainFactory("EDGE")
    face = _FieldVarianceDomainFactory("FACE")
    corner = _FieldVarianceDomainFactory("CORNER")
    spline = _FieldVarianceDomainFactory("CURVE")
    instance = _FieldVarianceDomainFactory("INSTANCE")
    layer = _FieldVarianceDomainFactory("LAYER")


class FieldToList(_FieldToListMixin, BaseNode):
    """
    Create a list of values

    Parameters
    ----------
    count : InputInteger
        Count

    Inputs
    ------
    i.count : IntegerSocket
        Count
    """

    _bl_idname = "GeometryNodeFieldToList"
    node: bpy.types.GeometryNodeFieldToList

    class _Inputs(SocketAccessor):
        count: IntegerSocket
        """Count"""

    class _Outputs(SocketAccessor):
        pass

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...


class FilterList(BaseNode, Generic[_T]):
    """
    Remove items from a list

    Parameters
    ----------
    list : InputFloat
        List
    selection : InputBoolean
        Selection

    Inputs
    ------
    i.list : FloatSocket
        List
    i.selection : BooleanSocket
        Selection

    Outputs
    -------
    o.selection : FloatSocket
        Selection
    o.inverted : FloatSocket
        Inverted
    """

    _bl_idname = "GeometryNodeFilterList"
    node: bpy.types.GeometryNodeFilterList  # ty: ignore[unresolved-attribute]

    class _Inputs(SocketAccessor, Generic[_S]):
        list: _S
        """List"""
        selection: BooleanSocket
        """Selection"""

    class _Outputs(SocketAccessor, Generic[_S]):
        selection: _S
        """Selection"""
        inverted: _S
        """Inverted"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        list: InputAny = 0.0,
        selection: InputBoolean = True,
        *,
        socket_type: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ] = "FLOAT",
    ):
        super().__init__()
        key_args = {"List": list, "Selection": selection}
        self.socket_type = socket_type
        self._establish_links(**key_args)

    @classmethod
    def float(
        cls, list: InputFloat = 0.0, selection: InputBoolean = True
    ) -> "FilterList[FloatSocket]":
        """Create Filter List with operation 'Float'."""
        return FilterList(socket_type="FLOAT", list=list, selection=selection)

    @classmethod
    def integer(
        cls, list: InputInteger = 0, selection: InputBoolean = True
    ) -> "FilterList[IntegerSocket]":
        """Create Filter List with operation 'Integer'."""
        return FilterList(socket_type="INT", list=list, selection=selection)

    @classmethod
    def boolean(
        cls, list: InputBoolean = False, selection: InputBoolean = True
    ) -> "FilterList[BooleanSocket]":
        """Create Filter List with operation 'Boolean'."""
        return FilterList(socket_type="BOOLEAN", list=list, selection=selection)

    @classmethod
    def vector(
        cls, list: InputVector = None, selection: InputBoolean = True
    ) -> "FilterList[VectorSocket]":
        """Create Filter List with operation 'Vector'."""
        return FilterList(socket_type="VECTOR", list=list, selection=selection)

    @classmethod
    def color(
        cls, list: InputColor = None, selection: InputBoolean = True
    ) -> "FilterList[ColorSocket]":
        """Create Filter List with operation 'Color'."""
        return FilterList(socket_type="RGBA", list=list, selection=selection)

    @classmethod
    def rotation(
        cls, list: InputRotation = None, selection: InputBoolean = True
    ) -> "FilterList[RotationSocket]":
        """Create Filter List with operation 'Rotation'."""
        return FilterList(socket_type="ROTATION", list=list, selection=selection)

    @classmethod
    def matrix(
        cls, list: InputMatrix = None, selection: InputBoolean = True
    ) -> "FilterList[MatrixSocket]":
        """Create Filter List with operation 'Matrix'."""
        return FilterList(socket_type="MATRIX", list=list, selection=selection)

    @classmethod
    def string(
        cls, list: InputString = "", selection: InputBoolean = True
    ) -> "FilterList[StringSocket]":
        """Create Filter List with operation 'String'."""
        return FilterList(socket_type="STRING", list=list, selection=selection)

    @classmethod
    def menu(
        cls, list: InputMenu = None, selection: InputBoolean = True
    ) -> "FilterList[MenuSocket]":
        """Create Filter List with operation 'Menu'."""
        return FilterList(socket_type="MENU", list=list, selection=selection)

    @classmethod
    def object(
        cls, list: InputObject = None, selection: InputBoolean = True
    ) -> "FilterList[ObjectSocket]":
        """Create Filter List with operation 'Object'."""
        return FilterList(socket_type="OBJECT", list=list, selection=selection)

    @classmethod
    def image(
        cls, list: InputImage = None, selection: InputBoolean = True
    ) -> "FilterList[ImageSocket]":
        """Create Filter List with operation 'Image'."""
        return FilterList(socket_type="IMAGE", list=list, selection=selection)

    @classmethod
    def geometry(
        cls, list: InputGeometry = None, selection: InputBoolean = True
    ) -> "FilterList[GeometrySocket]":
        """Create Filter List with operation 'Geometry'."""
        return FilterList(socket_type="GEOMETRY", list=list, selection=selection)

    @classmethod
    def collection(
        cls, list: InputCollection = None, selection: InputBoolean = True
    ) -> "FilterList[CollectionSocket]":
        """Create Filter List with operation 'Collection'."""
        return FilterList(socket_type="COLLECTION", list=list, selection=selection)

    @classmethod
    def material(
        cls, list: InputMaterial = None, selection: InputBoolean = True
    ) -> "FilterList[MaterialSocket]":
        """Create Filter List with operation 'Material'."""
        return FilterList(socket_type="MATERIAL", list=list, selection=selection)

    @classmethod
    def bundle(
        cls, list: InputBundle = None, selection: InputBoolean = True
    ) -> "FilterList[BundleSocket]":
        """Create Filter List with operation 'Bundle'."""
        return FilterList(socket_type="BUNDLE", list=list, selection=selection)

    @classmethod
    def closure(
        cls, list: InputClosure = None, selection: InputBoolean = True
    ) -> "FilterList[ClosureSocket]":
        """Create Filter List with operation 'Closure'."""
        return FilterList(socket_type="CLOSURE", list=list, selection=selection)

    @classmethod
    def font(
        cls, list: InputFont = None, selection: InputBoolean = True
    ) -> "FilterList[FontSocket]":
        """Create Filter List with operation 'Font'."""
        return FilterList(socket_type="FONT", list=list, selection=selection)

    @classmethod
    def sound(
        cls, list: InputSound = None, selection: InputBoolean = True
    ) -> "FilterList[SoundSocket]":
        """Create Filter List with operation 'Sound'."""
        return FilterList(socket_type="SOUND", list=list, selection=selection)

    @property
    def socket_type(
        self,
    ) -> Literal[
        "FLOAT",
        "INT",
        "BOOLEAN",
        "VECTOR",
        "RGBA",
        "ROTATION",
        "MATRIX",
        "STRING",
        "MENU",
        "OBJECT",
        "IMAGE",
        "GEOMETRY",
        "COLLECTION",
        "MATERIAL",
        "BUNDLE",
        "CLOSURE",
        "FONT",
        "SOUND",
    ]:
        return self.node.socket_type

    @socket_type.setter
    def socket_type(
        self,
        value: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ],
    ):
        self.node.socket_type = value


class FindInString(BaseNode):
    """
    Find the number of times a given string occurs in another string and the position of the first match

    Parameters
    ----------
    string : InputString
        String
    search : InputString
        Search
    mode : InputMenu | Literal['From Start', 'From End']
        Mode

    Inputs
    ------
    i.string : StringSocket
        String
    i.search : StringSocket
        Search
    i.mode : MenuSocket
        Mode

    Outputs
    -------
    o.first_found : IntegerSocket
        First Found
    o.count : IntegerSocket
        Count
    """

    _bl_idname = "FunctionNodeFindInString"
    node: bpy.types.FunctionNodeFindInString

    class _Inputs(SocketAccessor):
        string: StringSocket
        """String"""
        search: StringSocket
        """Search"""
        mode: MenuSocket
        """Mode"""

    class _Outputs(SocketAccessor):
        first_found: IntegerSocket
        """First Found"""
        count: IntegerSocket
        """Count"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        string: InputString = "",
        search: InputString = "",
        mode: InputMenu | Literal["From Start", "From End"] = "From Start",
    ):
        super().__init__()
        key_args = {"String": string, "Search": search, "Mode": mode}

        self._establish_links(**key_args)


class FloatToInteger(BaseNode):
    """
    Convert the given floating-point number to an integer, with a choice of methods

    Parameters
    ----------
    float : InputFloat
        Float

    Inputs
    ------
    i.float : FloatSocket
        Float

    Outputs
    -------
    o.integer : IntegerSocket
        Integer
    """

    _bl_idname = "FunctionNodeFloatToInt"
    node: bpy.types.FunctionNodeFloatToInt

    class _Inputs(SocketAccessor):
        float: FloatSocket
        """Float"""

    class _Outputs(SocketAccessor):
        integer: IntegerSocket
        """Integer"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        float: InputFloat = 0.0,
        *,
        rounding_mode: Literal["ROUND", "FLOOR", "CEILING", "TRUNCATE"] = "ROUND",
    ):
        super().__init__()
        key_args = {"Float": float}
        self.rounding_mode = rounding_mode
        self._establish_links(**key_args)

    @property
    def rounding_mode(self) -> Literal["ROUND", "FLOOR", "CEILING", "TRUNCATE"]:
        return self.node.rounding_mode

    @rounding_mode.setter
    def rounding_mode(self, value: Literal["ROUND", "FLOOR", "CEILING", "TRUNCATE"]):
        self.node.rounding_mode = value


class FormatString(_FormatStringMixin, BaseNode):
    """
    Insert values into a string using a Python and path template compatible formatting syntax

    Parameters
    ----------
    format : InputString
        Format

    Inputs
    ------
    i.format : StringSocket
        Format

    Outputs
    -------
    o.string : StringSocket
        String
    """

    _bl_idname = "FunctionNodeFormatString"
    node: bpy.types.FunctionNodeFormatString

    class _Inputs(SocketAccessor):
        format: StringSocket
        """Format"""

    class _Outputs(SocketAccessor):
        string: StringSocket
        """String"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...


class GetBundleItem(BaseNode, Generic[_T]):
    """
    Retrieve a bundle item by path.

    Parameters
    ----------
    bundle : InputBundle
        Bundle
    path : InputString
        Path
    remove : InputBoolean
        Remove

    Inputs
    ------
    i.bundle : BundleSocket
        Bundle
    i.path : StringSocket
        Path
    i.remove : BooleanSocket
        Remove

    Outputs
    -------
    o.bundle : BundleSocket
        Bundle
    o.item : FloatSocket
        Item
    o.exists : BooleanSocket
        Exists
    """

    _bl_idname = "NodeGetBundleItem"
    node: bpy.types.NodeGetBundleItem

    class _Inputs(SocketAccessor):
        bundle: BundleSocket
        """Bundle"""
        path: StringSocket
        """Path"""
        remove: BooleanSocket
        """Remove"""

    class _Outputs(SocketAccessor, Generic[_S]):
        bundle: BundleSocket
        """Bundle"""
        item: _S
        """Item"""
        exists: BooleanSocket
        """Exists"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
        *,
        socket_type: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ] = "FLOAT",
        structure_type: Literal[
            "AUTO", "DYNAMIC", "FIELD", "GRID", "LIST", "SINGLE"
        ] = "AUTO",
    ):
        super().__init__()
        key_args = {"Bundle": bundle, "Path": path, "Remove": remove}
        self.socket_type = socket_type
        self.structure_type = structure_type
        self._establish_links(**key_args)

    @classmethod
    def float(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[FloatSocket]":
        """Create Get Bundle Item with operation 'Float'."""
        return GetBundleItem(
            socket_type="FLOAT", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def integer(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[IntegerSocket]":
        """Create Get Bundle Item with operation 'Integer'."""
        return GetBundleItem(socket_type="INT", bundle=bundle, path=path, remove=remove)

    @classmethod
    def boolean(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[BooleanSocket]":
        """Create Get Bundle Item with operation 'Boolean'."""
        return GetBundleItem(
            socket_type="BOOLEAN", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def vector(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[VectorSocket]":
        """Create Get Bundle Item with operation 'Vector'."""
        return GetBundleItem(
            socket_type="VECTOR", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def color(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[ColorSocket]":
        """Create Get Bundle Item with operation 'Color'."""
        return GetBundleItem(
            socket_type="RGBA", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def rotation(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[RotationSocket]":
        """Create Get Bundle Item with operation 'Rotation'."""
        return GetBundleItem(
            socket_type="ROTATION", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def matrix(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[MatrixSocket]":
        """Create Get Bundle Item with operation 'Matrix'."""
        return GetBundleItem(
            socket_type="MATRIX", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def string(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[StringSocket]":
        """Create Get Bundle Item with operation 'String'."""
        return GetBundleItem(
            socket_type="STRING", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def menu(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[MenuSocket]":
        """Create Get Bundle Item with operation 'Menu'."""
        return GetBundleItem(
            socket_type="MENU", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def object(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[ObjectSocket]":
        """Create Get Bundle Item with operation 'Object'."""
        return GetBundleItem(
            socket_type="OBJECT", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def image(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[ImageSocket]":
        """Create Get Bundle Item with operation 'Image'."""
        return GetBundleItem(
            socket_type="IMAGE", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def geometry(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[GeometrySocket]":
        """Create Get Bundle Item with operation 'Geometry'."""
        return GetBundleItem(
            socket_type="GEOMETRY", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def collection(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[CollectionSocket]":
        """Create Get Bundle Item with operation 'Collection'."""
        return GetBundleItem(
            socket_type="COLLECTION", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def material(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[MaterialSocket]":
        """Create Get Bundle Item with operation 'Material'."""
        return GetBundleItem(
            socket_type="MATERIAL", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def bundle(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[BundleSocket]":
        """Create Get Bundle Item with operation 'Bundle'."""
        return GetBundleItem(
            socket_type="BUNDLE", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def closure(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[ClosureSocket]":
        """Create Get Bundle Item with operation 'Closure'."""
        return GetBundleItem(
            socket_type="CLOSURE", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def font(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[FontSocket]":
        """Create Get Bundle Item with operation 'Font'."""
        return GetBundleItem(
            socket_type="FONT", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def sound(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[SoundSocket]":
        """Create Get Bundle Item with operation 'Sound'."""
        return GetBundleItem(
            socket_type="SOUND", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def auto(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[FloatSocket]":
        """Create Get Bundle Item with operation 'Auto'. Automatically detect a good structure type based on how the socket is used"""
        return GetBundleItem(
            structure_type="AUTO", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def dynamic(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[FloatSocket]":
        """Create Get Bundle Item with operation 'Dynamic'. Socket can work with different kinds of structures"""
        return GetBundleItem(
            structure_type="DYNAMIC", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def field(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[FloatSocket]":
        """Create Get Bundle Item with operation 'Field'. Socket expects a field"""
        return GetBundleItem(
            structure_type="FIELD", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def grid(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[FloatSocket]":
        """Create Get Bundle Item with operation 'Grid'. Socket expects a grid"""
        return GetBundleItem(
            structure_type="GRID", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def list(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[FloatSocket]":
        """Create Get Bundle Item with operation 'List'. Socket expects a list"""
        return GetBundleItem(
            structure_type="LIST", bundle=bundle, path=path, remove=remove
        )

    @classmethod
    def single(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        remove: InputBoolean = False,
    ) -> "GetBundleItem[FloatSocket]":
        """Create Get Bundle Item with operation 'Single'. Socket expects a single value"""
        return GetBundleItem(
            structure_type="SINGLE", bundle=bundle, path=path, remove=remove
        )

    @property
    def socket_type(
        self,
    ) -> Literal[
        "FLOAT",
        "INT",
        "BOOLEAN",
        "VECTOR",
        "RGBA",
        "ROTATION",
        "MATRIX",
        "STRING",
        "MENU",
        "OBJECT",
        "IMAGE",
        "GEOMETRY",
        "COLLECTION",
        "MATERIAL",
        "BUNDLE",
        "CLOSURE",
        "FONT",
        "SOUND",
    ]:
        return self.node.socket_type  # ty: ignore[invalid-return-type]

    @socket_type.setter
    def socket_type(
        self,
        value: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ],
    ):
        self.node.socket_type = value

    @property
    def structure_type(
        self,
    ) -> Literal["AUTO", "DYNAMIC", "FIELD", "GRID", "LIST", "SINGLE"]:
        return self.node.structure_type

    @structure_type.setter
    def structure_type(
        self, value: Literal["AUTO", "DYNAMIC", "FIELD", "GRID", "LIST", "SINGLE"]
    ):
        self.node.structure_type = value


class GetListItem(BaseNode, Generic[_T]):
    """
    Retrieve a value from a list

    Parameters
    ----------
    list : InputFloat
        List
    index : InputInteger
        Index

    Inputs
    ------
    i.list : FloatSocket
        List
    i.index : IntegerSocket
        Index

    Outputs
    -------
    o.value : FloatSocket
        Value
    """

    _bl_idname = "GeometryNodeListGetItem"
    node: bpy.types.GeometryNodeListGetItem

    class _Inputs(SocketAccessor, Generic[_S]):
        list: _S
        """List"""
        index: IntegerSocket
        """Index"""

    class _Outputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        list: InputAny = 0.0,
        index: InputInteger = 0,
        *,
        socket_type: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ] = "FLOAT",
        structure_type: Literal[
            "AUTO", "DYNAMIC", "FIELD", "GRID", "LIST", "SINGLE"
        ] = "AUTO",
    ):
        super().__init__()
        key_args = {"List": list, "Index": index}
        self.socket_type = socket_type
        self.structure_type = structure_type
        self._establish_links(**key_args)

    @classmethod
    def float(
        cls, list: InputFloat = 0.0, index: InputInteger = 0
    ) -> "GetListItem[FloatSocket]":
        """Create Get List Item with operation 'Float'."""
        return GetListItem(socket_type="FLOAT", list=list, index=index)

    @classmethod
    def integer(
        cls, list: InputInteger = 0, index: InputInteger = 0
    ) -> "GetListItem[IntegerSocket]":
        """Create Get List Item with operation 'Integer'."""
        return GetListItem(socket_type="INT", list=list, index=index)

    @classmethod
    def boolean(
        cls, list: InputBoolean = False, index: InputInteger = 0
    ) -> "GetListItem[BooleanSocket]":
        """Create Get List Item with operation 'Boolean'."""
        return GetListItem(socket_type="BOOLEAN", list=list, index=index)

    @classmethod
    def vector(
        cls, list: InputVector = None, index: InputInteger = 0
    ) -> "GetListItem[VectorSocket]":
        """Create Get List Item with operation 'Vector'."""
        return GetListItem(socket_type="VECTOR", list=list, index=index)

    @classmethod
    def color(
        cls, list: InputColor = None, index: InputInteger = 0
    ) -> "GetListItem[ColorSocket]":
        """Create Get List Item with operation 'Color'."""
        return GetListItem(socket_type="RGBA", list=list, index=index)

    @classmethod
    def rotation(
        cls, list: InputRotation = None, index: InputInteger = 0
    ) -> "GetListItem[RotationSocket]":
        """Create Get List Item with operation 'Rotation'."""
        return GetListItem(socket_type="ROTATION", list=list, index=index)

    @classmethod
    def matrix(
        cls, list: InputMatrix = None, index: InputInteger = 0
    ) -> "GetListItem[MatrixSocket]":
        """Create Get List Item with operation 'Matrix'."""
        return GetListItem(socket_type="MATRIX", list=list, index=index)

    @classmethod
    def string(
        cls, list: InputString = "", index: InputInteger = 0
    ) -> "GetListItem[StringSocket]":
        """Create Get List Item with operation 'String'."""
        return GetListItem(socket_type="STRING", list=list, index=index)

    @classmethod
    def menu(
        cls, list: InputMenu = None, index: InputInteger = 0
    ) -> "GetListItem[MenuSocket]":
        """Create Get List Item with operation 'Menu'."""
        return GetListItem(socket_type="MENU", list=list, index=index)

    @classmethod
    def object(
        cls, list: InputObject = None, index: InputInteger = 0
    ) -> "GetListItem[ObjectSocket]":
        """Create Get List Item with operation 'Object'."""
        return GetListItem(socket_type="OBJECT", list=list, index=index)

    @classmethod
    def image(
        cls, list: InputImage = None, index: InputInteger = 0
    ) -> "GetListItem[ImageSocket]":
        """Create Get List Item with operation 'Image'."""
        return GetListItem(socket_type="IMAGE", list=list, index=index)

    @classmethod
    def geometry(
        cls, list: InputGeometry = None, index: InputInteger = 0
    ) -> "GetListItem[GeometrySocket]":
        """Create Get List Item with operation 'Geometry'."""
        return GetListItem(socket_type="GEOMETRY", list=list, index=index)

    @classmethod
    def collection(
        cls, list: InputCollection = None, index: InputInteger = 0
    ) -> "GetListItem[CollectionSocket]":
        """Create Get List Item with operation 'Collection'."""
        return GetListItem(socket_type="COLLECTION", list=list, index=index)

    @classmethod
    def material(
        cls, list: InputMaterial = None, index: InputInteger = 0
    ) -> "GetListItem[MaterialSocket]":
        """Create Get List Item with operation 'Material'."""
        return GetListItem(socket_type="MATERIAL", list=list, index=index)

    @classmethod
    def bundle(
        cls, list: InputBundle = None, index: InputInteger = 0
    ) -> "GetListItem[BundleSocket]":
        """Create Get List Item with operation 'Bundle'."""
        return GetListItem(socket_type="BUNDLE", list=list, index=index)

    @classmethod
    def closure(
        cls, list: InputClosure = None, index: InputInteger = 0
    ) -> "GetListItem[ClosureSocket]":
        """Create Get List Item with operation 'Closure'."""
        return GetListItem(socket_type="CLOSURE", list=list, index=index)

    @classmethod
    def font(
        cls, list: InputFont = None, index: InputInteger = 0
    ) -> "GetListItem[FontSocket]":
        """Create Get List Item with operation 'Font'."""
        return GetListItem(socket_type="FONT", list=list, index=index)

    @classmethod
    def sound(
        cls, list: InputSound = None, index: InputInteger = 0
    ) -> "GetListItem[SoundSocket]":
        """Create Get List Item with operation 'Sound'."""
        return GetListItem(socket_type="SOUND", list=list, index=index)

    @classmethod
    def auto(
        cls, list: InputFloat = 0.0, index: InputInteger = 0
    ) -> "GetListItem[FloatSocket]":
        """Create Get List Item with operation 'Auto'. Automatically detect a good structure type based on how the socket is used"""
        return GetListItem(structure_type="AUTO", list=list, index=index)

    @classmethod
    def dynamic(
        cls, list: InputFloat = 0.0, index: InputInteger = 0
    ) -> "GetListItem[FloatSocket]":
        """Create Get List Item with operation 'Dynamic'. Socket can work with different kinds of structures"""
        return GetListItem(structure_type="DYNAMIC", list=list, index=index)

    @classmethod
    def field(
        cls, list: InputFloat = 0.0, index: InputInteger = 0
    ) -> "GetListItem[FloatSocket]":
        """Create Get List Item with operation 'Field'. Socket expects a field"""
        return GetListItem(structure_type="FIELD", list=list, index=index)

    @classmethod
    def grid(
        cls, list: InputFloat = 0.0, index: InputInteger = 0
    ) -> "GetListItem[FloatSocket]":
        """Create Get List Item with operation 'Grid'. Socket expects a grid"""
        return GetListItem(structure_type="GRID", list=list, index=index)

    @classmethod
    def list(
        cls, list: InputFloat = 0.0, index: InputInteger = 0
    ) -> "GetListItem[FloatSocket]":
        """Create Get List Item with operation 'List'. Socket expects a list"""
        return GetListItem(structure_type="LIST", list=list, index=index)

    @classmethod
    def single(
        cls, list: InputFloat = 0.0, index: InputInteger = 0
    ) -> "GetListItem[FloatSocket]":
        """Create Get List Item with operation 'Single'. Socket expects a single value"""
        return GetListItem(structure_type="SINGLE", list=list, index=index)

    @property
    def socket_type(
        self,
    ) -> Literal[
        "FLOAT",
        "INT",
        "BOOLEAN",
        "VECTOR",
        "RGBA",
        "ROTATION",
        "MATRIX",
        "STRING",
        "MENU",
        "OBJECT",
        "IMAGE",
        "GEOMETRY",
        "COLLECTION",
        "MATERIAL",
        "BUNDLE",
        "CLOSURE",
        "FONT",
        "SOUND",
    ]:
        return self.node.socket_type  # ty: ignore[invalid-return-type]

    @socket_type.setter
    def socket_type(
        self,
        value: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ],
    ):
        self.node.socket_type = value

    @property
    def structure_type(
        self,
    ) -> Literal["AUTO", "DYNAMIC", "FIELD", "GRID", "LIST", "SINGLE"]:
        return self.node.structure_type

    @structure_type.setter
    def structure_type(
        self, value: Literal["AUTO", "DYNAMIC", "FIELD", "GRID", "LIST", "SINGLE"]
    ):
        self.node.structure_type = value


class GetNestedBundlePaths(BaseNode):
    """
    Get paths to items in a nested bundle with a filter

    Parameters
    ----------
    bundle : InputBundle
        Bundle
    mode : InputMenu | Literal['All', 'Bundle Type', 'Data Type']
        Mode
    pattern_mode : InputMenu | Literal['Exact', 'Wildcard']
        Pattern Mode
    bundle_type : InputString
        Bundle Type
    data_type : InputMenu | Literal['Float', 'Integer', 'Boolean', 'Vector', 'Color', 'Rotation', 'Matrix', 'String', 'Menu', 'Object', 'Image', 'Geometry', 'Collection', 'Material', 'Bundle', 'Closure', 'Font', 'Sound']
        Data Type

    Inputs
    ------
    i.bundle : BundleSocket
        Bundle
    i.mode : MenuSocket
        Mode
    i.pattern_mode : MenuSocket
        Pattern Mode
    i.bundle_type : StringSocket
        Bundle Type
    i.data_type : MenuSocket
        Data Type

    Outputs
    -------
    o.paths : StringSocket
        Paths
    """

    _bl_idname = "NodeGetNestedBundlePaths"
    node: bpy.types.NodeGetNestedBundlePaths  # ty: ignore[unresolved-attribute]

    class _Inputs(SocketAccessor):
        bundle: BundleSocket
        """Bundle"""
        mode: MenuSocket
        """Mode"""
        pattern_mode: MenuSocket
        """Pattern Mode"""
        bundle_type: StringSocket
        """Bundle Type"""
        data_type: MenuSocket
        """Data Type"""

    class _Outputs(SocketAccessor):
        paths: StringSocketList
        """Paths"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        bundle: InputBundle = None,
        mode: InputMenu | Literal["All", "Bundle Type", "Data Type"] = "All",
        pattern_mode: InputMenu | Literal["Exact", "Wildcard"] = "Exact",
        bundle_type: InputString = "",
        data_type: InputMenu
        | Literal[
            "Float",
            "Integer",
            "Boolean",
            "Vector",
            "Color",
            "Rotation",
            "Matrix",
            "String",
            "Menu",
            "Object",
            "Image",
            "Geometry",
            "Collection",
            "Material",
            "Bundle",
            "Closure",
            "Font",
            "Sound",
        ] = "Float",
    ):
        super().__init__()
        key_args = {
            "Bundle": bundle,
            "Mode": mode,
            "Pattern Mode": pattern_mode,
            "Bundle Type": bundle_type,
            "Data Type": data_type,
        }

        self._establish_links(**key_args)


class HashValue(BaseNode, Generic[_T]):
    """
    Generate a randomized integer using the given input value as a seed

    Parameters
    ----------
    value : InputInteger
        Value
    seed : InputInteger
        Seed

    Inputs
    ------
    i.value : IntegerSocket
        Value
    i.seed : IntegerSocket
        Seed

    Outputs
    -------
    o.hash : IntegerSocket
        Hash
    """

    _bl_idname = "FunctionNodeHashValue"
    node: bpy.types.FunctionNodeHashValue

    class _Inputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""
        seed: IntegerSocket
        """Seed"""

    class _Outputs(SocketAccessor):
        hash: IntegerSocket
        """Hash"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        value: InputAny = 0,
        seed: InputInteger = 0,
        *,
        data_type: Literal[
            "FLOAT", "INT", "VECTOR", "RGBA", "ROTATION", "MATRIX", "STRING"
        ] = "INT",
    ):
        super().__init__()
        key_args = {"Value": value, "Seed": seed}
        self.data_type = data_type
        self._establish_links(**key_args)

    @classmethod
    def float(
        cls, value: InputFloat = 0.0, seed: InputInteger = 0
    ) -> "HashValue[FloatSocket]":
        """Create Hash Value with operation 'Float'."""
        return HashValue(data_type="FLOAT", value=value, seed=seed)

    @classmethod
    def integer(
        cls, value: InputInteger = 0, seed: InputInteger = 0
    ) -> "HashValue[IntegerSocket]":
        """Create Hash Value with operation 'Integer'."""
        return HashValue(data_type="INT", value=value, seed=seed)

    @classmethod
    def vector(
        cls, value: InputVector = None, seed: InputInteger = 0
    ) -> "HashValue[VectorSocket]":
        """Create Hash Value with operation 'Vector'."""
        return HashValue(data_type="VECTOR", value=value, seed=seed)

    @classmethod
    def color(
        cls, value: InputColor = None, seed: InputInteger = 0
    ) -> "HashValue[ColorSocket]":
        """Create Hash Value with operation 'Color'."""
        return HashValue(data_type="RGBA", value=value, seed=seed)

    @classmethod
    def rotation(
        cls, value: InputRotation = None, seed: InputInteger = 0
    ) -> "HashValue[RotationSocket]":
        """Create Hash Value with operation 'Rotation'."""
        return HashValue(data_type="ROTATION", value=value, seed=seed)

    @classmethod
    def matrix(
        cls, value: InputMatrix = None, seed: InputInteger = 0
    ) -> "HashValue[MatrixSocket]":
        """Create Hash Value with operation 'Matrix'."""
        return HashValue(data_type="MATRIX", value=value, seed=seed)

    @classmethod
    def string(
        cls, value: InputString = "", seed: InputInteger = 0
    ) -> "HashValue[StringSocket]":
        """Create Hash Value with operation 'String'."""
        return HashValue(data_type="STRING", value=value, seed=seed)

    @property
    def data_type(
        self,
    ) -> Literal["FLOAT", "INT", "VECTOR", "RGBA", "ROTATION", "MATRIX", "STRING"]:
        return self.node.data_type  # ty: ignore[invalid-return-type]

    @data_type.setter
    def data_type(
        self,
        value: Literal[
            "FLOAT", "INT", "VECTOR", "RGBA", "ROTATION", "MATRIX", "STRING"
        ],
    ):
        self.node.data_type = value


class ImplicitConversion(BaseNode, Generic[_T]):
    """
    Implicitly convert the input value to a fixed socket type

    Parameters
    ----------
    value : InputColor
        Value

    Inputs
    ------
    i.value : ColorSocket
        Value

    Outputs
    -------
    o.value : ColorSocket
        Value
    """

    _bl_idname = "NodeImplicitConversion"
    node: bpy.types.NodeImplicitConversion

    class _Inputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""

    class _Outputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        value: InputAny = None,
        *,
        data_type: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ] = "RGBA",
    ):
        super().__init__()
        key_args = {"Value": value}
        self.data_type = data_type
        self._establish_links(**key_args)

    @classmethod
    def float(cls, value: InputFloat = 0.0) -> "ImplicitConversion[FloatSocket]":
        """Create Implicit Conversion with operation 'Float'."""
        return ImplicitConversion(data_type="FLOAT", value=value)

    @classmethod
    def integer(cls, value: InputInteger = 0) -> "ImplicitConversion[IntegerSocket]":
        """Create Implicit Conversion with operation 'Integer'."""
        return ImplicitConversion(data_type="INT", value=value)

    @classmethod
    def boolean(
        cls, value: InputBoolean = False
    ) -> "ImplicitConversion[BooleanSocket]":
        """Create Implicit Conversion with operation 'Boolean'."""
        return ImplicitConversion(data_type="BOOLEAN", value=value)

    @classmethod
    def vector(cls, value: InputVector = None) -> "ImplicitConversion[VectorSocket]":
        """Create Implicit Conversion with operation 'Vector'."""
        return ImplicitConversion(data_type="VECTOR", value=value)

    @classmethod
    def color(cls, value: InputColor = None) -> "ImplicitConversion[ColorSocket]":
        """Create Implicit Conversion with operation 'Color'."""
        return ImplicitConversion(data_type="RGBA", value=value)

    @classmethod
    def rotation(
        cls, value: InputRotation = None
    ) -> "ImplicitConversion[RotationSocket]":
        """Create Implicit Conversion with operation 'Rotation'."""
        return ImplicitConversion(data_type="ROTATION", value=value)

    @classmethod
    def matrix(cls, value: InputMatrix = None) -> "ImplicitConversion[MatrixSocket]":
        """Create Implicit Conversion with operation 'Matrix'."""
        return ImplicitConversion(data_type="MATRIX", value=value)

    @classmethod
    def string(cls, value: InputString = "") -> "ImplicitConversion[StringSocket]":
        """Create Implicit Conversion with operation 'String'."""
        return ImplicitConversion(data_type="STRING", value=value)

    @classmethod
    def menu(cls, value: InputMenu = None) -> "ImplicitConversion[MenuSocket]":
        """Create Implicit Conversion with operation 'Menu'."""
        return ImplicitConversion(data_type="MENU", value=value)

    @classmethod
    def object(cls, value: InputObject = None) -> "ImplicitConversion[ObjectSocket]":
        """Create Implicit Conversion with operation 'Object'."""
        return ImplicitConversion(data_type="OBJECT", value=value)

    @classmethod
    def image(cls, value: InputImage = None) -> "ImplicitConversion[ImageSocket]":
        """Create Implicit Conversion with operation 'Image'."""
        return ImplicitConversion(data_type="IMAGE", value=value)

    @classmethod
    def geometry(
        cls, value: InputGeometry = None
    ) -> "ImplicitConversion[GeometrySocket]":
        """Create Implicit Conversion with operation 'Geometry'."""
        return ImplicitConversion(data_type="GEOMETRY", value=value)

    @classmethod
    def collection(
        cls, value: InputCollection = None
    ) -> "ImplicitConversion[CollectionSocket]":
        """Create Implicit Conversion with operation 'Collection'."""
        return ImplicitConversion(data_type="COLLECTION", value=value)

    @classmethod
    def material(
        cls, value: InputMaterial = None
    ) -> "ImplicitConversion[MaterialSocket]":
        """Create Implicit Conversion with operation 'Material'."""
        return ImplicitConversion(data_type="MATERIAL", value=value)

    @classmethod
    def bundle(cls, value: InputBundle = None) -> "ImplicitConversion[BundleSocket]":
        """Create Implicit Conversion with operation 'Bundle'."""
        return ImplicitConversion(data_type="BUNDLE", value=value)

    @classmethod
    def closure(cls, value: InputClosure = None) -> "ImplicitConversion[ClosureSocket]":
        """Create Implicit Conversion with operation 'Closure'."""
        return ImplicitConversion(data_type="CLOSURE", value=value)

    @classmethod
    def font(cls, value: InputFont = None) -> "ImplicitConversion[FontSocket]":
        """Create Implicit Conversion with operation 'Font'."""
        return ImplicitConversion(data_type="FONT", value=value)

    @classmethod
    def sound(cls, value: InputSound = None) -> "ImplicitConversion[SoundSocket]":
        """Create Implicit Conversion with operation 'Sound'."""
        return ImplicitConversion(data_type="SOUND", value=value)

    @property
    def data_type(
        self,
    ) -> Literal[
        "FLOAT",
        "INT",
        "BOOLEAN",
        "VECTOR",
        "RGBA",
        "ROTATION",
        "MATRIX",
        "STRING",
        "MENU",
        "OBJECT",
        "IMAGE",
        "GEOMETRY",
        "COLLECTION",
        "MATERIAL",
        "BUNDLE",
        "CLOSURE",
        "FONT",
        "SOUND",
    ]:
        return self.node.data_type  # ty: ignore[invalid-return-type]

    @data_type.setter
    def data_type(
        self,
        value: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ],
    ):
        self.node.data_type = value


class IndexOfNearest(BaseNode):
    """
    Find the nearest element in a group. Similar to the "Sample Nearest" node

    Parameters
    ----------
    position : InputVector
        Position
    group_id : InputInteger
        Group ID

    Inputs
    ------
    i.position : VectorSocket
        Position
    i.group_id : IntegerSocket
        Group ID

    Outputs
    -------
    o.index : IntegerSocket
        Index
    o.has_neighbor : BooleanSocket
        Has Neighbor
    """

    _bl_idname = "GeometryNodeIndexOfNearest"
    node: bpy.types.GeometryNodeIndexOfNearest

    class _Inputs(SocketAccessor):
        position: VectorSocket
        """Position"""
        group_id: IntegerSocket
        """Group ID"""

    class _Outputs(SocketAccessor):
        index: IntegerSocket
        """Index"""
        has_neighbor: BooleanSocket
        """Has Neighbor"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        position: InputVector = None,
        group_id: InputInteger = 0,
    ):
        super().__init__()
        key_args = {"Position": position, "Group ID": group_id}

        self._establish_links(**key_args)


class IntegerMath(BaseNode):
    """
    Perform various math operations on the given integer inputs

    Parameters
    ----------
    value : InputInteger
        Value
    value_001 : InputInteger
        Value
    value_002 : InputInteger
        Value

    Inputs
    ------
    i.value : IntegerSocket
        Value
    i.value_001 : IntegerSocket
        Value
    i.value_002 : IntegerSocket
        Value

    Outputs
    -------
    o.value : IntegerSocket
        Value
    """

    _bl_idname = "FunctionNodeIntegerMath"
    node: bpy.types.FunctionNodeIntegerMath

    class _Inputs(SocketAccessor):
        value: IntegerSocket
        """Value"""
        value_001: IntegerSocket
        """Value"""
        value_002: IntegerSocket
        """Value"""

    class _Outputs(SocketAccessor):
        value: IntegerSocket
        """Value"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        value: InputInteger = 0,
        value_001: InputInteger = 0,
        value_002: InputInteger = 0,
        *,
        operation: Literal[
            "ADD",
            "SUBTRACT",
            "MULTIPLY",
            "DIVIDE",
            "MULTIPLY_ADD",
            "ABSOLUTE",
            "NEGATE",
            "POWER",
            "MINIMUM",
            "MAXIMUM",
            "SIGN",
            "DIVIDE_ROUND",
            "DIVIDE_FLOOR",
            "DIVIDE_CEIL",
            "FLOORED_MODULO",
            "MODULO",
            "GCD",
            "LCM",
        ] = "ADD",
    ):
        super().__init__()
        key_args = {"Value": value, "Value_001": value_001, "Value_002": value_002}
        self.operation = operation
        self._establish_links(**key_args)

    @classmethod
    def add(cls, value: InputInteger = 0, value_001: InputInteger = 0) -> "IntegerMath":
        """Create Integer Math with operation 'Add'. A + B"""
        return cls(operation="ADD", value=value, value_001=value_001)

    @classmethod
    def subtract(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Subtract'. A - B"""
        return cls(operation="SUBTRACT", value=value, value_001=value_001)

    @classmethod
    def multiply(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Multiply'. A * B"""
        return cls(operation="MULTIPLY", value=value, value_001=value_001)

    @classmethod
    def divide(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Divide'. A / B"""
        return cls(operation="DIVIDE", value=value, value_001=value_001)

    @classmethod
    def multiply_add(
        cls,
        value: InputInteger = 0,
        value_001: InputInteger = 0,
        value_002: InputInteger = 0,
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Multiply Add'. A * B + C"""
        return cls(
            operation="MULTIPLY_ADD",
            value=value,
            value_001=value_001,
            value_002=value_002,
        )

    @classmethod
    def absolute(cls, value: InputInteger = 0) -> "IntegerMath":
        """Create Integer Math with operation 'Absolute'. Non-negative value of A, abs(A)"""
        return cls(operation="ABSOLUTE", value=value)

    @classmethod
    def negate(cls, value: InputInteger = 0) -> "IntegerMath":
        """Create Integer Math with operation 'Negate'. -A"""
        return cls(operation="NEGATE", value=value)

    @classmethod
    def power(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Power'. A power B, pow(A,B)"""
        return cls(operation="POWER", value=value, value_001=value_001)

    @classmethod
    def minimum(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Minimum'. The minimum value from A and B, min(A,B)"""
        return cls(operation="MINIMUM", value=value, value_001=value_001)

    @classmethod
    def maximum(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Maximum'. The maximum value from A and B, max(A,B)"""
        return cls(operation="MAXIMUM", value=value, value_001=value_001)

    @classmethod
    def sign(cls, value: InputInteger = 0) -> "IntegerMath":
        """Create Integer Math with operation 'Sign'. Return the sign of A, sign(A)"""
        return cls(operation="SIGN", value=value)

    @classmethod
    def divide_round(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Divide Round'. Divide and round result toward zero"""
        return cls(operation="DIVIDE_ROUND", value=value, value_001=value_001)

    @classmethod
    def divide_floor(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Divide Floor'. Divide and floor to the largest integer smaller than or equal to the result"""
        return cls(operation="DIVIDE_FLOOR", value=value, value_001=value_001)

    @classmethod
    def divide_ceiling(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Divide Ceiling'. Divide and ceil to the smallest integer greater than or equal to the result"""
        return cls(operation="DIVIDE_CEIL", value=value, value_001=value_001)

    @classmethod
    def floored_modulo(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Floored Modulo'. Modulo that is periodic for both negative and positive operands"""
        return cls(operation="FLOORED_MODULO", value=value, value_001=value_001)

    @classmethod
    def modulo(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Modulo'. Modulo which is the remainder of A / B"""
        return cls(operation="MODULO", value=value, value_001=value_001)

    @classmethod
    def greatest_common_divisor(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Greatest Common Divisor'. The largest positive integer that divides into each of the values A and B, e.g. GCD(8,12) = 4"""
        return cls(operation="GCD", value=value, value_001=value_001)

    @classmethod
    def least_common_multiple(
        cls, value: InputInteger = 0, value_001: InputInteger = 0
    ) -> "IntegerMath":
        """Create Integer Math with operation 'Least Common Multiple'. The smallest positive integer that is divisible by both A and B, e.g. LCM(6,10) = 30"""
        return cls(operation="LCM", value=value, value_001=value_001)

    @property
    def operation(
        self,
    ) -> Literal[
        "ADD",
        "SUBTRACT",
        "MULTIPLY",
        "DIVIDE",
        "MULTIPLY_ADD",
        "ABSOLUTE",
        "NEGATE",
        "POWER",
        "MINIMUM",
        "MAXIMUM",
        "SIGN",
        "DIVIDE_ROUND",
        "DIVIDE_FLOOR",
        "DIVIDE_CEIL",
        "FLOORED_MODULO",
        "MODULO",
        "GCD",
        "LCM",
    ]:
        return self.node.operation

    @operation.setter
    def operation(
        self,
        value: Literal[
            "ADD",
            "SUBTRACT",
            "MULTIPLY",
            "DIVIDE",
            "MULTIPLY_ADD",
            "ABSOLUTE",
            "NEGATE",
            "POWER",
            "MINIMUM",
            "MAXIMUM",
            "SIGN",
            "DIVIDE_ROUND",
            "DIVIDE_FLOOR",
            "DIVIDE_CEIL",
            "FLOORED_MODULO",
            "MODULO",
            "GCD",
            "LCM",
        ],
    ):
        self.node.operation = value


class InvertMatrix(BaseNode):
    """
    Compute the inverse of the given matrix, if one exists

    Parameters
    ----------
    matrix : InputMatrix
        Matrix

    Inputs
    ------
    i.matrix : MatrixSocket
        Matrix

    Outputs
    -------
    o.matrix : MatrixSocket
        Matrix
    o.invertible : BooleanSocket
        Invertible
    """

    _bl_idname = "FunctionNodeInvertMatrix"
    node: bpy.types.FunctionNodeInvertMatrix

    class _Inputs(SocketAccessor):
        matrix: MatrixSocket
        """Matrix"""

    class _Outputs(SocketAccessor):
        matrix: MatrixSocket
        """Matrix"""
        invertible: BooleanSocket
        """Invertible"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, matrix: InputMatrix = None):
        super().__init__()
        key_args = {"Matrix": matrix}

        self._establish_links(**key_args)


class InvertRotation(BaseNode):
    """
    Compute the inverse of the given rotation

    Parameters
    ----------
    rotation : InputRotation
        Rotation

    Inputs
    ------
    i.rotation : RotationSocket
        Rotation

    Outputs
    -------
    o.rotation : RotationSocket
        Rotation
    """

    _bl_idname = "FunctionNodeInvertRotation"
    node: bpy.types.FunctionNodeInvertRotation

    class _Inputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    class _Outputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, rotation: InputRotation = None):
        super().__init__()
        key_args = {"Rotation": rotation}

        self._establish_links(**key_args)


class JoinBundle(BaseNode):
    """
    Join multiple bundles together

    Parameters
    ----------
    bundle : InputBundle
        Bundle

    Inputs
    ------
    i.bundle : BundleSocket
        Bundle

    Outputs
    -------
    o.bundle : BundleSocket
        Bundle
    """

    _bl_idname = "NodeJoinBundle"
    node: bpy.types.NodeJoinBundle

    class _Inputs(SocketAccessor):
        bundle: BundleSocket
        """Bundle"""

    class _Outputs(SocketAccessor):
        bundle: BundleSocket
        """Bundle"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, bundle: InputBundle = None):
        super().__init__()
        key_args = {"Bundle": bundle}

        self._establish_links(**key_args)


class ListLength(BaseNode, Generic[_T]):
    """
    Count how many items are in a given list

    Parameters
    ----------
    list : InputFloat
        List

    Inputs
    ------
    i.list : FloatSocket
        List

    Outputs
    -------
    o.length : IntegerSocket
        Length
    """

    _bl_idname = "GeometryNodeListLength"
    node: bpy.types.GeometryNodeListLength

    class _Inputs(SocketAccessor, Generic[_S]):
        list: _S
        """List"""

    class _Outputs(SocketAccessor):
        length: IntegerSocket
        """Length"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        list: InputAny = 0.0,
        *,
        data_type: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ] = "FLOAT",
    ):
        super().__init__()
        key_args = {"List": list}
        self.data_type = data_type
        self._establish_links(**key_args)

    @classmethod
    def float(cls, list: InputFloat = 0.0) -> "ListLength[FloatSocket]":
        """Create List Length with operation 'Float'."""
        return ListLength(data_type="FLOAT", list=list)

    @classmethod
    def integer(cls, list: InputInteger = 0) -> "ListLength[IntegerSocket]":
        """Create List Length with operation 'Integer'."""
        return ListLength(data_type="INT", list=list)

    @classmethod
    def boolean(cls, list: InputBoolean = False) -> "ListLength[BooleanSocket]":
        """Create List Length with operation 'Boolean'."""
        return ListLength(data_type="BOOLEAN", list=list)

    @classmethod
    def vector(cls, list: InputVector = None) -> "ListLength[VectorSocket]":
        """Create List Length with operation 'Vector'."""
        return ListLength(data_type="VECTOR", list=list)

    @classmethod
    def color(cls, list: InputColor = None) -> "ListLength[ColorSocket]":
        """Create List Length with operation 'Color'."""
        return ListLength(data_type="RGBA", list=list)

    @classmethod
    def rotation(cls, list: InputRotation = None) -> "ListLength[RotationSocket]":
        """Create List Length with operation 'Rotation'."""
        return ListLength(data_type="ROTATION", list=list)

    @classmethod
    def matrix(cls, list: InputMatrix = None) -> "ListLength[MatrixSocket]":
        """Create List Length with operation 'Matrix'."""
        return ListLength(data_type="MATRIX", list=list)

    @classmethod
    def string(cls, list: InputString = "") -> "ListLength[StringSocket]":
        """Create List Length with operation 'String'."""
        return ListLength(data_type="STRING", list=list)

    @classmethod
    def menu(cls, list: InputMenu = None) -> "ListLength[MenuSocket]":
        """Create List Length with operation 'Menu'."""
        return ListLength(data_type="MENU", list=list)

    @classmethod
    def object(cls, list: InputObject = None) -> "ListLength[ObjectSocket]":
        """Create List Length with operation 'Object'."""
        return ListLength(data_type="OBJECT", list=list)

    @classmethod
    def image(cls, list: InputImage = None) -> "ListLength[ImageSocket]":
        """Create List Length with operation 'Image'."""
        return ListLength(data_type="IMAGE", list=list)

    @classmethod
    def geometry(cls, list: InputGeometry = None) -> "ListLength[GeometrySocket]":
        """Create List Length with operation 'Geometry'."""
        return ListLength(data_type="GEOMETRY", list=list)

    @classmethod
    def collection(cls, list: InputCollection = None) -> "ListLength[CollectionSocket]":
        """Create List Length with operation 'Collection'."""
        return ListLength(data_type="COLLECTION", list=list)

    @classmethod
    def material(cls, list: InputMaterial = None) -> "ListLength[MaterialSocket]":
        """Create List Length with operation 'Material'."""
        return ListLength(data_type="MATERIAL", list=list)

    @classmethod
    def bundle(cls, list: InputBundle = None) -> "ListLength[BundleSocket]":
        """Create List Length with operation 'Bundle'."""
        return ListLength(data_type="BUNDLE", list=list)

    @classmethod
    def closure(cls, list: InputClosure = None) -> "ListLength[ClosureSocket]":
        """Create List Length with operation 'Closure'."""
        return ListLength(data_type="CLOSURE", list=list)

    @classmethod
    def font(cls, list: InputFont = None) -> "ListLength[FontSocket]":
        """Create List Length with operation 'Font'."""
        return ListLength(data_type="FONT", list=list)

    @classmethod
    def sound(cls, list: InputSound = None) -> "ListLength[SoundSocket]":
        """Create List Length with operation 'Sound'."""
        return ListLength(data_type="SOUND", list=list)

    @property
    def data_type(
        self,
    ) -> Literal[
        "FLOAT",
        "INT",
        "BOOLEAN",
        "VECTOR",
        "RGBA",
        "ROTATION",
        "MATRIX",
        "STRING",
        "MENU",
        "OBJECT",
        "IMAGE",
        "GEOMETRY",
        "COLLECTION",
        "MATERIAL",
        "BUNDLE",
        "CLOSURE",
        "FONT",
        "SOUND",
    ]:
        return self.node.data_type  # ty: ignore[invalid-return-type]

    @data_type.setter
    def data_type(
        self,
        value: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ],
    ):
        self.node.data_type = value


class MapRange(BaseNode):
    """
    Remap a value from a range to a target range

    Parameters
    ----------
    value : InputFloat
        Value
    from_min : InputFloat
        From Min
    from_max : InputFloat
        From Max
    to_min : InputFloat
        To Min
    to_max : InputFloat
        To Max
    steps : InputFloat
        Steps
    vector : InputVector
        Vector
    from_min_float3 : InputVector
        From Min
    from_max_float3 : InputVector
        From Max
    to_min_float3 : InputVector
        To Min
    to_max_float3 : InputVector
        To Max
    steps_float3 : InputVector
        Steps

    Inputs
    ------
    i.value : FloatSocket
        Value
    i.from_min : FloatSocket
        From Min
    i.from_max : FloatSocket
        From Max
    i.to_min : FloatSocket
        To Min
    i.to_max : FloatSocket
        To Max
    i.steps : FloatSocket
        Steps
    i.vector : VectorSocket
        Vector
    i.from_min_float3 : VectorSocket
        From Min
    i.from_max_float3 : VectorSocket
        From Max
    i.to_min_float3 : VectorSocket
        To Min
    i.to_max_float3 : VectorSocket
        To Max
    i.steps_float3 : VectorSocket
        Steps

    Outputs
    -------
    o.result : FloatSocket
        Result
    o.vector : VectorSocket
        Vector
    """

    _bl_idname = "ShaderNodeMapRange"
    node: bpy.types.ShaderNodeMapRange

    class _Inputs(SocketAccessor):
        value: FloatSocket
        """Value"""
        from_min: FloatSocket
        """From Min"""
        from_max: FloatSocket
        """From Max"""
        to_min: FloatSocket
        """To Min"""
        to_max: FloatSocket
        """To Max"""
        steps: FloatSocket
        """Steps"""
        vector: VectorSocket
        """Vector"""
        from_min_float3: VectorSocket
        """From Min"""
        from_max_float3: VectorSocket
        """From Max"""
        to_min_float3: VectorSocket
        """To Min"""
        to_max_float3: VectorSocket
        """To Max"""
        steps_float3: VectorSocket
        """Steps"""

    class _Outputs(SocketAccessor):
        result: FloatSocket
        """Result"""
        vector: VectorSocket
        """Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        value: InputFloat = 1.0,
        from_min: InputFloat = 0.0,
        from_max: InputFloat = 1.0,
        to_min: InputFloat = 0.0,
        to_max: InputFloat = 1.0,
        steps: InputFloat = 4.0,
        vector: InputVector = None,
        from_min_float3: InputVector = None,
        from_max_float3: InputVector = None,
        to_min_float3: InputVector = None,
        to_max_float3: InputVector = None,
        steps_float3: InputVector = None,
        *,
        clamp: bool = False,
        interpolation_type: Literal[
            "LINEAR", "STEPPED", "SMOOTHSTEP", "SMOOTHERSTEP"
        ] = "LINEAR",
        data_type: Literal["FLOAT", "FLOAT_VECTOR"] = "FLOAT",
    ):
        super().__init__()
        key_args = {
            "Value": value,
            "From Min": from_min,
            "From Max": from_max,
            "To Min": to_min,
            "To Max": to_max,
            "Steps": steps,
            "Vector": vector,
            "From_Min_FLOAT3": from_min_float3,
            "From_Max_FLOAT3": from_max_float3,
            "To_Min_FLOAT3": to_min_float3,
            "To_Max_FLOAT3": to_max_float3,
            "Steps_FLOAT3": steps_float3,
        }
        self.clamp = clamp
        self.interpolation_type = interpolation_type
        self.data_type = data_type
        self._establish_links(**key_args)

    @classmethod
    def linear(
        cls,
        value: InputFloat = 1.0,
        from_min: InputFloat = 0.0,
        from_max: InputFloat = 1.0,
        to_min: InputFloat = 0.0,
        to_max: InputFloat = 1.0,
    ) -> "MapRange":
        """Create Map Range with operation 'Linear'. Linear interpolation between From Min and From Max values"""
        return cls(
            interpolation_type="LINEAR",
            value=value,
            from_min=from_min,
            from_max=from_max,
            to_min=to_min,
            to_max=to_max,
        )

    @classmethod
    def stepped_linear(
        cls,
        value: InputFloat = 1.0,
        from_min: InputFloat = 0.0,
        from_max: InputFloat = 1.0,
        to_min: InputFloat = 0.0,
        to_max: InputFloat = 1.0,
        steps: InputFloat = 4.0,
    ) -> "MapRange":
        """Create Map Range with operation 'Stepped Linear'. Stepped linear interpolation between From Min and From Max values"""
        return cls(
            interpolation_type="STEPPED",
            value=value,
            from_min=from_min,
            from_max=from_max,
            to_min=to_min,
            to_max=to_max,
            steps=steps,
        )

    @classmethod
    def smooth_step(
        cls,
        value: InputFloat = 1.0,
        from_min: InputFloat = 0.0,
        from_max: InputFloat = 1.0,
        to_min: InputFloat = 0.0,
        to_max: InputFloat = 1.0,
    ) -> "MapRange":
        """Create Map Range with operation 'Smooth Step'. Smooth Hermite edge interpolation between From Min and From Max values"""
        return cls(
            interpolation_type="SMOOTHSTEP",
            value=value,
            from_min=from_min,
            from_max=from_max,
            to_min=to_min,
            to_max=to_max,
        )

    @classmethod
    def smoother_step(
        cls,
        value: InputFloat = 1.0,
        from_min: InputFloat = 0.0,
        from_max: InputFloat = 1.0,
        to_min: InputFloat = 0.0,
        to_max: InputFloat = 1.0,
    ) -> "MapRange":
        """Create Map Range with operation 'Smoother Step'. Smoother Hermite edge interpolation between From Min and From Max values"""
        return cls(
            interpolation_type="SMOOTHERSTEP",
            value=value,
            from_min=from_min,
            from_max=from_max,
            to_min=to_min,
            to_max=to_max,
        )

    @classmethod
    def float(
        cls,
        value: InputFloat = 1.0,
        from_min: InputFloat = 0.0,
        from_max: InputFloat = 1.0,
        to_min: InputFloat = 0.0,
        to_max: InputFloat = 1.0,
    ) -> "MapRange":
        """Create Map Range with operation 'Float'. Floating-point value"""
        return cls(
            data_type="FLOAT",
            value=value,
            from_min=from_min,
            from_max=from_max,
            to_min=to_min,
            to_max=to_max,
        )

    @classmethod
    def vector(
        cls,
        vector: InputVector = None,
        from_min3: InputVector = None,
        from_max3: InputVector = None,
        to_min3: InputVector = None,
        to_max3: InputVector = None,
    ) -> "MapRange":
        """Create Map Range with operation 'Vector'. 3D vector with floating-point values"""
        return cls(
            data_type="FLOAT_VECTOR",
            vector=vector,
            from_min_float3=from_min3,
            from_max_float3=from_max3,
            to_min_float3=to_min3,
            to_max_float3=to_max3,
        )

    @property
    def clamp(self) -> bool:
        return self.node.clamp

    @clamp.setter
    def clamp(self, value: bool):
        self.node.clamp = value

    @property
    def interpolation_type(
        self,
    ) -> Literal["LINEAR", "STEPPED", "SMOOTHSTEP", "SMOOTHERSTEP"]:
        return self.node.interpolation_type

    @interpolation_type.setter
    def interpolation_type(
        self, value: Literal["LINEAR", "STEPPED", "SMOOTHSTEP", "SMOOTHERSTEP"]
    ):
        self.node.interpolation_type = value

    @property
    def data_type(self) -> Literal["FLOAT", "FLOAT_VECTOR"]:
        return self.node.data_type

    @data_type.setter
    def data_type(self, value: Literal["FLOAT", "FLOAT_VECTOR"]):
        self.node.data_type = value


class MatchString(BaseNode):
    """
    Check if a given string exists within another string

    Parameters
    ----------
    string : InputString
        String
    operation : InputMenu | Literal['Starts With', 'Ends With', 'Contains']
        Operation
    key : InputString
        Key

    Inputs
    ------
    i.string : StringSocket
        String
    i.operation : MenuSocket
        Operation
    i.key : StringSocket
        Key

    Outputs
    -------
    o.result : BooleanSocket
        Result
    """

    _bl_idname = "FunctionNodeMatchString"
    node: bpy.types.FunctionNodeMatchString

    class _Inputs(SocketAccessor):
        string: StringSocket
        """String"""
        operation: MenuSocket
        """Operation"""
        key: StringSocket
        """Key"""

    class _Outputs(SocketAccessor):
        result: BooleanSocket
        """Result"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        string: InputString = "",
        operation: InputMenu
        | Literal["Starts With", "Ends With", "Contains"] = "Starts With",
        key: InputString = "",
    ):
        super().__init__()
        key_args = {"String": string, "Operation": operation, "Key": key}

        self._establish_links(**key_args)


class Math(BaseNode):
    """
    Perform math operations

    Parameters
    ----------
    value : InputFloat
        Value
    value_001 : InputFloat
        Value
    value_002 : InputFloat
        Value

    Inputs
    ------
    i.value : FloatSocket
        Value
    i.value_001 : FloatSocket
        Value
    i.value_002 : FloatSocket
        Value

    Outputs
    -------
    o.value : FloatSocket
        Value
    """

    _bl_idname = "ShaderNodeMath"
    node: bpy.types.ShaderNodeMath

    class _Inputs(SocketAccessor):
        value: FloatSocket
        """Value"""
        value_001: FloatSocket
        """Value"""
        value_002: FloatSocket
        """Value"""

    class _Outputs(SocketAccessor):
        value: FloatSocket
        """Value"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        value: InputFloat = 0.5,
        value_001: InputFloat = 0.5,
        value_002: InputFloat = 0.5,
        *,
        operation: Literal[
            "ADD",
            "SUBTRACT",
            "MULTIPLY",
            "DIVIDE",
            "MULTIPLY_ADD",
            "POWER",
            "LOGARITHM",
            "SQRT",
            "INVERSE_SQRT",
            "ABSOLUTE",
            "EXPONENT",
            "MINIMUM",
            "MAXIMUM",
            "LESS_THAN",
            "GREATER_THAN",
            "SIGN",
            "COMPARE",
            "SMOOTH_MIN",
            "SMOOTH_MAX",
            "ROUND",
            "FLOOR",
            "CEIL",
            "TRUNC",
            "FRACT",
            "MODULO",
            "FLOORED_MODULO",
            "WRAP",
            "SNAP",
            "PINGPONG",
            "SINE",
            "COSINE",
            "TANGENT",
            "ARCSINE",
            "ARCCOSINE",
            "ARCTANGENT",
            "ARCTAN2",
            "SINH",
            "COSH",
            "TANH",
            "RADIANS",
            "DEGREES",
        ] = "ADD",
        use_clamp: bool = False,
    ):
        super().__init__()
        key_args = {"Value": value, "Value_001": value_001, "Value_002": value_002}
        self.operation = operation
        self.use_clamp = use_clamp
        self._establish_links(**key_args)

    @classmethod
    def add(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Add'. A + B"""
        return cls(operation="ADD", value=value, value_001=value_001)

    @classmethod
    def subtract(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Subtract'. A - B"""
        return cls(operation="SUBTRACT", value=value, value_001=value_001)

    @classmethod
    def multiply(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Multiply'. A * B"""
        return cls(operation="MULTIPLY", value=value, value_001=value_001)

    @classmethod
    def divide(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Divide'. A / B"""
        return cls(operation="DIVIDE", value=value, value_001=value_001)

    @classmethod
    def multiply_add(
        cls,
        value: InputFloat = 0.5,
        value_001: InputFloat = 0.5,
        value_002: InputFloat = 0.5,
    ) -> "Math":
        """Create Math with operation 'Multiply Add'. A * B + C"""
        return cls(
            operation="MULTIPLY_ADD",
            value=value,
            value_001=value_001,
            value_002=value_002,
        )

    @classmethod
    def power(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Power'. A power B"""
        return cls(operation="POWER", value=value, value_001=value_001)

    @classmethod
    def logarithm(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Logarithm'. Logarithm A base B"""
        return cls(operation="LOGARITHM", value=value, value_001=value_001)

    @classmethod
    def square_root(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Square Root'. Square root of A"""
        return cls(operation="SQRT", value=value)

    @classmethod
    def inverse_square_root(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Inverse Square Root'. 1 / Square root of A"""
        return cls(operation="INVERSE_SQRT", value=value)

    @classmethod
    def absolute(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Absolute'. Magnitude of A"""
        return cls(operation="ABSOLUTE", value=value)

    @classmethod
    def exponent(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Exponent'. exp(A)"""
        return cls(operation="EXPONENT", value=value)

    @classmethod
    def minimum(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Minimum'. The minimum from A and B"""
        return cls(operation="MINIMUM", value=value, value_001=value_001)

    @classmethod
    def maximum(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Maximum'. The maximum from A and B"""
        return cls(operation="MAXIMUM", value=value, value_001=value_001)

    @classmethod
    def less_than(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Less Than'. 1 if A < B else 0"""
        return cls(operation="LESS_THAN", value=value, value_001=value_001)

    @classmethod
    def greater_than(
        cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5
    ) -> "Math":
        """Create Math with operation 'Greater Than'. 1 if A > B else 0"""
        return cls(operation="GREATER_THAN", value=value, value_001=value_001)

    @classmethod
    def sign(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Sign'. Returns the sign of A"""
        return cls(operation="SIGN", value=value)

    @classmethod
    def compare(
        cls,
        value: InputFloat = 0.5,
        value_001: InputFloat = 0.5,
        value_002: InputFloat = 0.5,
    ) -> "Math":
        """Create Math with operation 'Compare'. 1 if (A == B) within tolerance C else 0"""
        return cls(
            operation="COMPARE", value=value, value_001=value_001, value_002=value_002
        )

    @classmethod
    def smooth_minimum(
        cls,
        value: InputFloat = 0.5,
        value_001: InputFloat = 0.5,
        value_002: InputFloat = 0.5,
    ) -> "Math":
        """Create Math with operation 'Smooth Minimum'. The minimum from A and B with smoothing C"""
        return cls(
            operation="SMOOTH_MIN",
            value=value,
            value_001=value_001,
            value_002=value_002,
        )

    @classmethod
    def smooth_maximum(
        cls,
        value: InputFloat = 0.5,
        value_001: InputFloat = 0.5,
        value_002: InputFloat = 0.5,
    ) -> "Math":
        """Create Math with operation 'Smooth Maximum'. The maximum from A and B with smoothing C"""
        return cls(
            operation="SMOOTH_MAX",
            value=value,
            value_001=value_001,
            value_002=value_002,
        )

    @classmethod
    def round(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Round'. Round A to the nearest integer. Round upward if the fraction part is 0.5"""
        return cls(operation="ROUND", value=value)

    @classmethod
    def floor(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Floor'. The largest integer smaller than or equal A"""
        return cls(operation="FLOOR", value=value)

    @classmethod
    def ceil(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Ceil'. The smallest integer greater than or equal A"""
        return cls(operation="CEIL", value=value)

    @classmethod
    def truncate(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Truncate'. The integer part of A, removing fractional digits"""
        return cls(operation="TRUNC", value=value)

    @classmethod
    def fraction(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Fraction'. The fraction part of A"""
        return cls(operation="FRACT", value=value)

    @classmethod
    def truncated_modulo(
        cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5
    ) -> "Math":
        """Create Math with operation 'Truncated Modulo'. The remainder of truncated division using fmod(A,B)"""
        return cls(operation="MODULO", value=value, value_001=value_001)

    @classmethod
    def floored_modulo(
        cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5
    ) -> "Math":
        """Create Math with operation 'Floored Modulo'. The remainder of floored division"""
        return cls(operation="FLOORED_MODULO", value=value, value_001=value_001)

    @classmethod
    def wrap(
        cls,
        value: InputFloat = 0.5,
        value_001: InputFloat = 0.5,
        value_002: InputFloat = 0.5,
    ) -> "Math":
        """Create Math with operation 'Wrap'. Wrap value to range, wrap(A,B)"""
        return cls(
            operation="WRAP", value=value, value_001=value_001, value_002=value_002
        )

    @classmethod
    def snap(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Snap'. Snap to increment, snap(A,B)"""
        return cls(operation="SNAP", value=value, value_001=value_001)

    @classmethod
    def ping_pong(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Ping-Pong'. Wraps a value and reverses every other cycle (A,B)"""
        return cls(operation="PINGPONG", value=value, value_001=value_001)

    @classmethod
    def sine(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Sine'. sin(A)"""
        return cls(operation="SINE", value=value)

    @classmethod
    def cosine(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Cosine'. cos(A)"""
        return cls(operation="COSINE", value=value)

    @classmethod
    def tangent(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Tangent'. tan(A)"""
        return cls(operation="TANGENT", value=value)

    @classmethod
    def arcsine(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Arcsine'. arcsin(A)"""
        return cls(operation="ARCSINE", value=value)

    @classmethod
    def arccosine(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Arccosine'. arccos(A)"""
        return cls(operation="ARCCOSINE", value=value)

    @classmethod
    def arctangent(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Arctangent'. arctan(A)"""
        return cls(operation="ARCTANGENT", value=value)

    @classmethod
    def arctan2(cls, value: InputFloat = 0.5, value_001: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Arctan2'. The signed angle arctan(A / B)"""
        return cls(operation="ARCTAN2", value=value, value_001=value_001)

    @classmethod
    def hyperbolic_sine(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Hyperbolic Sine'. sinh(A)"""
        return cls(operation="SINH", value=value)

    @classmethod
    def hyperbolic_cosine(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Hyperbolic Cosine'. cosh(A)"""
        return cls(operation="COSH", value=value)

    @classmethod
    def hyperbolic_tangent(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'Hyperbolic Tangent'. tanh(A)"""
        return cls(operation="TANH", value=value)

    @classmethod
    def to_radians(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'To Radians'. Convert from degrees to radians"""
        return cls(operation="RADIANS", value=value)

    @classmethod
    def to_degrees(cls, value: InputFloat = 0.5) -> "Math":
        """Create Math with operation 'To Degrees'. Convert from radians to degrees"""
        return cls(operation="DEGREES", value=value)

    @property
    def operation(
        self,
    ) -> Literal[
        "ADD",
        "SUBTRACT",
        "MULTIPLY",
        "DIVIDE",
        "MULTIPLY_ADD",
        "POWER",
        "LOGARITHM",
        "SQRT",
        "INVERSE_SQRT",
        "ABSOLUTE",
        "EXPONENT",
        "MINIMUM",
        "MAXIMUM",
        "LESS_THAN",
        "GREATER_THAN",
        "SIGN",
        "COMPARE",
        "SMOOTH_MIN",
        "SMOOTH_MAX",
        "ROUND",
        "FLOOR",
        "CEIL",
        "TRUNC",
        "FRACT",
        "MODULO",
        "FLOORED_MODULO",
        "WRAP",
        "SNAP",
        "PINGPONG",
        "SINE",
        "COSINE",
        "TANGENT",
        "ARCSINE",
        "ARCCOSINE",
        "ARCTANGENT",
        "ARCTAN2",
        "SINH",
        "COSH",
        "TANH",
        "RADIANS",
        "DEGREES",
    ]:
        return self.node.operation

    @operation.setter
    def operation(
        self,
        value: Literal[
            "ADD",
            "SUBTRACT",
            "MULTIPLY",
            "DIVIDE",
            "MULTIPLY_ADD",
            "POWER",
            "LOGARITHM",
            "SQRT",
            "INVERSE_SQRT",
            "ABSOLUTE",
            "EXPONENT",
            "MINIMUM",
            "MAXIMUM",
            "LESS_THAN",
            "GREATER_THAN",
            "SIGN",
            "COMPARE",
            "SMOOTH_MIN",
            "SMOOTH_MAX",
            "ROUND",
            "FLOOR",
            "CEIL",
            "TRUNC",
            "FRACT",
            "MODULO",
            "FLOORED_MODULO",
            "WRAP",
            "SNAP",
            "PINGPONG",
            "SINE",
            "COSINE",
            "TANGENT",
            "ARCSINE",
            "ARCCOSINE",
            "ARCTANGENT",
            "ARCTAN2",
            "SINH",
            "COSH",
            "TANH",
            "RADIANS",
            "DEGREES",
        ],
    ):
        self.node.operation = value

    @property
    def use_clamp(self) -> bool:
        return self.node.use_clamp

    @use_clamp.setter
    def use_clamp(self, value: bool):
        self.node.use_clamp = value


class MatrixDeterminant(BaseNode):
    """
    Compute the determinant of the given matrix

    Parameters
    ----------
    matrix : InputMatrix
        Matrix

    Inputs
    ------
    i.matrix : MatrixSocket
        Matrix

    Outputs
    -------
    o.determinant : FloatSocket
        Determinant
    """

    _bl_idname = "FunctionNodeMatrixDeterminant"
    node: bpy.types.FunctionNodeMatrixDeterminant

    class _Inputs(SocketAccessor):
        matrix: MatrixSocket
        """Matrix"""

    class _Outputs(SocketAccessor):
        determinant: FloatSocket
        """Determinant"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, matrix: InputMatrix = None):
        super().__init__()
        key_args = {"Matrix": matrix}

        self._establish_links(**key_args)


class MatrixSVD(BaseNode):
    """
    Compute the singular value decomposition of the 3x3 part of a matrix

    Parameters
    ----------
    matrix : InputMatrix
        Matrix

    Inputs
    ------
    i.matrix : MatrixSocket
        Matrix

    Outputs
    -------
    o.u : MatrixSocket
        U
    o.s : VectorSocket
        S
    o.v : MatrixSocket
        V
    """

    _bl_idname = "FunctionNodeMatrixSVD"
    node: bpy.types.FunctionNodeMatrixSVD

    class _Inputs(SocketAccessor):
        matrix: MatrixSocket
        """Matrix"""

    class _Outputs(SocketAccessor):
        u: MatrixSocket
        """U"""
        s: VectorSocket
        """S"""
        v: MatrixSocket
        """V"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, matrix: InputMatrix = None):
        super().__init__()
        key_args = {"Matrix": matrix}

        self._establish_links(**key_args)


class MultiplyMatrices(BaseNode):
    """
    Perform a matrix multiplication on two input matrices

    Parameters
    ----------
    matrix : InputMatrix
        Matrix
    matrix_001 : InputMatrix
        Matrix

    Inputs
    ------
    i.matrix : MatrixSocket
        Matrix
    i.matrix_001 : MatrixSocket
        Matrix

    Outputs
    -------
    o.matrix : MatrixSocket
        Matrix
    """

    _bl_idname = "FunctionNodeMatrixMultiply"
    node: bpy.types.FunctionNodeMatrixMultiply

    class _Inputs(SocketAccessor):
        matrix: MatrixSocket
        """Matrix"""
        matrix_001: MatrixSocket
        """Matrix"""

    class _Outputs(SocketAccessor):
        matrix: MatrixSocket
        """Matrix"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        matrix: InputMatrix = None,
        matrix_001: InputMatrix = None,
    ):
        super().__init__()
        key_args = {"Matrix": matrix, "Matrix_001": matrix_001}

        self._establish_links(**key_args)


class PackUVIslands(BaseNode):
    """
    Scale islands of a UV map and move them so they fill the UV space as much as possible

    Parameters
    ----------
    uv : InputVector
        UV
    selection : InputBoolean
        Selection
    margin : InputFloat
        Margin
    rotate : InputBoolean
        Rotate
    method : InputMenu | Literal['Bounding Box', 'Convex Hull', 'Exact Shape']
        Method
    bottom_left : InputVector
        Bottom Left
    top_right : InputVector
        Top Right

    Inputs
    ------
    i.uv : VectorSocket
        UV
    i.selection : BooleanSocket
        Selection
    i.margin : FloatSocket
        Margin
    i.rotate : BooleanSocket
        Rotate
    i.method : MenuSocket
        Method
    i.bottom_left : VectorSocket
        Bottom Left
    i.top_right : VectorSocket
        Top Right

    Outputs
    -------
    o.uv : VectorSocket
        UV
    """

    _bl_idname = "GeometryNodeUVPackIslands"
    node: bpy.types.GeometryNodeUVPackIslands

    class _Inputs(SocketAccessor):
        uv: VectorSocket
        """UV"""
        selection: BooleanSocket
        """Selection"""
        margin: FloatSocket
        """Margin"""
        rotate: BooleanSocket
        """Rotate"""
        method: MenuSocket
        """Method"""
        bottom_left: VectorSocket
        """Bottom Left"""
        top_right: VectorSocket
        """Top Right"""

    class _Outputs(SocketAccessor):
        uv: VectorSocket
        """UV"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        uv: InputVector = None,
        selection: InputBoolean = True,
        margin: InputFloat = 0.001,
        rotate: InputBoolean = True,
        method: InputMenu
        | Literal["Bounding Box", "Convex Hull", "Exact Shape"] = "Bounding Box",
        bottom_left: InputVector = None,
        top_right: InputVector = None,
    ):
        super().__init__()
        key_args = {
            "UV": uv,
            "Selection": selection,
            "Margin": margin,
            "Rotate": rotate,
            "Method": method,
            "Bottom Left": bottom_left,
            "Top Right": top_right,
        }

        self._establish_links(**key_args)


class ProjectPoint(BaseNode):
    """
    Project a point using a matrix, using location, rotation, scale, and perspective divide

    Parameters
    ----------
    vector : InputVector
        Vector
    transform : InputMatrix
        Transform

    Inputs
    ------
    i.vector : VectorSocket
        Vector
    i.transform : MatrixSocket
        Transform

    Outputs
    -------
    o.vector : VectorSocket
        Vector
    """

    _bl_idname = "FunctionNodeProjectPoint"
    node: bpy.types.FunctionNodeProjectPoint

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""
        transform: MatrixSocket
        """Transform"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        vector: InputVector = None,
        transform: InputMatrix = None,
    ):
        super().__init__()
        key_args = {"Vector": vector, "Transform": transform}

        self._establish_links(**key_args)


class QuaternionToRotation(BaseNode):
    """
    Build a rotation from quaternion components

    Parameters
    ----------
    w : InputFloat
        W
    x : InputFloat
        X
    y : InputFloat
        Y
    z : InputFloat
        Z

    Inputs
    ------
    i.w : FloatSocket
        W
    i.x : FloatSocket
        X
    i.y : FloatSocket
        Y
    i.z : FloatSocket
        Z

    Outputs
    -------
    o.rotation : RotationSocket
        Rotation
    """

    _bl_idname = "FunctionNodeQuaternionToRotation"
    node: bpy.types.FunctionNodeQuaternionToRotation

    class _Inputs(SocketAccessor):
        w: FloatSocket
        """W"""
        x: FloatSocket
        """X"""
        y: FloatSocket
        """Y"""
        z: FloatSocket
        """Z"""

    class _Outputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        w: InputFloat = 1.0,
        x: InputFloat = 0.0,
        y: InputFloat = 0.0,
        z: InputFloat = 0.0,
    ):
        super().__init__()
        key_args = {"W": w, "X": x, "Y": y, "Z": z}

        self._establish_links(**key_args)


class RandomValue(BaseNode, Generic[_T]):
    """
    Output a randomized value

    Parameters
    ----------
    min : InputFloat
        Min
    max : InputFloat
        Max
    id : InputInteger
        ID
    seed : InputInteger
        Seed
    probability : InputFloat
        Probability

    Inputs
    ------
    i.min : FloatSocket
        Min
    i.max : FloatSocket
        Max
    i.id : IntegerSocket
        ID
    i.seed : IntegerSocket
        Seed
    i.probability : FloatSocket
        Probability

    Outputs
    -------
    o.value : FloatSocket
        Value
    """

    _bl_idname = "FunctionNodeRandomValue"
    node: bpy.types.FunctionNodeRandomValue

    class _Inputs(SocketAccessor, Generic[_S]):
        min: _S
        """Min"""
        max: _S
        """Max"""
        id: IntegerSocket
        """ID"""
        seed: IntegerSocket
        """Seed"""
        probability: FloatSocket
        """Probability"""

    class _Outputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        min: InputAny = 0.0,
        max: InputAny = 1.0,
        id: InputInteger = 0,
        seed: InputInteger = 0,
        probability: InputFloat = None,
        *,
        data_type: Literal["FLOAT", "INT", "BOOLEAN", "FLOAT_VECTOR"] = "FLOAT",
    ):
        super().__init__()
        self.data_type = data_type
        _all_args = {
            "Min": min,
            "Max": max,
            "ID": id,
            "Seed": seed,
            "Probability": probability,
        }
        _socket_ids = {s.identifier for s in self.node.inputs}
        key_args = {k: v for k, v in _all_args.items() if k in _socket_ids}
        self._establish_links(**key_args)

    @classmethod
    def float(
        cls,
        min: InputFloat = 0.0,
        max: InputFloat = 1.0,
        id: InputInteger = 0,
        seed: InputInteger = 0,
    ) -> "RandomValue[FloatSocket]":
        """Create Random Value with operation 'Float'. Floating-point value"""
        return RandomValue(data_type="FLOAT", min=min, max=max, id=id, seed=seed)

    @classmethod
    def integer(
        cls,
        min: InputInteger = 0,
        max: InputInteger = 100,
        id: InputInteger = 0,
        seed: InputInteger = 0,
    ) -> "RandomValue[IntegerSocket]":
        """Create Random Value with operation 'Integer'. 32-bit integer"""
        return RandomValue(data_type="INT", min=min, max=max, id=id, seed=seed)

    @classmethod
    def boolean(
        cls, probability: InputFloat = 0.5, id: InputInteger = 0, seed: InputInteger = 0
    ) -> "RandomValue[BooleanSocket]":
        """Create Random Value with operation 'Boolean'. True or false"""
        return RandomValue(
            data_type="BOOLEAN", probability=probability, id=id, seed=seed
        )

    @classmethod
    def vector(
        cls,
        min: InputVector = None,
        max: InputVector = None,
        id: InputInteger = 0,
        seed: InputInteger = 0,
    ) -> "RandomValue[VectorSocket]":
        """Create Random Value with operation 'Vector'. 3D vector with floating-point values"""
        return RandomValue(data_type="FLOAT_VECTOR", min=min, max=max, id=id, seed=seed)

    @property
    def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "FLOAT_VECTOR"]:
        return self.node.data_type  # ty: ignore[invalid-return-type]

    @data_type.setter
    def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "FLOAT_VECTOR"]):
        self.node.data_type = value


class ReplaceString(BaseNode):
    """
    Replace a given string segment with another

    Parameters
    ----------
    string : InputString
        String
    find : InputString
        Find
    replace : InputString
        Replace

    Inputs
    ------
    i.string : StringSocket
        String
    i.find : StringSocket
        Find
    i.replace : StringSocket
        Replace

    Outputs
    -------
    o.string : StringSocket
        String
    """

    _bl_idname = "FunctionNodeReplaceString"
    node: bpy.types.FunctionNodeReplaceString

    class _Inputs(SocketAccessor):
        string: StringSocket
        """String"""
        find: StringSocket
        """Find"""
        replace: StringSocket
        """Replace"""

    class _Outputs(SocketAccessor):
        string: StringSocket
        """String"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        string: InputString = "",
        find: InputString = "",
        replace: InputString = "",
    ):
        super().__init__()
        key_args = {"String": string, "Find": find, "Replace": replace}

        self._establish_links(**key_args)


class ReverseString(BaseNode):
    """
    Reverse the order of the characters in a string

    Parameters
    ----------
    string : InputString
        String

    Inputs
    ------
    i.string : StringSocket
        String

    Outputs
    -------
    o.string : StringSocket
        String
    """

    _bl_idname = "FunctionNodeReverseString"
    node: bpy.types.FunctionNodeReverseString  # ty: ignore[unresolved-attribute]

    class _Inputs(SocketAccessor):
        string: StringSocket
        """String"""

    class _Outputs(SocketAccessor):
        string: StringSocket
        """String"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, string: InputString = ""):
        super().__init__()
        key_args = {"String": string}

        self._establish_links(**key_args)


class RotateEuler(BaseNode):
    """
    Apply a secondary Euler rotation to a given Euler rotation

    Parameters
    ----------
    rotation : InputVector
        Rotation
    rotate_by : InputVector
        Rotate By
    axis : InputVector
        Axis
    angle : InputFloat
        Angle

    Inputs
    ------
    i.rotation : VectorSocket
        Rotation
    i.rotate_by : VectorSocket
        Rotate By
    i.axis : VectorSocket
        Axis
    i.angle : FloatSocket
        Angle

    Outputs
    -------
    o.rotation : VectorSocket
        Rotation
    """

    _bl_idname = "FunctionNodeRotateEuler"
    node: bpy.types.FunctionNodeRotateEuler

    class _Inputs(SocketAccessor):
        rotation: VectorSocket
        """Rotation"""
        rotate_by: VectorSocket
        """Rotate By"""
        axis: VectorSocket
        """Axis"""
        angle: FloatSocket
        """Angle"""

    class _Outputs(SocketAccessor):
        rotation: VectorSocket
        """Rotation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        rotation: InputVector = None,
        rotate_by: InputVector = None,
        axis: InputVector = None,
        angle: InputFloat = None,
        *,
        rotation_type: Literal["AXIS_ANGLE", "EULER"] = "EULER",
        space: Literal["OBJECT", "LOCAL"] = "OBJECT",
    ):
        super().__init__()
        self.rotation_type = rotation_type
        self.space = space
        _all_args = {
            "Rotation": rotation,
            "Rotate By": rotate_by,
            "Axis": axis,
            "Angle": angle,
        }
        _socket_ids = {s.identifier for s in self.node.inputs}
        key_args = {k: v for k, v in _all_args.items() if k in _socket_ids}
        self._establish_links(**key_args)

    @classmethod
    def axis_angle(
        cls,
        rotation: InputVector = None,
        axis: InputVector = None,
        angle: InputFloat = 0.0,
    ) -> "RotateEuler":
        """Create Rotate Euler with operation 'Axis Angle'. Rotate around an axis by an angle"""
        return cls(
            rotation_type="AXIS_ANGLE", rotation=rotation, axis=axis, angle=angle
        )

    @classmethod
    def euler(
        cls, rotation: InputVector = None, rotate_by: InputVector = None
    ) -> "RotateEuler":
        """Create Rotate Euler with operation 'Euler'. Rotate around the X, Y, and Z axes"""
        return cls(rotation_type="EULER", rotation=rotation, rotate_by=rotate_by)

    @property
    def rotation_type(self) -> Literal["AXIS_ANGLE", "EULER"]:
        return self.node.rotation_type

    @rotation_type.setter
    def rotation_type(self, value: Literal["AXIS_ANGLE", "EULER"]):
        self.node.rotation_type = value

    @property
    def space(self) -> Literal["OBJECT", "LOCAL"]:
        return self.node.space

    @space.setter
    def space(self, value: Literal["OBJECT", "LOCAL"]):
        self.node.space = value


class RotateRotation(BaseNode):
    """
    Apply a secondary rotation to a given rotation value

    Parameters
    ----------
    rotation : InputRotation
        Rotation
    rotate_by : InputRotation
        Rotate By

    Inputs
    ------
    i.rotation : RotationSocket
        Rotation
    i.rotate_by : RotationSocket
        Rotate By

    Outputs
    -------
    o.rotation : RotationSocket
        Rotation
    """

    _bl_idname = "FunctionNodeRotateRotation"
    node: bpy.types.FunctionNodeRotateRotation

    class _Inputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""
        rotate_by: RotationSocket
        """Rotate By"""

    class _Outputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        rotation: InputRotation = None,
        rotate_by: InputRotation = None,
        *,
        rotation_space: Literal["GLOBAL", "LOCAL"] = "GLOBAL",
    ):
        super().__init__()
        key_args = {"Rotation": rotation, "Rotate By": rotate_by}
        self.rotation_space = rotation_space
        self._establish_links(**key_args)

    @property
    def rotation_space(self) -> Literal["GLOBAL", "LOCAL"]:
        return self.node.rotation_space

    @rotation_space.setter
    def rotation_space(self, value: Literal["GLOBAL", "LOCAL"]):
        self.node.rotation_space = value


class RotateVector(BaseNode):
    """
    Apply a rotation to a given vector

    Parameters
    ----------
    vector : InputVector
        Vector
    rotation : InputRotation
        Rotation

    Inputs
    ------
    i.vector : VectorSocket
        Vector
    i.rotation : RotationSocket
        Rotation

    Outputs
    -------
    o.vector : VectorSocket
        Vector
    """

    _bl_idname = "FunctionNodeRotateVector"
    node: bpy.types.FunctionNodeRotateVector

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""
        rotation: RotationSocket
        """Rotation"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        vector: InputVector = None,
        rotation: InputRotation = None,
    ):
        super().__init__()
        key_args = {"Vector": vector, "Rotation": rotation}

        self._establish_links(**key_args)


class RotationToAxisAngle(BaseNode):
    """
    Convert a rotation to axis angle components

    Parameters
    ----------
    rotation : InputRotation
        Rotation

    Inputs
    ------
    i.rotation : RotationSocket
        Rotation

    Outputs
    -------
    o.axis : VectorSocket
        Axis
    o.angle : FloatSocket
        Angle
    """

    _bl_idname = "FunctionNodeRotationToAxisAngle"
    node: bpy.types.FunctionNodeRotationToAxisAngle

    class _Inputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    class _Outputs(SocketAccessor):
        axis: VectorSocket
        """Axis"""
        angle: FloatSocket
        """Angle"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, rotation: InputRotation = None):
        super().__init__()
        key_args = {"Rotation": rotation}

        self._establish_links(**key_args)


class RotationToEuler(BaseNode):
    """
    Convert a standard rotation value to an Euler rotation

    Parameters
    ----------
    rotation : InputRotation
        Rotation

    Inputs
    ------
    i.rotation : RotationSocket
        Rotation

    Outputs
    -------
    o.euler : VectorSocket
        Euler
    """

    _bl_idname = "FunctionNodeRotationToEuler"
    node: bpy.types.FunctionNodeRotationToEuler

    class _Inputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    class _Outputs(SocketAccessor):
        euler: VectorSocket
        """Euler"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, rotation: InputRotation = None):
        super().__init__()
        key_args = {"Rotation": rotation}

        self._establish_links(**key_args)


class RotationToQuaternion(BaseNode):
    """
    Retrieve the quaternion components representing a rotation

    Parameters
    ----------
    rotation : InputRotation
        Rotation

    Inputs
    ------
    i.rotation : RotationSocket
        Rotation

    Outputs
    -------
    o.w : FloatSocket
        W
    o.x : FloatSocket
        X
    o.y : FloatSocket
        Y
    o.z : FloatSocket
        Z
    """

    _bl_idname = "FunctionNodeRotationToQuaternion"
    node: bpy.types.FunctionNodeRotationToQuaternion

    class _Inputs(SocketAccessor):
        rotation: RotationSocket
        """Rotation"""

    class _Outputs(SocketAccessor):
        w: FloatSocket
        """W"""
        x: FloatSocket
        """X"""
        y: FloatSocket
        """Y"""
        z: FloatSocket
        """Z"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, rotation: InputRotation = None):
        super().__init__()
        key_args = {"Rotation": rotation}

        self._establish_links(**key_args)


class SampleSoundFrequencies(BaseNode):
    """
    Retrieve the amplitude from a sound data-block of a frequency range at a given time

    Parameters
    ----------
    sound : InputSound
        Sound
    time : InputFloat
        Time
    all_channels : InputBoolean
        All Channels
    channel : InputInteger
        Channel
    low : InputFloat
        Low
    high : InputFloat
        High
    fft_size : InputMenu | Literal['128', '256', '512', '1024', '2048', '4096', '8192', '16384', '32768']
        FFT Size
    window_function : InputMenu | Literal['Hann', 'Hamming', 'Blackman', 'Rectangular']
        Window Function

    Inputs
    ------
    i.sound : SoundSocket
        Sound
    i.time : FloatSocket
        Time
    i.all_channels : BooleanSocket
        All Channels
    i.channel : IntegerSocket
        Channel
    i.low : FloatSocket
        Low
    i.high : FloatSocket
        High
    i.fft_size : MenuSocket
        FFT Size
    i.window_function : MenuSocket
        Window Function

    Outputs
    -------
    o.amplitude : FloatSocket
        Amplitude
    """

    _bl_idname = "GeometryNodeSampleSoundFrequencies"
    node: bpy.types.GeometryNodeSampleSoundFrequencies

    class _Inputs(SocketAccessor):
        sound: SoundSocket
        """Sound"""
        time: FloatSocket
        """Time"""
        all_channels: BooleanSocket
        """All Channels"""
        channel: IntegerSocket
        """Channel"""
        low: FloatSocket
        """Low"""
        high: FloatSocket
        """High"""
        fft_size: MenuSocket
        """FFT Size"""
        window_function: MenuSocket
        """Window Function"""

    class _Outputs(SocketAccessor):
        amplitude: FloatSocket
        """Amplitude"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        sound: InputSound = None,
        time: InputFloat = 0.0,
        all_channels: InputBoolean = True,
        channel: InputInteger = 0,
        low: InputFloat = 0.0,
        high: InputFloat = 10000.0,
        fft_size: InputMenu
        | Literal[
            "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "32768"
        ] = "4096",
        window_function: InputMenu
        | Literal["Hann", "Hamming", "Blackman", "Rectangular"] = "Hann",
    ):
        super().__init__()
        key_args = {
            "Sound": sound,
            "Time": time,
            "All Channels": all_channels,
            "Channel": channel,
            "Low": low,
            "High": high,
            "FFT Size": fft_size,
            "Window Function": window_function,
        }

        self._establish_links(**key_args)


class SeparateBundle(BaseNode):
    """
    Split a bundle into multiple sockets.

    Parameters
    ----------
    bundle : InputBundle
        Bundle

    Inputs
    ------
    i.bundle : BundleSocket
        Bundle
    """

    _bl_idname = "NodeSeparateBundle"
    node: bpy.types.NodeSeparateBundle

    class _Inputs(SocketAccessor):
        bundle: BundleSocket
        """Bundle"""

    class _Outputs(SocketAccessor):
        pass

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    @property
    def define_signature(self) -> bool:
        return self.node.define_signature

    @define_signature.setter
    def define_signature(self, value: bool):
        self.node.define_signature = value

    def __init__(
        self,
        bundle: InputBundle = None,
        items: "dict[str, str] | None" = None,
        *,
        define_signature: bool = False,
    ):
        super().__init__()
        self.define_signature = define_signature
        # Items are output sockets pulled from the bundle; each is declared by
        # name and socket-type string (the inverse of CombineBundle, where the
        # type is inferred from a linked source).
        for name, socket_type in (items or {}).items():
            self.node.bundle_items.new(socket_type, name)  # ty: ignore[invalid-argument-type]
        self._establish_links(Bundle=bundle)


class SeparateColor(BaseNode):
    """
    Split a color into separate channels, based on a particular color model

    Parameters
    ----------
    color : InputColor
        Color

    Inputs
    ------
    i.color : ColorSocket
        Color

    Outputs
    -------
    o.red : FloatSocket
        Red
    o.green : FloatSocket
        Green
    o.blue : FloatSocket
        Blue
    o.alpha : FloatSocket
        Alpha
    """

    _bl_idname = "FunctionNodeSeparateColor"
    node: bpy.types.FunctionNodeSeparateColor

    class _Inputs(SocketAccessor):
        color: ColorSocket
        """Color"""

    class _Outputs(SocketAccessor):
        red: FloatSocket
        """Red"""
        green: FloatSocket
        """Green"""
        blue: FloatSocket
        """Blue"""
        alpha: FloatSocket
        """Alpha"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        color: InputColor = None,
        *,
        mode: Literal["RGB", "HSV", "HSL"] = "RGB",
    ):
        super().__init__()
        key_args = {"Color": color}
        self.mode = mode
        self._establish_links(**key_args)

    @classmethod
    def rgb(cls, color: InputColor = None) -> "SeparateColor":
        """Create Separate Color with operation 'RGB'. Use RGB (Red, Green, Blue) color processing"""
        return cls(mode="RGB", color=color)

    @classmethod
    def hsv(cls, color: InputColor = None) -> "SeparateColor":
        """Create Separate Color with operation 'HSV'. Use HSV (Hue, Saturation, Value) color processing"""
        return cls(mode="HSV", color=color)

    @classmethod
    def hsl(cls, color: InputColor = None) -> "SeparateColor":
        """Create Separate Color with operation 'HSL'. Use HSL (Hue, Saturation, Lightness) color processing"""
        return cls(mode="HSL", color=color)

    @property
    def mode(self) -> Literal["RGB", "HSV", "HSL"]:
        return self.node.mode

    @mode.setter
    def mode(self, value: Literal["RGB", "HSV", "HSL"]):
        self.node.mode = value


class SeparateMatrix(BaseNode):
    """
    Split a 4x4 matrix into its individual values

    Parameters
    ----------
    matrix : InputMatrix
        Matrix

    Inputs
    ------
    i.matrix : MatrixSocket
        Matrix

    Outputs
    -------
    o.column_1_row_1 : FloatSocket
        Column 1 Row 1
    o.column_1_row_2 : FloatSocket
        Column 1 Row 2
    o.column_1_row_3 : FloatSocket
        Column 1 Row 3
    o.column_1_row_4 : FloatSocket
        Column 1 Row 4
    o.column_2_row_1 : FloatSocket
        Column 2 Row 1
    o.column_2_row_2 : FloatSocket
        Column 2 Row 2
    o.column_2_row_3 : FloatSocket
        Column 2 Row 3
    o.column_2_row_4 : FloatSocket
        Column 2 Row 4
    o.column_3_row_1 : FloatSocket
        Column 3 Row 1
    o.column_3_row_2 : FloatSocket
        Column 3 Row 2
    o.column_3_row_3 : FloatSocket
        Column 3 Row 3
    o.column_3_row_4 : FloatSocket
        Column 3 Row 4
    o.column_4_row_1 : FloatSocket
        Column 4 Row 1
    o.column_4_row_2 : FloatSocket
        Column 4 Row 2
    o.column_4_row_3 : FloatSocket
        Column 4 Row 3
    o.column_4_row_4 : FloatSocket
        Column 4 Row 4
    """

    _bl_idname = "FunctionNodeSeparateMatrix"
    node: bpy.types.FunctionNodeSeparateMatrix

    class _Inputs(SocketAccessor):
        matrix: MatrixSocket
        """Matrix"""

    class _Outputs(SocketAccessor):
        column_1_row_1: FloatSocket
        """Column 1 Row 1"""
        column_1_row_2: FloatSocket
        """Column 1 Row 2"""
        column_1_row_3: FloatSocket
        """Column 1 Row 3"""
        column_1_row_4: FloatSocket
        """Column 1 Row 4"""
        column_2_row_1: FloatSocket
        """Column 2 Row 1"""
        column_2_row_2: FloatSocket
        """Column 2 Row 2"""
        column_2_row_3: FloatSocket
        """Column 2 Row 3"""
        column_2_row_4: FloatSocket
        """Column 2 Row 4"""
        column_3_row_1: FloatSocket
        """Column 3 Row 1"""
        column_3_row_2: FloatSocket
        """Column 3 Row 2"""
        column_3_row_3: FloatSocket
        """Column 3 Row 3"""
        column_3_row_4: FloatSocket
        """Column 3 Row 4"""
        column_4_row_1: FloatSocket
        """Column 4 Row 1"""
        column_4_row_2: FloatSocket
        """Column 4 Row 2"""
        column_4_row_3: FloatSocket
        """Column 4 Row 3"""
        column_4_row_4: FloatSocket
        """Column 4 Row 4"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, matrix: InputMatrix = None):
        super().__init__()
        key_args = {"Matrix": matrix}

        self._establish_links(**key_args)


class SeparateTransform(BaseNode):
    """
    Split a transformation matrix into a translation vector, a rotation, and a scale vector

    Parameters
    ----------
    transform : InputMatrix
        Transform

    Inputs
    ------
    i.transform : MatrixSocket
        Transform

    Outputs
    -------
    o.translation : VectorSocket
        Translation
    o.rotation : RotationSocket
        Rotation
    o.scale : VectorSocket
        Scale
    """

    _bl_idname = "FunctionNodeSeparateTransform"
    node: bpy.types.FunctionNodeSeparateTransform

    class _Inputs(SocketAccessor):
        transform: MatrixSocket
        """Transform"""

    class _Outputs(SocketAccessor):
        translation: VectorSocket
        """Translation"""
        rotation: RotationSocket
        """Rotation"""
        scale: VectorSocket
        """Scale"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, transform: InputMatrix = None):
        super().__init__()
        key_args = {"Transform": transform}

        self._establish_links(**key_args)


class SeparateXYZ(BaseNode):
    """
    Split a vector into its X, Y, and Z components

    Parameters
    ----------
    vector : InputVector
        Vector

    Inputs
    ------
    i.vector : VectorSocket
        Vector

    Outputs
    -------
    o.x : FloatSocket
        X
    o.y : FloatSocket
        Y
    o.z : FloatSocket
        Z
    """

    _bl_idname = "ShaderNodeSeparateXYZ"
    node: bpy.types.ShaderNodeSeparateXYZ

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    class _Outputs(SocketAccessor):
        x: FloatSocket
        """X"""
        y: FloatSocket
        """Y"""
        z: FloatSocket
        """Z"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, vector: InputVector = None):
        super().__init__()
        key_args = {"Vector": vector}

        self._establish_links(**key_args)


class SetStringCase(BaseNode):
    """
    Convert the case of a string

    Parameters
    ----------
    string : InputString
        String
    case : InputMenu | Literal['Uppercase', 'Lowercase']
        Case

    Inputs
    ------
    i.string : StringSocket
        String
    i.case : MenuSocket
        Case

    Outputs
    -------
    o.string : StringSocket
        String
    """

    _bl_idname = "FunctionNodeSetStringCase"
    node: bpy.types.FunctionNodeSetStringCase  # ty: ignore[unresolved-attribute]

    class _Inputs(SocketAccessor):
        string: StringSocket
        """String"""
        case: MenuSocket
        """Case"""

    class _Outputs(SocketAccessor):
        string: StringSocket
        """String"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        string: InputString = "",
        case: InputMenu | Literal["Uppercase", "Lowercase"] = "Uppercase",
    ):
        super().__init__()
        key_args = {"String": string, "Case": case}

        self._establish_links(**key_args)


class SliceString(BaseNode):
    """
    Extract a string segment from a larger string

    Parameters
    ----------
    string : InputString
        String
    position : InputInteger
        Position
    length : InputInteger
        Length

    Inputs
    ------
    i.string : StringSocket
        String
    i.position : IntegerSocket
        Position
    i.length : IntegerSocket
        Length

    Outputs
    -------
    o.string : StringSocket
        String
    """

    _bl_idname = "FunctionNodeSliceString"
    node: bpy.types.FunctionNodeSliceString

    class _Inputs(SocketAccessor):
        string: StringSocket
        """String"""
        position: IntegerSocket
        """Position"""
        length: IntegerSocket
        """Length"""

    class _Outputs(SocketAccessor):
        string: StringSocket
        """String"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        string: InputString = "",
        position: InputInteger = 0,
        length: InputInteger = 10,
    ):
        super().__init__()
        key_args = {"String": string, "Position": position, "Length": length}

        self._establish_links(**key_args)


class SortList(BaseNode, Generic[_T]):
    """
    Sort a list based on weights

    Parameters
    ----------
    list : InputFloat
        List
    selection : InputBoolean
        Selection
    group_id : InputInteger
        Group ID
    sort_weight : InputFloat
        Sort Weight

    Inputs
    ------
    i.list : FloatSocket
        List
    i.selection : BooleanSocket
        Selection
    i.group_id : IntegerSocket
        Group ID
    i.sort_weight : FloatSocket
        Sort Weight

    Outputs
    -------
    o.list : FloatSocket
        List
    """

    _bl_idname = "GeometryNodeSortList"
    node: bpy.types.GeometryNodeSortList  # ty: ignore[unresolved-attribute]

    class _Inputs(SocketAccessor, Generic[_S]):
        list: _S
        """List"""
        selection: BooleanSocket
        """Selection"""
        group_id: IntegerSocket
        """Group ID"""
        sort_weight: FloatSocket
        """Sort Weight"""

    class _Outputs(SocketAccessor, Generic[_S]):
        list: _S
        """List"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        list: InputAny = 0.0,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
        *,
        socket_type: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ] = "FLOAT",
    ):
        super().__init__()
        key_args = {
            "List": list,
            "Selection": selection,
            "Group ID": group_id,
            "Sort Weight": sort_weight,
        }
        self.socket_type = socket_type
        self._establish_links(**key_args)

    @classmethod
    def float(
        cls,
        list: InputFloat = 0.0,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[FloatSocket]":
        """Create Sort List with operation 'Float'."""
        return SortList(
            socket_type="FLOAT",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def integer(
        cls,
        list: InputInteger = 0,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[IntegerSocket]":
        """Create Sort List with operation 'Integer'."""
        return SortList(
            socket_type="INT",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def boolean(
        cls,
        list: InputBoolean = False,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[BooleanSocket]":
        """Create Sort List with operation 'Boolean'."""
        return SortList(
            socket_type="BOOLEAN",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def vector(
        cls,
        list: InputVector = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[VectorSocket]":
        """Create Sort List with operation 'Vector'."""
        return SortList(
            socket_type="VECTOR",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def color(
        cls,
        list: InputColor = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[ColorSocket]":
        """Create Sort List with operation 'Color'."""
        return SortList(
            socket_type="RGBA",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def rotation(
        cls,
        list: InputRotation = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[RotationSocket]":
        """Create Sort List with operation 'Rotation'."""
        return SortList(
            socket_type="ROTATION",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def matrix(
        cls,
        list: InputMatrix = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[MatrixSocket]":
        """Create Sort List with operation 'Matrix'."""
        return SortList(
            socket_type="MATRIX",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def string(
        cls,
        list: InputString = "",
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[StringSocket]":
        """Create Sort List with operation 'String'."""
        return SortList(
            socket_type="STRING",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def menu(
        cls,
        list: InputMenu = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[MenuSocket]":
        """Create Sort List with operation 'Menu'."""
        return SortList(
            socket_type="MENU",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def object(
        cls,
        list: InputObject = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[ObjectSocket]":
        """Create Sort List with operation 'Object'."""
        return SortList(
            socket_type="OBJECT",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def image(
        cls,
        list: InputImage = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[ImageSocket]":
        """Create Sort List with operation 'Image'."""
        return SortList(
            socket_type="IMAGE",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def geometry(
        cls,
        list: InputGeometry = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[GeometrySocket]":
        """Create Sort List with operation 'Geometry'."""
        return SortList(
            socket_type="GEOMETRY",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def collection(
        cls,
        list: InputCollection = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[CollectionSocket]":
        """Create Sort List with operation 'Collection'."""
        return SortList(
            socket_type="COLLECTION",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def material(
        cls,
        list: InputMaterial = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[MaterialSocket]":
        """Create Sort List with operation 'Material'."""
        return SortList(
            socket_type="MATERIAL",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def bundle(
        cls,
        list: InputBundle = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[BundleSocket]":
        """Create Sort List with operation 'Bundle'."""
        return SortList(
            socket_type="BUNDLE",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def closure(
        cls,
        list: InputClosure = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[ClosureSocket]":
        """Create Sort List with operation 'Closure'."""
        return SortList(
            socket_type="CLOSURE",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def font(
        cls,
        list: InputFont = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[FontSocket]":
        """Create Sort List with operation 'Font'."""
        return SortList(
            socket_type="FONT",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @classmethod
    def sound(
        cls,
        list: InputSound = None,
        selection: InputBoolean = True,
        group_id: InputInteger = 0,
        sort_weight: InputFloat = 0.0,
    ) -> "SortList[SoundSocket]":
        """Create Sort List with operation 'Sound'."""
        return SortList(
            socket_type="SOUND",
            list=list,
            selection=selection,
            group_id=group_id,
            sort_weight=sort_weight,
        )

    @property
    def socket_type(
        self,
    ) -> Literal[
        "FLOAT",
        "INT",
        "BOOLEAN",
        "VECTOR",
        "RGBA",
        "ROTATION",
        "MATRIX",
        "STRING",
        "MENU",
        "OBJECT",
        "IMAGE",
        "GEOMETRY",
        "COLLECTION",
        "MATERIAL",
        "BUNDLE",
        "CLOSURE",
        "FONT",
        "SOUND",
    ]:
        return self.node.socket_type

    @socket_type.setter
    def socket_type(
        self,
        value: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ],
    ):
        self.node.socket_type = value


class SplitString(BaseNode):
    """
    Split a string into a list using a separator

    Parameters
    ----------
    string : InputString
        String
    separator : InputString
        Separator

    Inputs
    ------
    i.string : StringSocket
        String
    i.separator : StringSocket
        Separator

    Outputs
    -------
    o.list : StringSocket
        List
    """

    _bl_idname = "FunctionNodeSplitString"
    node: bpy.types.FunctionNodeSplitString

    class _Inputs(SocketAccessor):
        string: StringSocket
        """String"""
        separator: StringSocket
        """Separator"""

    class _Outputs(SocketAccessor):
        list: StringSocketList
        """List"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        string: InputString = "",
        separator: InputString = "",
    ):
        super().__init__()
        key_args = {"String": string, "Separator": separator}

        self._establish_links(**key_args)


class StoreBundleItem(BaseNode, Generic[_T]):
    """
    Store a bundle item by path and data type.

    Parameters
    ----------
    bundle : InputBundle
        Bundle
    path : InputString
        Path
    item : InputFloat
        Item

    Inputs
    ------
    i.bundle : BundleSocket
        Bundle
    i.path : StringSocket
        Path
    i.item : FloatSocket
        Item

    Outputs
    -------
    o.bundle : BundleSocket
        Bundle
    """

    _bl_idname = "NodeStoreBundleItem"
    node: bpy.types.NodeStoreBundleItem

    class _Inputs(SocketAccessor, Generic[_S]):
        bundle: BundleSocket
        """Bundle"""
        path: StringSocket
        """Path"""
        item: _S
        """Item"""

    class _Outputs(SocketAccessor):
        bundle: BundleSocket
        """Bundle"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputAny = 0.0,
        *,
        socket_type: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ] = "FLOAT",
        structure_type: Literal[
            "AUTO", "DYNAMIC", "FIELD", "GRID", "LIST", "SINGLE"
        ] = "AUTO",
    ):
        super().__init__()
        key_args = {"Bundle": bundle, "Path": path, "Item": item}
        self.socket_type = socket_type
        self.structure_type = structure_type
        self._establish_links(**key_args)

    @classmethod
    def float(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputFloat = 0.0
    ) -> "StoreBundleItem[FloatSocket]":
        """Create Store Bundle Item with operation 'Float'."""
        return StoreBundleItem(socket_type="FLOAT", bundle=bundle, path=path, item=item)

    @classmethod
    def integer(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputInteger = 0
    ) -> "StoreBundleItem[IntegerSocket]":
        """Create Store Bundle Item with operation 'Integer'."""
        return StoreBundleItem(socket_type="INT", bundle=bundle, path=path, item=item)

    @classmethod
    def boolean(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputBoolean = False,
    ) -> "StoreBundleItem[BooleanSocket]":
        """Create Store Bundle Item with operation 'Boolean'."""
        return StoreBundleItem(
            socket_type="BOOLEAN", bundle=bundle, path=path, item=item
        )

    @classmethod
    def vector(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputVector = None,
    ) -> "StoreBundleItem[VectorSocket]":
        """Create Store Bundle Item with operation 'Vector'."""
        return StoreBundleItem(
            socket_type="VECTOR", bundle=bundle, path=path, item=item
        )

    @classmethod
    def color(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputColor = None
    ) -> "StoreBundleItem[ColorSocket]":
        """Create Store Bundle Item with operation 'Color'."""
        return StoreBundleItem(socket_type="RGBA", bundle=bundle, path=path, item=item)

    @classmethod
    def rotation(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputRotation = None,
    ) -> "StoreBundleItem[RotationSocket]":
        """Create Store Bundle Item with operation 'Rotation'."""
        return StoreBundleItem(
            socket_type="ROTATION", bundle=bundle, path=path, item=item
        )

    @classmethod
    def matrix(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputMatrix = None,
    ) -> "StoreBundleItem[MatrixSocket]":
        """Create Store Bundle Item with operation 'Matrix'."""
        return StoreBundleItem(
            socket_type="MATRIX", bundle=bundle, path=path, item=item
        )

    @classmethod
    def string(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputString = ""
    ) -> "StoreBundleItem[StringSocket]":
        """Create Store Bundle Item with operation 'String'."""
        return StoreBundleItem(
            socket_type="STRING", bundle=bundle, path=path, item=item
        )

    @classmethod
    def menu(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputMenu = None
    ) -> "StoreBundleItem[MenuSocket]":
        """Create Store Bundle Item with operation 'Menu'."""
        return StoreBundleItem(socket_type="MENU", bundle=bundle, path=path, item=item)

    @classmethod
    def object(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputObject = None,
    ) -> "StoreBundleItem[ObjectSocket]":
        """Create Store Bundle Item with operation 'Object'."""
        return StoreBundleItem(
            socket_type="OBJECT", bundle=bundle, path=path, item=item
        )

    @classmethod
    def image(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputImage = None
    ) -> "StoreBundleItem[ImageSocket]":
        """Create Store Bundle Item with operation 'Image'."""
        return StoreBundleItem(socket_type="IMAGE", bundle=bundle, path=path, item=item)

    @classmethod
    def geometry(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputGeometry = None,
    ) -> "StoreBundleItem[GeometrySocket]":
        """Create Store Bundle Item with operation 'Geometry'."""
        return StoreBundleItem(
            socket_type="GEOMETRY", bundle=bundle, path=path, item=item
        )

    @classmethod
    def collection(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputCollection = None,
    ) -> "StoreBundleItem[CollectionSocket]":
        """Create Store Bundle Item with operation 'Collection'."""
        return StoreBundleItem(
            socket_type="COLLECTION", bundle=bundle, path=path, item=item
        )

    @classmethod
    def material(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputMaterial = None,
    ) -> "StoreBundleItem[MaterialSocket]":
        """Create Store Bundle Item with operation 'Material'."""
        return StoreBundleItem(
            socket_type="MATERIAL", bundle=bundle, path=path, item=item
        )

    @classmethod
    def bundle(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputBundle = None,
    ) -> "StoreBundleItem[BundleSocket]":
        """Create Store Bundle Item with operation 'Bundle'."""
        return StoreBundleItem(
            socket_type="BUNDLE", bundle=bundle, path=path, item=item
        )

    @classmethod
    def closure(
        cls,
        bundle: InputBundle = None,
        path: InputString = "",
        item: InputClosure = None,
    ) -> "StoreBundleItem[ClosureSocket]":
        """Create Store Bundle Item with operation 'Closure'."""
        return StoreBundleItem(
            socket_type="CLOSURE", bundle=bundle, path=path, item=item
        )

    @classmethod
    def font(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputFont = None
    ) -> "StoreBundleItem[FontSocket]":
        """Create Store Bundle Item with operation 'Font'."""
        return StoreBundleItem(socket_type="FONT", bundle=bundle, path=path, item=item)

    @classmethod
    def sound(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputSound = None
    ) -> "StoreBundleItem[SoundSocket]":
        """Create Store Bundle Item with operation 'Sound'."""
        return StoreBundleItem(socket_type="SOUND", bundle=bundle, path=path, item=item)

    @classmethod
    def auto(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputFloat = 0.0
    ) -> "StoreBundleItem[FloatSocket]":
        """Create Store Bundle Item with operation 'Auto'. Automatically detect a good structure type based on how the socket is used"""
        return StoreBundleItem(
            structure_type="AUTO", bundle=bundle, path=path, item=item
        )

    @classmethod
    def dynamic(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputFloat = 0.0
    ) -> "StoreBundleItem[FloatSocket]":
        """Create Store Bundle Item with operation 'Dynamic'. Socket can work with different kinds of structures"""
        return StoreBundleItem(
            structure_type="DYNAMIC", bundle=bundle, path=path, item=item
        )

    @classmethod
    def field(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputFloat = 0.0
    ) -> "StoreBundleItem[FloatSocket]":
        """Create Store Bundle Item with operation 'Field'. Socket expects a field"""
        return StoreBundleItem(
            structure_type="FIELD", bundle=bundle, path=path, item=item
        )

    @classmethod
    def grid(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputFloat = 0.0
    ) -> "StoreBundleItem[FloatSocket]":
        """Create Store Bundle Item with operation 'Grid'. Socket expects a grid"""
        return StoreBundleItem(
            structure_type="GRID", bundle=bundle, path=path, item=item
        )

    @classmethod
    def list(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputFloat = 0.0
    ) -> "StoreBundleItem[FloatSocket]":
        """Create Store Bundle Item with operation 'List'. Socket expects a list"""
        return StoreBundleItem(
            structure_type="LIST", bundle=bundle, path=path, item=item
        )

    @classmethod
    def single(
        cls, bundle: InputBundle = None, path: InputString = "", item: InputFloat = 0.0
    ) -> "StoreBundleItem[FloatSocket]":
        """Create Store Bundle Item with operation 'Single'. Socket expects a single value"""
        return StoreBundleItem(
            structure_type="SINGLE", bundle=bundle, path=path, item=item
        )

    @property
    def socket_type(
        self,
    ) -> Literal[
        "FLOAT",
        "INT",
        "BOOLEAN",
        "VECTOR",
        "RGBA",
        "ROTATION",
        "MATRIX",
        "STRING",
        "MENU",
        "OBJECT",
        "IMAGE",
        "GEOMETRY",
        "COLLECTION",
        "MATERIAL",
        "BUNDLE",
        "CLOSURE",
        "FONT",
        "SOUND",
    ]:
        return self.node.socket_type  # ty: ignore[invalid-return-type]

    @socket_type.setter
    def socket_type(
        self,
        value: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ],
    ):
        self.node.socket_type = value

    @property
    def structure_type(
        self,
    ) -> Literal["AUTO", "DYNAMIC", "FIELD", "GRID", "LIST", "SINGLE"]:
        return self.node.structure_type

    @structure_type.setter
    def structure_type(
        self, value: Literal["AUTO", "DYNAMIC", "FIELD", "GRID", "LIST", "SINGLE"]
    ):
        self.node.structure_type = value


class StringLength(BaseNode):
    """
    Output the number of characters in the given string

    Parameters
    ----------
    string : InputString
        String

    Inputs
    ------
    i.string : StringSocket
        String

    Outputs
    -------
    o.length : IntegerSocket
        Length
    """

    _bl_idname = "FunctionNodeStringLength"
    node: bpy.types.FunctionNodeStringLength

    class _Inputs(SocketAccessor):
        string: StringSocket
        """String"""

    class _Outputs(SocketAccessor):
        length: IntegerSocket
        """Length"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, string: InputString = ""):
        super().__init__()
        key_args = {"String": string}

        self._establish_links(**key_args)


class StringToValue(BaseNode, Generic[_T]):
    """
    Derive a numeric value from a given string representation

    Parameters
    ----------
    string : InputString
        String
    base : InputInteger
        Base

    Inputs
    ------
    i.string : StringSocket
        String
    i.base : IntegerSocket
        Base

    Outputs
    -------
    o.value : FloatSocket
        Value
    o.length : IntegerSocket
        Length
    """

    _bl_idname = "FunctionNodeStringToValue"
    node: bpy.types.FunctionNodeStringToValue

    class _Inputs(SocketAccessor):
        string: StringSocket
        """String"""
        base: IntegerSocket
        """Base"""

    class _Outputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""
        length: IntegerSocket
        """Length"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        string: InputString = "",
        base: InputInteger = 10,
        *,
        data_type: Literal["FLOAT", "INT"] = "FLOAT",
    ):
        super().__init__()
        key_args = {"String": string, "Base": base}
        self.data_type = data_type
        self._establish_links(**key_args)

    @classmethod
    def float(cls, string: InputString = "") -> "StringToValue[FloatSocket]":
        """Create String to Value with operation 'Float'. Floating-point value"""
        return StringToValue(data_type="FLOAT", string=string)

    @classmethod
    def integer(
        cls, string: InputString = "", base: InputInteger = 10
    ) -> "StringToValue[IntegerSocket]":
        """Create String to Value with operation 'Integer'. 32-bit integer"""
        return StringToValue(data_type="INT", string=string, base=base)

    @property
    def data_type(self) -> Literal["FLOAT", "INT"]:
        return self.node.data_type

    @data_type.setter
    def data_type(self, value: Literal["FLOAT", "INT"]):
        self.node.data_type = value


class Switch(BaseNode, Generic[_T]):
    """
    Switch between two inputs

    Parameters
    ----------
    switch : InputBoolean
        Switch
    false : InputFloat
        False
    true : InputFloat
        True

    Inputs
    ------
    i.switch : BooleanSocket
        Switch
    i.false : FloatSocket
        False
    i.true : FloatSocket
        True

    Outputs
    -------
    o.output : FloatSocket
        Output
    """

    _bl_idname = "GeometryNodeSwitch"
    node: bpy.types.GeometryNodeSwitch

    class _Inputs(SocketAccessor, Generic[_S]):
        switch: BooleanSocket
        """Switch"""
        false: _S
        """False"""
        true: _S
        """True"""

    class _Outputs(SocketAccessor, Generic[_S]):
        output: _S
        """Output"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs[_T]: ...

    def __init__(
        self,
        switch: InputBoolean = False,
        false: InputAny = 0.0,
        true: InputAny = 0.0,
        *,
        input_type: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ] = "FLOAT",
    ):
        super().__init__()
        key_args = {"Switch": switch, "False": false, "True": true}
        self.input_type = input_type
        self._establish_links(**key_args)

    @classmethod
    def float(
        cls,
        switch: InputBoolean = False,
        false: InputFloat = 0.0,
        true: InputFloat = 0.0,
    ) -> "Switch[FloatSocket]":
        """Create Switch with operation 'Float'."""
        return Switch(input_type="FLOAT", switch=switch, false=false, true=true)

    @classmethod
    def integer(
        cls,
        switch: InputBoolean = False,
        false: InputInteger = 0,
        true: InputInteger = 0,
    ) -> "Switch[IntegerSocket]":
        """Create Switch with operation 'Integer'."""
        return Switch(input_type="INT", switch=switch, false=false, true=true)

    @classmethod
    def boolean(
        cls,
        switch: InputBoolean = False,
        false: InputBoolean = False,
        true: InputBoolean = False,
    ) -> "Switch[BooleanSocket]":
        """Create Switch with operation 'Boolean'."""
        return Switch(input_type="BOOLEAN", switch=switch, false=false, true=true)

    @classmethod
    def vector(
        cls,
        switch: InputBoolean = False,
        false: InputVector = None,
        true: InputVector = None,
    ) -> "Switch[VectorSocket]":
        """Create Switch with operation 'Vector'."""
        return Switch(input_type="VECTOR", switch=switch, false=false, true=true)

    @classmethod
    def color(
        cls,
        switch: InputBoolean = False,
        false: InputColor = None,
        true: InputColor = None,
    ) -> "Switch[ColorSocket]":
        """Create Switch with operation 'Color'."""
        return Switch(input_type="RGBA", switch=switch, false=false, true=true)

    @classmethod
    def rotation(
        cls,
        switch: InputBoolean = False,
        false: InputRotation = None,
        true: InputRotation = None,
    ) -> "Switch[RotationSocket]":
        """Create Switch with operation 'Rotation'."""
        return Switch(input_type="ROTATION", switch=switch, false=false, true=true)

    @classmethod
    def matrix(
        cls,
        switch: InputBoolean = False,
        false: InputMatrix = None,
        true: InputMatrix = None,
    ) -> "Switch[MatrixSocket]":
        """Create Switch with operation 'Matrix'."""
        return Switch(input_type="MATRIX", switch=switch, false=false, true=true)

    @classmethod
    def string(
        cls,
        switch: InputBoolean = False,
        false: InputString = "",
        true: InputString = "",
    ) -> "Switch[StringSocket]":
        """Create Switch with operation 'String'."""
        return Switch(input_type="STRING", switch=switch, false=false, true=true)

    @classmethod
    def menu(
        cls,
        switch: InputBoolean = False,
        false: InputMenu = None,
        true: InputMenu = None,
    ) -> "Switch[MenuSocket]":
        """Create Switch with operation 'Menu'."""
        return Switch(input_type="MENU", switch=switch, false=false, true=true)

    @classmethod
    def object(
        cls,
        switch: InputBoolean = False,
        false: InputObject = None,
        true: InputObject = None,
    ) -> "Switch[ObjectSocket]":
        """Create Switch with operation 'Object'."""
        return Switch(input_type="OBJECT", switch=switch, false=false, true=true)

    @classmethod
    def image(
        cls,
        switch: InputBoolean = False,
        false: InputImage = None,
        true: InputImage = None,
    ) -> "Switch[ImageSocket]":
        """Create Switch with operation 'Image'."""
        return Switch(input_type="IMAGE", switch=switch, false=false, true=true)

    @classmethod
    def geometry(
        cls,
        switch: InputBoolean = False,
        false: InputGeometry = None,
        true: InputGeometry = None,
    ) -> "Switch[GeometrySocket]":
        """Create Switch with operation 'Geometry'."""
        return Switch(input_type="GEOMETRY", switch=switch, false=false, true=true)

    @classmethod
    def collection(
        cls,
        switch: InputBoolean = False,
        false: InputCollection = None,
        true: InputCollection = None,
    ) -> "Switch[CollectionSocket]":
        """Create Switch with operation 'Collection'."""
        return Switch(input_type="COLLECTION", switch=switch, false=false, true=true)

    @classmethod
    def material(
        cls,
        switch: InputBoolean = False,
        false: InputMaterial = None,
        true: InputMaterial = None,
    ) -> "Switch[MaterialSocket]":
        """Create Switch with operation 'Material'."""
        return Switch(input_type="MATERIAL", switch=switch, false=false, true=true)

    @classmethod
    def bundle(
        cls,
        switch: InputBoolean = False,
        false: InputBundle = None,
        true: InputBundle = None,
    ) -> "Switch[BundleSocket]":
        """Create Switch with operation 'Bundle'."""
        return Switch(input_type="BUNDLE", switch=switch, false=false, true=true)

    @classmethod
    def closure(
        cls,
        switch: InputBoolean = False,
        false: InputClosure = None,
        true: InputClosure = None,
    ) -> "Switch[ClosureSocket]":
        """Create Switch with operation 'Closure'."""
        return Switch(input_type="CLOSURE", switch=switch, false=false, true=true)

    @classmethod
    def font(
        cls,
        switch: InputBoolean = False,
        false: InputFont = None,
        true: InputFont = None,
    ) -> "Switch[FontSocket]":
        """Create Switch with operation 'Font'."""
        return Switch(input_type="FONT", switch=switch, false=false, true=true)

    @classmethod
    def sound(
        cls,
        switch: InputBoolean = False,
        false: InputSound = None,
        true: InputSound = None,
    ) -> "Switch[SoundSocket]":
        """Create Switch with operation 'Sound'."""
        return Switch(input_type="SOUND", switch=switch, false=false, true=true)

    @property
    def input_type(
        self,
    ) -> Literal[
        "FLOAT",
        "INT",
        "BOOLEAN",
        "VECTOR",
        "RGBA",
        "ROTATION",
        "MATRIX",
        "STRING",
        "MENU",
        "OBJECT",
        "IMAGE",
        "GEOMETRY",
        "COLLECTION",
        "MATERIAL",
        "BUNDLE",
        "CLOSURE",
        "FONT",
        "SOUND",
    ]:
        return self.node.input_type  # ty: ignore[invalid-return-type]

    @input_type.setter
    def input_type(
        self,
        value: Literal[
            "FLOAT",
            "INT",
            "BOOLEAN",
            "VECTOR",
            "RGBA",
            "ROTATION",
            "MATRIX",
            "STRING",
            "MENU",
            "OBJECT",
            "IMAGE",
            "GEOMETRY",
            "COLLECTION",
            "MATERIAL",
            "BUNDLE",
            "CLOSURE",
            "FONT",
            "SOUND",
        ],
    ):
        self.node.input_type = value


class TagFilter(BaseNode):
    """
    Check if a filter string matches a list of tags

    Parameters
    ----------
    tag_filter : InputString
        Tag Filter
    tags : InputString
        Tags

    Inputs
    ------
    i.tag_filter : StringSocket
        Tag Filter
    i.tags : StringSocket
        Tags

    Outputs
    -------
    o.match : BooleanSocket
        Match
    """

    _bl_idname = "GeometryNodeTagFilter"
    node: bpy.types.GeometryNodeTagFilter  # ty: ignore[unresolved-attribute]

    class _Inputs(SocketAccessor):
        tag_filter: StringSocket
        """Tag Filter"""
        tags: StringSocket
        """Tags"""

    class _Outputs(SocketAccessor):
        match: BooleanSocket
        """Match"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        tag_filter: InputString = "",
        tags: InputString = "",
    ):
        super().__init__()
        key_args = {"Tag Filter": tag_filter, "Tags": tags}

        self._establish_links(**key_args)


class TransformDirection(BaseNode):
    """
    Apply a transformation matrix (excluding translation) to the given vector

    Parameters
    ----------
    direction : InputVector
        Direction
    transform : InputMatrix
        Transform

    Inputs
    ------
    i.direction : VectorSocket
        Direction
    i.transform : MatrixSocket
        Transform

    Outputs
    -------
    o.direction : VectorSocket
        Direction
    """

    _bl_idname = "FunctionNodeTransformDirection"
    node: bpy.types.FunctionNodeTransformDirection

    class _Inputs(SocketAccessor):
        direction: VectorSocket
        """Direction"""
        transform: MatrixSocket
        """Transform"""

    class _Outputs(SocketAccessor):
        direction: VectorSocket
        """Direction"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        direction: InputVector = None,
        transform: InputMatrix = None,
    ):
        super().__init__()
        key_args = {"Direction": direction, "Transform": transform}

        self._establish_links(**key_args)


class TransformPoint(BaseNode):
    """
    Apply a transformation matrix to the given vector

    Parameters
    ----------
    vector : InputVector
        Vector
    transform : InputMatrix
        Transform

    Inputs
    ------
    i.vector : VectorSocket
        Vector
    i.transform : MatrixSocket
        Transform

    Outputs
    -------
    o.vector : VectorSocket
        Vector
    """

    _bl_idname = "FunctionNodeTransformPoint"
    node: bpy.types.FunctionNodeTransformPoint

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""
        transform: MatrixSocket
        """Transform"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        vector: InputVector = None,
        transform: InputMatrix = None,
    ):
        super().__init__()
        key_args = {"Vector": vector, "Transform": transform}

        self._establish_links(**key_args)


class TransposeMatrix(BaseNode):
    """
    Flip a matrix over its diagonal, turning columns into rows and vice-versa

    Parameters
    ----------
    matrix : InputMatrix
        Matrix

    Inputs
    ------
    i.matrix : MatrixSocket
        Matrix

    Outputs
    -------
    o.matrix : MatrixSocket
        Matrix
    """

    _bl_idname = "FunctionNodeTransposeMatrix"
    node: bpy.types.FunctionNodeTransposeMatrix

    class _Inputs(SocketAccessor):
        matrix: MatrixSocket
        """Matrix"""

    class _Outputs(SocketAccessor):
        matrix: MatrixSocket
        """Matrix"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self, matrix: InputMatrix = None):
        super().__init__()
        key_args = {"Matrix": matrix}

        self._establish_links(**key_args)


class TrimString(BaseNode):
    """
    Remove characters from the beginning and end of a string

    Parameters
    ----------
    string : InputString
        String
    characters : InputString
        Characters
    whitespace : InputBoolean
        Whitespace
    start : InputBoolean
        Start
    end : InputBoolean
        End

    Inputs
    ------
    i.string : StringSocket
        String
    i.characters : StringSocket
        Characters
    i.whitespace : BooleanSocket
        Whitespace
    i.start : BooleanSocket
        Start
    i.end : BooleanSocket
        End

    Outputs
    -------
    o.string : StringSocket
        String
    """

    _bl_idname = "FunctionNodeTrimString"
    node: bpy.types.FunctionNodeTrimString

    class _Inputs(SocketAccessor):
        string: StringSocket
        """String"""
        characters: StringSocket
        """Characters"""
        whitespace: BooleanSocket
        """Whitespace"""
        start: BooleanSocket
        """Start"""
        end: BooleanSocket
        """End"""

    class _Outputs(SocketAccessor):
        string: StringSocket
        """String"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        string: InputString = "",
        characters: InputString = "",
        whitespace: InputBoolean = True,
        start: InputBoolean = True,
        end: InputBoolean = True,
    ):
        super().__init__()
        key_args = {
            "String": string,
            "Characters": characters,
            "Whitespace": whitespace,
            "Start": start,
            "End": end,
        }

        self._establish_links(**key_args)


class UVUnwrap(BaseNode):
    """
    Generate a UV map based on seam edges

    Parameters
    ----------
    selection : InputBoolean
        Selection
    seam : InputBoolean
        Seam
    margin : InputFloat
        Margin
    fill_holes : InputBoolean
        Fill Holes
    method : InputMenu | Literal['Angle Based', 'Conformal', 'Minimum Stretch']
        Method
    iterations : InputInteger
        Iterations
    no_flip : InputBoolean
        No Flip

    Inputs
    ------
    i.selection : BooleanSocket
        Selection
    i.seam : BooleanSocket
        Seam
    i.margin : FloatSocket
        Margin
    i.fill_holes : BooleanSocket
        Fill Holes
    i.method : MenuSocket
        Method
    i.iterations : IntegerSocket
        Iterations
    i.no_flip : BooleanSocket
        No Flip

    Outputs
    -------
    o.uv : VectorSocket
        UV
    """

    _bl_idname = "GeometryNodeUVUnwrap"
    node: bpy.types.GeometryNodeUVUnwrap

    class _Inputs(SocketAccessor):
        selection: BooleanSocket
        """Selection"""
        seam: BooleanSocket
        """Seam"""
        margin: FloatSocket
        """Margin"""
        fill_holes: BooleanSocket
        """Fill Holes"""
        method: MenuSocket
        """Method"""
        iterations: IntegerSocket
        """Iterations"""
        no_flip: BooleanSocket
        """No Flip"""

    class _Outputs(SocketAccessor):
        uv: VectorSocket
        """UV"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        selection: InputBoolean = True,
        seam: InputBoolean = False,
        margin: InputFloat = 0.001,
        fill_holes: InputBoolean = True,
        method: InputMenu
        | Literal["Angle Based", "Conformal", "Minimum Stretch"] = "Angle Based",
        iterations: InputInteger = 10,
        no_flip: InputBoolean = False,
    ):
        super().__init__()
        key_args = {
            "Selection": selection,
            "Seam": seam,
            "Margin": margin,
            "Fill Holes": fill_holes,
            "Method": method,
            "Iterations": iterations,
            "No Flip": no_flip,
        }

        self._establish_links(**key_args)


class ValueToString(BaseNode, Generic[_T]):
    """
    Generate a string representation of the given input value

    Parameters
    ----------
    value : InputFloat
        Value
    decimals : InputInteger
        Decimals
    base : InputInteger
        Base
    padding : InputInteger
        Padding

    Inputs
    ------
    i.value : FloatSocket
        Value
    i.decimals : IntegerSocket
        Decimals
    i.base : IntegerSocket
        Base
    i.padding : IntegerSocket
        Padding

    Outputs
    -------
    o.string : StringSocket
        String
    """

    _bl_idname = "FunctionNodeValueToString"
    node: bpy.types.FunctionNodeValueToString

    class _Inputs(SocketAccessor, Generic[_S]):
        value: _S
        """Value"""
        decimals: IntegerSocket
        """Decimals"""
        base: IntegerSocket
        """Base"""
        padding: IntegerSocket
        """Padding"""

    class _Outputs(SocketAccessor):
        string: StringSocket
        """String"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs[_T]: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        value: InputAny = 0.0,
        decimals: InputInteger = 0,
        base: InputInteger = 10,
        padding: InputInteger = 0,
        *,
        data_type: Literal["FLOAT", "INT"] = "FLOAT",
    ):
        super().__init__()
        key_args = {
            "Value": value,
            "Decimals": decimals,
            "Base": base,
            "Padding": padding,
        }
        self.data_type = data_type
        self._establish_links(**key_args)

    @classmethod
    def float(
        cls, value: InputFloat = 0.0, decimals: InputInteger = 0
    ) -> "ValueToString[FloatSocket]":
        """Create Value to String with operation 'Float'. Floating-point value"""
        return ValueToString(data_type="FLOAT", value=value, decimals=decimals)

    @classmethod
    def integer(
        cls, value: InputInteger = 0, base: InputInteger = 10, padding: InputInteger = 0
    ) -> "ValueToString[IntegerSocket]":
        """Create Value to String with operation 'Integer'. 32-bit integer"""
        return ValueToString(data_type="INT", value=value, base=base, padding=padding)

    @property
    def data_type(self) -> Literal["FLOAT", "INT"]:
        return self.node.data_type

    @data_type.setter
    def data_type(self, value: Literal["FLOAT", "INT"]):
        self.node.data_type = value
