
    Cjֲ              	      \   % S r SSKJr  SSKrSSKJr  SSKJrJr  SSK	J
r
JrJrJrJrJrJrJrJrJr  SSKJr  \
(       a  SSKJr  SSKr\\\\   \\\4   \\\\\4   4   rS	\S
'    \" S\\5      rSS jr " S S\5      r " S S\5      r  " S S\5      r! " S S\5      r" " S S5      r#\
(       d-  \RH                  RK                  SS5      S:X  a   SSK&JrJ!r!J r J"r"  \" SS5      r(S\S'    \!" SSSS5      r)S\S'    \ " SS5      r*S\S'    \"" SSSS5      r+S\S'   g! \' a     NHf = f) zd

Functions and classes to manage terminal geometry (anything involving coordinates or dimensions).
    )annotationsN)	lru_cache)
attrgetter
itemgetter)
TYPE_CHECKINGAny
CollectionIterableLiteral
NamedTupleTupleTypeVarUnioncast)Final)	TypeAliasr   SpacingDimensionsTc                L    X:  a  X:  a  U$ X:  a  U$ U $ X:  a  U$ X:  a  U$ U $ )a  Restrict a value to a given range.

If `value` is less than the minimum, return the minimum.
If `value` is greater than the maximum, return the maximum.
Otherwise, return `value`.

The `minimum` and `maximum` arguments values may be given in reverse order.

Args:
    value: A value.
    minimum: Minimum value.
    maximum: Maximum value.

Returns:
    New value that is not less than the minimum or greater than the maximum.
 )valueminimummaximums      b/home/rurouni/.local/share/pipx/venvs/strix-agent/lib/python3.13/site-packages/textual/geometry.pyclampr   '   s>    "  ?N?N?N?N    c                      \ rS rSr% SrSrS\S'    SrS\S'    \SS j5       r	\SS j5       r
\SS	 j5       rSS
 jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSrg)OffsetH   a2  A cell offset defined by x and y coordinates.

Offsets are typically relative to the top left of the terminal or other container.

Textual prefers the names `x` and `y`, but you could consider `x` to be the _column_ and `y` to be the _row_.

Offsets support addition, subtraction, multiplication, and negation.

Example:
    ```python
    >>> from textual.geometry import Offset
    >>> offset = Offset(3, 2)
    >>> offset
    Offset(x=3, y=2)
    >>> offset += Offset(10, 0)
    >>> offset
    Offset(x=13, y=2)
    >>> -offset
    Offset(x=-13, y=-2)
    ```
r   intxyc                    U S:H  $ )zIs the offset at (0, 0)?r   r   r   selfs    r   	is_originOffset.is_origind   s     v~r   c                J    U u  p[        US:  a  SOUUS:  a  S5      $ U5      $ )z=This offset with `x` and `y` restricted to values above zero.r   r   r&   r!   r"   s      r   clampedOffset.clampedi   s.     1q5aaa!e;;;;r   c                    U u  pX!4$ )z2A tuple of x and y, in reverse order, i.e. (y, x).r   r+   s      r   	transposeOffset.transposeo   s     tr   c                    U S:g  $ )Nr$   r   r%   s    r   __bool__Offset.__bool__u   s    v~r   c                h    [        U[        5      (       a  U u  p#Uu  pE[        X$-   X5-   5      $ [        $ N
isinstancetupler   NotImplementedr&   other_x_yr!   r"   s         r   __add__Offset.__add__x   4    eU##FBDA"&"&))r   c                h    [        U[        5      (       a  U u  p#Uu  pE[        X$-
  X5-
  5      $ [        $ r5   r6   r:   s         r   __sub__Offset.__sub__   r@   r   c                   [        U[        [        45      (       a&  U u  p#[        [        X!-  5      [        X1-  5      5      $ [        U[        5      (       a,  U u  p#[        [        X!S   -  5      [        X1S   -  5      5      $ [
        $ )Nr      )r7   floatr    r   r8   r9   )r&   r;   r!   r"   s       r   __mul__Offset.__mul__   sp    eeS\**DA#ai.#ai.99eU##DA#a(l+S1X->??r   c                &    U u  p[        U* U* 5      $ r5   r*   r+   s      r   __neg__Offset.__neg__   s    qb1"~r   c                n    U u  p4Uu  pV[        [        X5U-
  U-  -   5      [        XFU-
  U-  -   5      5      $ )zCalculate a new offset on a line between this offset and a destination offset.

Args:
    destination: Point where factor would be 1.0.
    factor: A value between 0 and 1.0.

Returns:
    A new point on a line between self and destination.
)r   r    )r&   destinationfactorx1y1x2y2s          r   blendOffset.blend   sG     2g''(2g''(
 	
r   c                B    U u  p#Uu  pEXB-
  XB-
  -  XS-
  XS-
  -  -   S-  nU$ )ziGet the distance to another offset.

Args:
    other: An offset.

Returns:
    Distance to other offset.
g      ?r   )r&   r;   rO   rP   rQ   rR   distances          r   get_distance_toOffset.get_distance_to   s8     G0BG3HHSPr   c           	     Z    U u  p4[        [        USUS-
  5      [        USUS-
  5      5      $ )zClamp the offset to fit within a rectangle of width x height.

Args:
    width: Width to clamp.
    height: Height to clamp.

Returns:
    A new offset.
r   rE   )r   r   )r&   widthheightr!   r"   s        r   r   Offset.clamp   s2     eAq%!),eAq&1*.EFFr   r   Nreturnboolr^   r   r^   tuple[int, int])r;   objectr^   r   )rM   r   rN   rF   r^   r   )r;   r   r^   rF   )rZ   r    r[   r    r^   r   )__name__
__module____qualname____firstlineno____doc__r!   __annotations__r"   propertyr'   r,   r/   r2   r>   rB   rG   rJ   rS   rW   r   __static_attributes__r   r   r   r   r   H   s    , AsJ+AsJ)  < <
  

"Gr   r   c                      \ rS rSr% SrSrS\S'    SrS\S'    SS jr\	SS j5       r
\	SS	 j5       r\	SS
 j5       rSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSrg) Size   a  The dimensions (width and height) of a rectangular region.

Example:
    ```python
    >>> from textual.geometry import Size
    >>> size = Size(2, 3)
    >>> size
    Size(width=2, height=3)
    >>> size.area
    6
    >>> size + Size(10, 20)
    Size(width=12, height=23)
    ```
r   r    rZ   r[   c                :    U R                   U R                  -  S:g  $ )z!A Size is Falsy if it has area 0.r   rZ   r[   r%   s    r   r2   Size.__bool__   s    zzDKK'1,,r   c                4    U R                   U R                  -  $ )z+The area occupied by a region of this size.rp   r%   s    r   area	Size.area        zzDKK''r   c                $    U u  p[        SSX5      $ )z)A region of the same size, at the origin.r   Region)r&   rZ   r[   s      r   regionSize.region   s     aE**r   c                ,    [        U R                  5      $ )z9A range object that covers values between 0 and `height`.)ranger[   r%   s    r   
line_rangeSize.line_range   s     T[[!!r   c                ,    [        XR                  5      $ )zjGet a new Size with just the width changed.

Args:
    width: New width.

Returns:
    New Size instance.
)rm   r[   )r&   rZ   s     r   
with_widthSize.with_width   s     E;;''r   c                .    [        U R                  U5      $ )zmGet a new Size with just the height changed.

Args:
    height: New height.

Returns:
    New Size instance.
)rm   rZ   )r&   r[   s     r   with_heightSize.with_height   s     DJJ''r   c                    [        U[        5      (       a,  U u  p#Uu  pE[        [        SX$-   5      [        SX5-   5      5      $ [        $ Nr   r7   r8   rm   maxr9   r&   r;   rZ   r[   width2height2s         r   r>   Size.__add__   C    eU## ME#OFAu~.Av7G0HIIr   c                    [        U[        5      (       a,  U u  p#Uu  pE[        [        SX$-
  5      [        SX5-
  5      5      $ [        $ r   r   r   s         r   rB   Size.__sub__  r   r   c                h    U u  p4X1s=:  =(       a    S:  Os  =(       a    XBs=:  =(       a    S:  $ s  $ )zCheck if a point is in area defined by the size.

Args:
    x: X coordinate.
    y: Y coordinate.

Returns:
    True if the point is within the region.
r   r   r&   r!   r"   rZ   r[   s        r   containsSize.contains  s+     ~~A~1&///1/1r   c                p    Uu  p#U u  pEXBs=:  =(       a    S:  Os  =(       a    XSs=:  =(       a    S:  $ s  $ )zCheck if a point is in the area defined by the size.

Args:
    point: A tuple of x and y coordinates.

Returns:
    True if the point is within the region.
r   r   )r&   pointr!   r"   rZ   r[   s         r   contains_pointSize.contains_point  s2     ~~A~1&///1/1r   c                     Uu  p#U u  pEXBs=:  =(       a    S:  Os  =(       a    XSs=:  =(       a    S:  $ s  $ ! [          a    [        S5      ef = f)Nz<Dimensions.__contains__ requires an iterable of two integersr   )	Exception	TypeError)r&   r;   r!   r"   rZ   r[   s         r   __contains__Size.__contains__(  sZ    	 DA
 ~~A~1&///1/1  	N 	s	   9 Ac                N    UR                  U R                  U R                  5      $ )zClamp an offset to fit within the width x height.

Args:
    offset: An offset.

Returns:
    A new offset that will fit inside the dimensions defined in the Size.
)r   rZ   r[   r&   offsets     r   clamp_offsetSize.clamp_offset4  s     ||DJJ44r   r   Nr]   r^   r    r^   rx   r^   r|   )rZ   r    r^   rm   )r[   r    r^   rm   )r;   rc   r^   rm   r!   r    r"   r    r^   r_   r   rb   r^   r_   r;   r   r^   r_   )r   r   r^   r   )rd   re   rf   rg   rh   rZ   ri   r[   r2   rj   rs   ry   r}   r   r   r>   rB   r   r   r   r   rk   r   r   r   rm   rm      s     E3NFCO- ( ( + +
 " "	(	(22
2	5r   rm   c                     \ rS rSr% SrSrS\S'    SrS\S'    SrS\S'    Sr	S\S'    \
S<S	 j5       r\
S=S
 j5       r\
S>S j5       r\
SS.       S?S jj5       rS@S jr\SAS j5       r\SAS j5       r\SBS j5       r\SBS j5       r\SBS j5       r\SCS j5       r\SDS j5       r\SCS j5       r\SCS j5       r\SCS j5       r\SCS j5       r\SES j5       r\SFS j5       r\SGS j5       r\SGS j5       r\SHS j5       r SIS  jr!SIS! jr"SJS" jr#SKS# jr$SLS$ jr%SLS% jr&\'" S&S'9SMS( j5       r(SNS) jr)SOS* jr*\'" S&S'9SMS+ j5       r+\'" S&S'9SKS, j5       r,\'" S-S'9SPS. j5       r-SQS/ jr.\'" S-S'9SRS0 j5       r/\'" S-S'9SRS1 j5       r0\'" S-S'9SSS2 j5       r1\'" S-S'9SSS3 j5       r2\'" S&S'9STS4 j5       r3\'" S&S'9SUS5 j5       r4\'" S&S'9SUS6 j5       r5 SV       SWS7 jjr6 SX       SYS9 jjr7          SZS: jr8S;r9g8)[rx   i@  uu  Defines a rectangular region.

A Region consists of a coordinate (x and y) and dimensions (width and height).

```
  (x, y)
    ┌────────────────────┐ ▲
    │                    │ │
    │                    │ │
    │                    │ height
    │                    │ │
    │                    │ │
    └────────────────────┘ ▼
    ◀─────── width ──────▶
```

Example:
    ```python
    >>> from textual.geometry import Region
    >>> region = Region(4, 5, 20, 10)
    >>> region
    Region(x=4, y=5, width=20, height=10)
    >>> region.area
    200
    >>> region.size
    Size(width=20, height=10)
    >>> region.offset
    Offset(x=4, y=5)
    >>> region.contains(1, 2)
    False
    >>> region.contains(10, 8)
    True
    ```
r   r    r!   r"   rZ   r[   c                *   U(       d  [        S5      e[        U[        S5      S9R                  n[	        U[        S5      S9R                  n[        U[        S5      S9R                  n[	        U[        S5      S9R                  nU " X$X2-
  XT-
  5      $ )zCreate a Region from the union of other regions.

Args:
    regions: One or more regions.

Returns:
    A Region that encloses all other regions.
zAt least one region expectedr   keyrightrE   bottom)	
ValueErrorminr   r!   r   r   r   r"   r   )clsregionsmin_xmax_xmin_ymax_ys         r   
from_unionRegion.from_unionm  s     ;<<GA/11GG!45;;GA/11GH!56==5>>r   c                    U " XX1-
  XB-
  5      $ )zConstruct a Region form the top left and bottom right corners.

Args:
    x1: Top left x.
    y1: Top left y.
    x2: Bottom right x.
    y2: Bottom right y.

Returns:
    A new region.
r   )r   rO   rP   rQ   rR   s        r   from_cornersRegion.from_corners  s     227BG,,r   c                $    Uu  p4Uu  pVU " X4XV5      $ )zCreate a region from offset and size.

Args:
    offset: Offset (top left point).
    size: Dimensions of region.

Returns:
    A region instance.
r   )r   r   sizer!   r"   rZ   r[   s          r   from_offsetRegion.from_offset  s     1''r   F)topc                  X!;   a  U(       d  [         $ UR                  u  pEpgUR                  UR                  5      nUR                  u  ppS=pXhs=:  a  U:  a  O  OXjs=:  a  U:  d"  O  [	        X-
  XUR
                  -
  -
  [        S9nU(       a  X-
  nO=Xys=:  a  U:  a  O  OX{s=:  a  U:  d"  O  [	        X-
  XUR                  -
  -
  [        S9n[        X5      $ )a  Calculate the smallest offset required to translate a window so that it contains
another region.

This method is used to calculate the required offset to scroll something into view.

Args:
    window_region: The window region.
    region: The region to move inside the window.
    top: Get offset to top of window.

Returns:
    An offset required to add to region to move it inside window_region.
r   r   )	NULL_OFFSETcorners	crop_sizer   r   rZ   absr[   r   )r   window_regionry   r   window_left
window_topwindow_rightwindow_bottomlefttop_r   r   delta_xdelta_ys                 r   get_scroll_to_visibleRegion.get_scroll_to_visible  s    $ "3?L?T?T<!!-"4"45$*NN!E /K/44 "v||34G 'G /Z/5:5 !56G
 g''r   c                    U u    pnX#-  S:  $ )z1A Region is considered False when it has no area.r   r   r&   _rZ   r[   s       r   r2   Region.__bool__  s    "1V~!!r   c                L    U R                   U R                   U R                  -   4$ )zpA pair of integers for the start and end columns (x coordinates) in this region.

The end value is *exclusive*.
r!   rZ   r%   s    r   column_spanRegion.column_span  s      +,,r   c                L    U R                   U R                   U R                  -   4$ )znA pair of integers for the start and end lines (y coordinates) in this region.

The end value is *exclusive*.
r"   r[   r%   s    r   	line_spanRegion.line_span  s      ,--r   c                4    U R                   U R                  -   $ )z Maximum X value (non inclusive).r   r%   s    r   r   Region.right  s     vv

""r   c                4    U R                   U R                  -   $ )z Maximum Y value (non inclusive).r   r%   s    r   r   Region.bottom  s     vv##r   c                4    U R                   U R                  -  $ )zThe area under the region.rp   r%   s    r   rs   Region.area  ru   r   c                    [        U SS 6 $ )z<The top left corner of the region.

Returns:
    An offset.
N   r*   r%   s    r   r   Region.offset  s     tBQx  r   c                (    U u  pp4XS-  -   X$S-  -   4$ )zThe center of the region.

Note, that this does *not* return an `Offset`, because the center may not be an integer coordinate.

Returns:
    Tuple of floats.
g       @r   r   s        r   centerRegion.center   s&     #eCKc\!122r   c                (    U u  pp4[        XU-   5      $ )z;Bottom left offset of the region.

Returns:
    An offset.
r*   )r&   r!   r"   _widthr[   s        r   bottom_leftRegion.bottom_left  s      $faV$$r   c                (    U u  pp4[        X-   U5      $ )z9Top right offset of the region.

Returns:
    An offset.
r*   )r&   r!   r"   rZ   _heights        r   	top_rightRegion.top_right  s      $eai##r   c                ,    U u  pp4[        X-   X$-   5      $ )z<Bottom right offset of the region.

Returns:
    An offset.
r*   r   s        r   bottom_rightRegion.bottom_right   s     #eai,,r   c                8    U u  pp4[        X-   S-
  X$-   S-
  5      $ )z9Bottom right corner of the region, within its boundaries.rE   r*   r   s        r   bottom_right_inclusiveRegion.bottom_right_inclusive*  s'     #eai!mQZ!^44r   c                    [        U SS 6 $ )zGet the size of the region.r   N)rm   r%   s    r   r   Region.size0  s     T!"Xr   c                    U u  pp4XX-   X$-   4$ )zFThe top left and bottom right coordinates as a tuple of four integers.r   r   s        r   r   Region.corners5  s     #eQY
**r   c                \    [        U R                  U R                  U R                  -   5      $ )z!A range object for X coordinates.)r|   r!   rZ   r%   s    r   column_rangeRegion.column_range;  s"     TVVTVVdjj011r   c                \    [        U R                  U R                  U R                  -   5      $ )z!A range object for Y coordinates.)r|   r"   r[   r%   s    r   r}   Region.line_range@  s"     TVVTVVdkk122r   c                (    U u    pn[        SSX#5      $ )zLAn region of the same size at (0, 0).

Returns:
    A region at the origin.
r   rw   r   s       r   reset_offsetRegion.reset_offsetE  s     #1VaE**r   c                l    [        U[        5      (       a  Uu  p#U u  pEpg[        XB-   XS-   Xg5      $ [        $ r5   r7   r8   rx   r9   r&   r;   oxoyr!   r"   rZ   r[   s           r   r>   Region.__add__O  9    eU##FB"&A%!&!&%88r   c                l    [        U[        5      (       a  Uu  p#U u  pEpg[        XB-
  XS-
  Xg5      $ [        $ r5   r  r  s           r   rB   Region.__sub__V  r  r   c                    [        UR                  U R                  -
  U R                  UR                  -
  U R                  UR                  -
  UR                  U R                  -
  5      $ )zGet spacing between two regions.

Args:
    region: Another region.

Returns:
    Spacing that if subtracted from `self` produces `region`.
)Spacingr"   r   r   r!   r&   ry   s     r   get_spacing_betweenRegion.get_spacing_between]  sQ     HHtvvJJ%KK&--'HHtvv	
 	
r   c                ,    Uu  p#U u  pEpg[        X#Xg5      $ )zGet a new Region with the same size at a given offset.

Args:
    offset: An offset.

Returns:
    New Region with adjusted offset.
rw   )r&   r   r!   r"   r<   r=   rZ   r[   s           r   	at_offsetRegion.at_offsetm  s"      $aE**r   c           	     R    U u  p#pEUu  pg[        X#[        XF5      [        XW5      5      $ )zGet a region with the same offset, with a size no larger than `size`.

Args:
    size: Maximum width and height (WIDTH, HEIGHT).

Returns:
    New region that could fit within `size`.
)rx   r   )r&   r   r!   r"   width1height1r   r   s           r   r   Region.crop_sizez  s.     !%faC/W1FGGr   c                L    Uu  p#U u  pEpg[        XB-
  XS-
  XbS-  -   XsS-  -   5      $ )z~Increase the size of the region by adding a border.

Args:
    size: Additional width and height.

Returns:
    A new region.
r   rw   )r&   r   expand_widthexpand_heightr!   r"   rZ   r[   s           r   expandRegion.expand  sE     '+#"e1$$Q&&	
 	
r   i   )maxsizec                `   U R                   u  p#pEUR                   u  pgpXFs=:  =(       a    U:  Os  =(       d*    XHs=:  =(       a    U:  Os  =(       d    Xb:  =(       a    X:  =(       aE    XWs=:  =(       a    U:  Os  =(       d*    XYs=:  =(       a    U:  Os  =(       d    Xs:  =(       a    X:  $ )zCheck if another region overlaps this region.

Args:
    other: A Region.

Returns:
    True if other region shares any cells with this region.
r   )
r&   r;   r!   r"   rQ   rR   r  r  ox2oy2s
             r   overlapsRegion.overlaps  su     ||b ==AJ2<<a<JRV5I	 
\\\Fr||!|F1ECI	
r   c                v    U u  p4pVX5-   Us=:  =(       a    U:  Os  =(       a    XF-   Us=:  =(       a    U:  $ s  $ )zCheck if a point is in the region.

Args:
    x: X coordinate.
    y: Y coordinate.

Returns:
    True if the point is within the region.
r   )r&   r!   r"   self_xself_yrZ   r[   s          r   r   Region.contains  s=     )-%,,f,Q6?Q3P3P&3PQ3PQr   c                    U R                   u  p#pE Uu  pgXFs=:  =(       a    U:  Os  =(       a    XWs=:  =(       a    U:  $ s  $ ! [         a    [        SU< 35      ef = f)zCheck if a point is in the region.

Args:
    point: A tuple of x and y coordinates.

Returns:
    True if the point is within the region.
z)a tuple of two integers is required, not )r   r   r   )r&   r   rO   rP   rQ   rR   r  r  s           r   r   Region.contains_point  sf     	SFB 22BMMrM2M2  	SGyQRR	Ss   A Ac                   U R                   u  p#pEUR                   u  pgpXFs=:  =(       a    U:  Os  =(       aJ    XWs=:  =(       a    U:  Os  =(       a/    XHs=:  =(       a    U:  Os  =(       a    XYs=:  =(       a    U:  $ s  $ )zCheck if a region is entirely contained within this region.

Args:
    other: A region.

Returns:
    True if the other region fits perfectly within this region.
r  )
r&   r;   rO   rP   rQ   rR   r  r  r  r   s
             r   contains_regionRegion.contains_region  sk      ==^^^ "R"b" b		
 !		
r   c                6    U u  p#pEUu  pg[        X&-   X7-   XE5      $ )zyMove the offset of the Region.

Args:
    offset: Offset to add to region.

Returns:
    A new region shifted by (x, y).
rw   )r&   r   r$  r%  rZ   r[   offset_xoffset_ys           r   	translateRegion.translate  s+     )-%#f'):EJJr   i   c                    [        U[        5      (       a  U R                  U5      $  U R                  U5      $ ! [         a     gf = f)z#Check if a point is in this region.F)r7   rx   r*  r   r   )r&   r;   s     r   r   Region.__contains__  sJ     eV$$''..**511 s   9 
AAc           
         U R                   u  p4pV[        n[        R                  " U" USU5      U" USU5      U" USU5      U" USU5      5      nU$ )zClip this region to fit within width, height.

Args:
    width: Width of bounds.
    height: Height of bounds.

Returns:
    Clipped region.
r   )r   r   rx   r   )	r&   rZ   r[   rO   rP   rQ   rR   _clamp
new_regions	            r   clipRegion.clip  s^     ((2q% 2q&!2q% 2q&!	

 r   c           
         [        U5      (       d  U $ Uu  p#pEU u  pgp[        Xe-
  Xr-
  [        SX-   U-   5      [        SX-   U-   5      S9$ )zGrow a region by adding spacing.

Args:
    margin: Grow space by `(<top>, <right>, <bottom>, <left>)`.

Returns:
    New region.
r   r!   r"   rZ   r[   anyrx   r   
r&   marginr   r   r   r   r!   r"   rZ   r[   s
             r   growRegion.grow	  s_     6{{K#) F"ehga-.q&,/0	
 	
r   c                    [        U5      (       d  U $ Uu  p#pEU u  pgp[        Xe-   Xr-   [        SXU-   -
  5      [        SXU-   -
  5      S9$ )zShrink a region by subtracting spacing.

Args:
    margin: Shrink space by `(<top>, <right>, <bottom>, <left>)`.

Returns:
    The new, smaller region.
r   r9  r:  r<  s
             r   shrinkRegion.shrink  s_     6{{K#) F"ehga,/0q&&L12	
 	
r   c                    U u  p#pEUu  pgpX$-   n
X5-   nXh-   nXy-   nX,:  a  UOX&:  a  UOUnX=:  a  UOX7:  a  UOUnX:  a  UOX:  a  UOU
nX:  a  UOX:  a  UOUn[        XUU-
  UU-
  5      $ )zGet the overlapping portion of the two regions.

Args:
    region: A region that overlaps this region.

Returns:
    A new region that covers when the two regions overlap.
rw   )r&   ry   rO   rP   w1h1cx1cy1w2h2rQ   rR   cx2cy2rx1ry1rx2ry2s                     r   intersectionRegion.intersection3  s     !"WWhhXc28CXc28CXc28CXc28Ccc	3955r   c           	         U R                   u  p#pEUR                   u  pgpU R                  [        X&5      [        X75      [        XH5      [        XY5      5      n
U
$ )zGet the smallest region that contains both regions.

Args:
    region: Another region.

Returns:
    An optimally sized region to cover both regions.
)r   r   r   r   )r&   ry   rO   rP   rQ   rR   ox1oy1r  r   union_regions              r   unionRegion.unionL  sP     #^^#((L#b,Bc"l
 r   c           
         U u  p4pVUS:  a  XQ-   nUS:  a  Xb-   n[         nU" X4X5      U" X1-   XEU-
  U5      U" X4U-   XU-
  5      U" X1-   XB-   XQ-
  Xb-
  5      4$ )u  Split a region into 4 from given x and y offsets (cuts).

```
           cut_x ↓
        ┌────────┐ ┌───┐
        │        │ │   │
        │    0   │ │ 1 │
        │        │ │   │
cut_y → └────────┘ └───┘
        ┌────────┐ ┌───┐
        │    2   │ │ 3 │
        └────────┘ └───┘
```

Args:
    cut_x: Offset from self.x where the cut should be made. If negative, the cut
        is taken from the right edge.
    cut_y: Offset from self.y where the cut should be made. If negative, the cut
        is taken from the lower edge.

Returns:
    Four new regions which add up to the original (self).
r   rw   )r&   cut_xcut_yr!   r"   rZ   r[   _Regions           r   splitRegion.split^  s}    4 #e19ME19NEA%'AIq%-7A5y%%8AIqy%-H	
 	
r   c                \    U u  p#pEUS:  a  XA-   n[        X#X5      [        X!-   X4U-
  U5      4$ )u  Split a region into two, from a given x offset.

```
         cut ↓
    ┌────────┐┌───┐
    │    0   ││ 1 │
    │        ││   │
    └────────┘└───┘
```

Args:
    cut: An offset from self.x where the cut should be made. If cut is negative,
        it is taken from the right edge.

Returns:
    Two regions, which add up to the original (self).
r   rw   r&   cutr!   r"   rZ   r[   s         r   split_verticalRegion.split_vertical  sD    ( #e7+C 1%17As{F3
 	
r   c                \    U u  p#pEUS:  a  XQ-   n[        X#XA5      [        X#U-   XEU-
  5      4$ )u  Split a region into two, from a given y offset.

```
            ┌─────────┐
            │    0    │
            │         │
    cut →   └─────────┘
            ┌─────────┐
            │    1    │
            └─────────┘
```

Args:
    cut: An offset from self.y where the cut should be made. May be negative,
        for the offset to start from the lower edge.

Returns:
    Two regions, which add up to the original (self).
r   rw   r_  s         r   split_horizontalRegion.split_horizontal  sD    * #e7,C 1$1#gusl3
 	
r   c           
         Uu  pEpgU u  pp[        U(       a  [        [        XU-   U
-
  5      U5      OUU(       a!  [        [        XU-   U-
  5      U5      U
U5      $ U	U
U5      $ )uD  Translate this region, so it fits within a container.

This will ensure that there is as little overlap as possible.
The top left of the returned region is guaranteed to be within the container.

```
┌──────────────────┐         ┌──────────────────┐
│    container     │         │    container     │
│                  │         │    ┌─────────────┤
│                  │   ──▶   │    │    return   │
│       ┌──────────┴──┐      │    │             │
│       │    self     │      │    │             │
└───────┤             │      └────┴─────────────┘
        │             │
        └─────────────┘
```


Args:
    container: A container region.
    x_axis: Allow translation of X axis.
    y_axis: Allow translation of Y axis.

Returns:
    A new region with same dimensions that fits with inside container.
)rx   r   r   )r&   	containerx_axisy_axisrO   rP   r  r  rQ   rR   r   r   s               r   translate_insideRegion.translate_inside  st    : #,"&6<CBVf,-r2"8>CBWw./4	
 	
DF	
 	
r   Nc                    Uc  [         OUnU u  pVpxU(       a  XWUR                  -   U-  -  nU(       a  XhUR                  -   U-  -  n[        XVXx5      $ )uF  Inflect a region around one or both axis.

The `x_axis` and `y_axis` parameters define which direction to move the region.
A positive value will move the region right or down, a negative value will move
the region left or up. A value of `0` will leave that axis unmodified.

If a margin is provided, it will add space between the resulting region.

Note that if margin is specified it *overlaps*, so the space will be the maximum
of two edges, and not the total.

```
╔══════════╗    │
║          ║
║   Self   ║    │
║          ║
╚══════════╝    │

─ ─ ─ ─ ─ ─ ─ ─ ┌──────────┐
                │          │
                │  Result  │
                │          │
                └──────────┘
```

Args:
    x_axis: +1 to inflect in the positive direction, -1 to inflect in the negative direction.
    y_axis: +1 to inflect in the positive direction, -1 to inflect in the negative direction.
    margin: Additional margin.

Returns:
    A new region.
)NULL_SPACING	max_width
max_heightrx   )	r&   rh  ri  r=  inflect_marginr!   r"   rZ   r[   s	            r   inflectRegion.inflect  s]    H *0V"e.222f<<A>444>>AaE**r   c           	        U R                  U5      nU n          SS jnUS:X  d  US:X  a  UR                  US:X  a4  U" UR                  UR                  UR                  UR                  5      * OSUS:X  a4  U" UR                  UR
                  UR                  UR
                  5      * OSU5      nUR                  UR                  U5      US:g  US:g  5      nU$ )a[  Constrain a region to fit within a container, using different methods per axis.

Args:
    constrain_x: Constrain method for the X-axis.
    constrain_y: Constrain method for the Y-axis.
    margin: Margin to maintain around region.
    container: Container to constrain to.

Returns:
    New widget, that fits inside the container (if possible).
c                &    X:  a  X::  a  gX:  a  gg)a  Compare a span with a container

Args:
    span_start: Start of the span.
    span_end: end of the span.
    container_start: Start of the container.
    container_end: End of the container.

Returns:
    0 if the span fits, -1 if it is less that the container, otherwise +1
r   rE   r   )
span_startspan_endcontainer_startcontainer_ends       r   compare_span&Region.constrain.<locals>.compare_span(  s     ,1J+r   rq  r   none)
rv  r    rw  r    rx  r    ry  r    r^   r    )r>  rq  r!   r   r"   r   rj  rA  )r&   constrain_xconstrain_yr=  rg  margin_regionry   rz  s           r   	constrainRegion.constrain  s   $ 		&)		'*	=@	QT		* )#{i'?^^ #i/ "%%++!!	   #i/ "%%,,!!((	  +F6 ((V$6!6!
 r   r   )r   zCollection[Region]r^   rx   )
rO   r    rP   r    rQ   r    rR   r    r^   rx   )r   rb   r   rb   r^   rx   )r   rx   ry   rx   r   r_   r^   r   r]   ra   r   r`   )r^   ztuple[float, float])r^   rm   )r^   tuple[int, int, int, int]r   r   )r;   rc   r^   rx   )ry   rx   r^   r  )r   rb   r^   rx   )r   rb   r^   rx   )r;   rx   r^   r_   r   r   r   )rZ   r    r[   r    r^   rx   )r=  r  r^   rx   )ry   rx   r^   rx   )rY  r    rZ  r    r^   z%tuple[Region, Region, Region, Region])r`  r    r^   ztuple[Region, Region])TT)rg  rx   rh  r_   ri  r_   r^   rx   )rE   rE   N)rh  r    ri  r    r=  zSpacing | Noner^   rx   )
r}  $Literal['none', 'inside', 'inflect']r~  r  r=  r  rg  rx   r^   rx   ):rd   re   rf   rg   rh   r!   ri   r"   rZ   r[   classmethodr   r   r   r   r2   rj   r   r   r   r   rs   r   r   r   r   r   r   r   r   r   r}   r   r>   rB   r  r  r   r  r   r!  r   r   r*  r/  r   r6  r>  rA  rP  rV  r\  ra  rd  rj  rq  r  rk   r   r   r   rx   rx   @  s   !F AsJ,AsJ*E3N"FCO#? ?" - - ( ( CH3("3(,23(<@3(	3( 3(j"
 - - . . # # $ $ ( ( ! ! 	3 	3 % % $ $ - - 5 5
   + +
 2 2 3 3 + +
 +H
$ t
 
 R3  t
 
$ tK K t * t
 
( t
 
( t6 60 t " t%
 %
N t
 
8 t
 
< FJ$
$
)-$
>B$
	$
N LP*+*+(+*+:H*+	*+XL9L :L 	L
 L 
Lr   rx   c                  r   \ rS rSr% SrSrS\S'    SrS\S'    SrS\S'    Sr	S\S'    SS	 jr
\SS
 j5       r\SS j5       r\SS j5       r\SS j5       r\SS j5       r\SS j5       r\SS j5       r\SS j5       r\SS j5       r\S S j5       r\S S j5       r\S S j5       rS!S jrS!S jrS"S jrSrg)#r  ib  u  Stores spacing around a widget, such as padding and border.

Spacing is defined by four integers for the space at the top, right, bottom, and left of a region.

```
┌ ─ ─ ─ ─ ─ ─ ─▲─ ─ ─ ─ ─ ─ ─ ─ ┐
               │ top
│        ┏━━━━━▼━━━━━━┓         │
 ◀──────▶┃            ┃◀───────▶
│  left  ┃            ┃ right   │
         ┃            ┃
│        ┗━━━━━▲━━━━━━┛         │
               │ bottom
└ ─ ─ ─ ─ ─ ─ ─▼─ ─ ─ ─ ─ ─ ─ ─ ┘
```

Example:
    ```python
    >>> from textual.geometry import Region, Spacing
    >>> region = Region(2, 3, 20, 10)
    >>> spacing = Spacing(1, 2, 3, 4)
    >>> region.grow(spacing)
    Region(x=-2, y=2, width=26, height=14)
    >>> region.shrink(spacing)
    Region(x=6, y=4, width=14, height=6)
    >>> spacing.css
    '1 2 3 4'
    ```
r   r    r   r   r   r   c                    U S:g  $ )N)r   r   r   r   r   r%   s    r   r2   Spacing.__bool__  s    |##r   c                4    U R                   U R                  -   $ )zTotal space in the x axis.)r   r   r%   s    r   rZ   Spacing.width  s     yy4::%%r   c                4    U R                   U R                  -   $ )zTotal space in the y axis.)r   r   r%   s    r   r[   Spacing.height  s     xx$++%%r   c                    U u  pp4XB:  a  U$ U$ )zcThe space between regions in the X direction if margins overlap, i.e. `max(self.left, self.right)`.r   )r&   _topr   _bottomr   s        r   rn  Spacing.max_width  s     &*"W|t..r   c                    U u  pp4X:  a  U$ U$ )zcThe space between regions in the Y direction if margins overlap, i.e. `max(self.top, self.bottom)`.r   )r&   r   _rightr   _lefts        r   ro  Spacing.max_height  s     &*"Vls..r   c                2    U R                   U R                  4$ )z/A pair of integers for the left, and top space.)r   r   r%   s    r   top_leftSpacing.top_left  s     		488$$r   c                2    U R                   U R                  4$ )z3A pair of integers for the right, and bottom space.)r   r   r%   s    r   r   Spacing.bottom_right  s     

DKK((r   c                    U u  pp4XB-   X-   4$ )z?A pair of integers for the total horizontal and vertical space.r   r&   r   r   r   r   s        r   totalsSpacing.totals  s     $( Fcl++r   c                t    U u  pp4Xs=:X  a  Us=:X  a	  U:X  a   U $   X4X44:X  a  U SU 3$ U SU SU SU 3$ )zXA string containing the spacing in CSS format.

For example: "1" or "2 4" or "4 2 8 2".
 r   r  s        r   cssSpacing.css  sd     $( F)6)T)UO *<F>)U!E7##U!E7!F81TF33r   c                h   [        U[        5      (       a	  U " XX5      $ [        U5      nUS:X  a  US   nU " X3X35      $ US:X  a(  [        [        [        [        4   U5      u  pEU " XEXE5      $ US:X  a3  [        [        [        [        [        [        4   U5      u  pgpU " XgX5      $ [        SU S35      e)zUnpack padding specified in CSS style.

Args:
    pad: An integer, or tuple of 1, 2, or 4 integers.

Raises:
    ValueError: If `pad` is an invalid value.

Returns:
    New Spacing object.
rE   r   r      z41, 2 or 4 integers required for spacing properties; z given)r7   r    lenr   r   r   )
r   padpad_len_padpad_top	pad_rightr   r   r   r   s
             r   unpackSpacing.unpack  s     c3s**c(a<q6Dt4..a<!%eCHos!;Gw7>>a<'+E#sC2D,Es'K$Cs600B7)6R
 	
r   c                    [        USUS5      $ )zConstruct a Spacing with a given amount of spacing on vertical edges,
and no horizontal spacing.

Args:
    amount: The magnitude of spacing to apply to vertical edges.

Returns:
    `Spacing(amount, 0, amount, 0)`
r   r  r   amounts     r   verticalSpacing.vertical  s     vq&!,,r   c                    [        SUSU5      $ )zConstruct a Spacing with a given amount of spacing on horizontal edges,
and no vertical spacing.

Args:
    amount: The magnitude of spacing to apply to horizontal edges.

Returns:
    `Spacing(0, amount, 0, amount)`
r   r  r  s     r   
horizontalSpacing.horizontal  s     q&!V,,r   c                    [        XX5      $ )zConstruct a Spacing with a given amount of spacing on all edges.

Args:
    amount: The magnitude of spacing to apply to all edges.

Returns:
    `Spacing(amount, amount, amount, amount)`
r  r  s     r   allSpacing.all  s     vv66r   c                x    [        U[        5      (       a   U u  p#pEUu  pgp[        X&-   X7-   XH-   XY-   5      $ [        $ r5   r7   r8   r  r9   
r&   r;   top1right1bottom1left1top2right2bottom2left2s
             r   r>   Spacing.__add__  J    eU##+/(D'+0(D'V_g.?  r   c                x    [        U[        5      (       a   U u  p#pEUu  pgp[        X&-
  X7-
  XH-
  XY-
  5      $ [        $ r5   r  r  s
             r   rB   Spacing.__sub__  r  r   c           	     z    U u  p#pEUu  pgp[        [        X&5      [        X75      [        XH5      [        XY5      5      $ )zGrow spacing with a maximum.

Args:
    other: Spacing object.

Returns:
    New spacing where the values are maximum of the two values.
)r  r   )
r&   r;   r   r   r   r   	other_topother_rightother_bottom
other_lefts
             r   grow_maximumSpacing.grow_maximum  sE     $( F;@8	#%!	
 	
r   r   Nr]   r   ra   )r^   str)r  r   r^   r  )r  r    r^   r  )r;   rc   r^   r  )r;   r  r^   r  )rd   re   rf   rg   rh   r   ri   r   r   r   r2   rj   rZ   r[   rn  ro  r  r   r  r  r  r  r  r  r  r>   rB   r  rk   r   r   r   r  r  b  s=   < CL)E3N+FCO,D#M*$ & & & & / /
 / /
 % % ) ) , ,
 4 4 
 
8 
- 
- 
- 
- 	7 	7
r   r  c                      \ rS rSrSrSS/rSS jrSS jrSS jrSS jr	SS	 jr
\SS
 j5       r\SS j5       r\SS j5       r\SS j5       rSS jrSS jrSrg)Shapei)  zAn arbitrary shape defined by a sequence of regions.

This class currently exists to filter widgets within a shape defined when the user is slecting text.

_regions_boundsc                    [        U5      U l        U R                  (       a&  [        R                  " U R                  5      U l        g[        U l        g)z:

Args:
    regions: Regions which will define the shape.
N)r8   r  rx   r   NULL_REGIONr  )r&   r   s     r   __init__Shape.__init__5  s8     g04Fdmm, 	CN 	r   c                ,    [        U R                  5      $ r5   )r_   r  r%   s    r   r2   Shape.__bool__@  s    DLL!!r   c                ,    [        U R                  5      $ r5   )hashr  r%   s    r   __hash__Shape.__hash__C  s    DMM""r   c              #  (   #    U R                   v   g 7fr5   r  r%   s    r   __rich_repr__Shape.__rich_repr__F  s     mms   c                    Uu  p#/ n[        U5       HI  nUR                  [        U5       Vs/ s H   nSU R                  [        Xe5      5         PM"     sn5        MK     SR	                  S U 5       5      $ s  snf )zsBuild a string with a 2D grid of results from contains_point.

This is a debugging aid (do not use in production).
z.X
c              3  D   #    U  H  nS R                  U5      v   M     g7f) N)join).0lines     r   	<genexpr>Shape.draw.<locals>.<genexpr>R  s     7343s    )r|   appendr   r   r  )r&   r   rZ   r[   mapr"   r!   s          r   draw
Shape.drawI  sl    
 !vAJJuVAT00>?VW yy73777 Ws   'A7
c                    U R                   $ )zThe regions in the shape.r  r%   s    r   r   Shape.regionsT  s     }}r   c                    U R                   $ )z!A region that encloses the shape.)r  r%   s    r   boundsShape.boundsY  s     ||r   c                :    [        S U R                   5       5      $ )zCells covered by the shape.c              3  8   #    U  H  oR                   v   M     g 7fr5   )rs   )r  ry   s     r   r  Shape.area.<locals>.<genexpr>b  s     ;]6;;]s   )sumr  r%   s    r   rs   
Shape.area^  s     ;T]];;;r   c                   ^^^^^^^ TR                   TR                   :  a  TTsmmTu  mmTu  mmSUUUUUUU4S jjn[        U" 5       5      $ )a  Get a shape that would be constructed by a user selecting text between two points.

The shape would look something like this:

```
    XXXXXXXXXX <- top
XXXXXXXXXXXXXX
XXXXXXXXXXXXXX <- middle
XXXXXXXXXXXXXX
XXXXXXXXX      <- bottom
```

Args:
    container: The container region for the selection.
    start: The start offset.
    end: The end offset.

Returns:
    A new shape covering the selection bounds.
c               3    >#    TT R                   :X  a;  TT R                  :X  a+  [        T R                   TT R                  TT-
  S-   5      v   gTR                  TR                  :X  a  [        TTTT-
  S5      v   g[        TTT R                  T-
  S5      v   TR                  TR                  -
  S:  a-  [        T R                   TS-   T R                  TT-
  S-
  5      v   [        T R                   TTT R                   -
  S5      v   g7f)zMGet regions to cover selection bounds.

Yields:
    Regions to cover bounds.
rE   N)r!   r   rx   rZ   r"   )rg  endend_xend_ystartstart_xstart_ys   r   get_regions+Shape.selection_bounds.<locals>.get_regions  s     )++%%9??*BKKOOGOa'	  CEE!GO	  OOg-	  55577?Q& !!!!+	  KKIKK'	 s   D	D)r^   Iterable[Region])r/   r  )	r   rg  r  r  r  r  r  r  r  s	    ``` @@@@r   selection_boundsShape.selection_boundsd  sM    , ??S]]*JC u1	 1	f []##r   c                B   ^ [        U4S jU R                   5       5      $ )zDoes a region overlap this shape?

Args:
    region: A Region to check.

Returns:
    `True` if any part of the shape overlaps the region, `False` if there is no overlap.
c              3  D   >#    U  H  oR                  T5      v   M     g 7fr5   )r!  )r  shape_regionry   s     r   r  !Shape.overlaps.<locals>.<genexpr>  s     S]\((00]    r;  r  r  s    `r   r!  Shape.overlaps  s     ST]]SSSr   c                B   ^ [        U4S jU R                   5       5      $ )zCheck if the given offset is within the shape.

Args:
    offset: An offset.

Returns:
    `True` if the given offset is anywhere within the shape, otherwise `False`.
c              3  D   >#    U  H  oR                  T5      v   M     g 7fr5   )r   )r  ry   r   s     r   r  'Shape.contains_point.<locals>.<genexpr>  s     M}V((00}r  r	  r   s    `r   r   Shape.contains_point  s     Mt}}MMMr   )r  r  N)r   r  r]   r   )r^   zrich.repr.Result)r   rm   r^   r  )r^   ztuple[Region, ...]r   )rg  rx   r  r   r  r   r^   r  )ry   rx   r^   r_   )r   r   r^   r_   )rd   re   rf   rg   rh   	__slots__r  r2   r  r  r  rj   r   r  rs   r  r  r!  r   rk   r   r   r   r  r  )  s     	I
	
"#	8     < <
 M$ M$^	T	Nr   r  TEXTUAL_SPEEDUPS1)r   rx   rm   r  r   r   r  	NULL_SIZErm  )r   r   r   r   r   r   r^   r   ),rh   
__future__r   os	functoolsr   operatorr   r   typingr   r   r	   r
   r   r   r   r   r   r   typing_extensionsr   r   	rich.reprrichr    r   ri   rF   r   r   r   rm   rx   r  r  environgettextual_speedupsImportErrorr   r  r  rm  r   r   r   <module>r     sf  
 # 	  +   $+ $sU38_eCc3,>&??  9  7CeBuGZ uGp}5: }5@_Z _DD
j D
N_N _ND (:C@CGBB
 Aq\U ! ?Aq!Q'U ' }1:	5  PaAq)e ) B  s   D" "D+*D+