
    .iP                       d Z ddlmZ ddlmZ ddlmZ ddlmZ	 ddlm
Z
 ddlmZ d	Zerdd
lZddlmZ ddlmZ g dZe G d de             ZddZddZd
d	d	 	 	 	 	 	 	 d dZ	 	 d!	 	 	 	 	 	 	 d"dZ	 	 	 	 d#	 	 	 	 	 	 	 	 	 	 	 d$dZ	 	 	 	 d%dZd&d'dZd(dZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 d)dZd*dZd+dZ 	 	 	 d,	 	 	 	 	 	 	 	 	 d-dZ!d.dZ"y
)/zYTime humanizing functions.

These are largely borrowed from Django's `contrib.humanize`.
    )annotations)Enum)total_ordering   )_gettext)	_ngettext)intcommaFN)Iterable)Any)naturaldate
naturaldaynaturaldeltanaturaltimeprecisedeltac                  4    e Zd ZdZdZdZdZdZdZdZ	dZ
dd	Zy
)Unitr   r                     c                p    | j                   |j                   u r| j                  |j                  k  S t        S )N)	__class__valueNotImplemented)selfothers     I/mnt/e/genesis-system/.venv/lib/python3.12/site-packages/humanize/time.py__lt__zUnit.__lt__)   s+    >>U__,::++    N)r   r   returnr   )__name__
__module____qualname__MICROSECONDSMILLISECONDSSECONDSMINUTESHOURSDAYSMONTHSYEARSr     r!   r   r   r      s/    LLGGEDFEr!   r   c                 >    dd l } | j                   j                         S )Nr   )datetimenow)dts    r   _nowr3   /   s    ;;??r!   c                H    | j                   dk  rt               }||| z   z
  S | S )zReturn an "absolute" value for a timedelta, always representing a time distance.

    Args:
        delta (datetime.timedelta): Input timedelta.

    Returns:
        datetime.timedelta: Absolute timedelta.
    r   )daysr3   )deltar1   s     r   _abs_timedeltar7   5   s*     zzA~fcEk""Lr!   )r1   precisec               6   ddl }|s
t               }t        | |j                         r| }|| z
  }nFt        | |j                        r|| z
  }| }n(	 |r| n
t	        |       }  |j                  |       }||z
  }|t        |      fS # t
        t        f$ r d| fcY S w xY w)zTurn a value into a date and a timedelta which represents how long ago it was.

    If that's not possible, return `(None, value)`.
    r   Nseconds)r0   r3   
isinstance	timedeltaround
ValueError	TypeErrorr7   )r   r1   r8   r2   dater6   s         r   _date_and_deltarB   D   s     f%%e	E2<<	(U{	$E%,E BLL/E;D &&& I& 	;	s   'B BBc                   ddl }t        |j                            }|t        j                  t        j                  t        j
                  fvrd| d}t        |      |}t        | |j                        r| }n*	 t        |        t        |       }  |j                  |       }|}t        |      }|j                  dz  }	|j                  dz  }
t        |
dz        }|	dk(  r|
dk  r|j                   dk(  r|t        j
                  k(  r3|j"                  d	k  r$t%        d
d|j"                        |j"                  z  S |t        j                  k(  s5|t        j
                  k(  rJd	|j"                  cxk  rdk  r5n t'        d      S |j"                  d	z  }t%        ddt        |            |z  S t'        d      S |j                   dk(  rt'        d      S |j                   dk  r$t%        dd|j                         |j                   z  S d|j                   cxk  rdk  rKn nHt        |j                   dz        }|dk(  rt'        d      S |dk(  rt'        d      S t%        dd|      |z  S d|j                   k  r/t        |j                   dz        }|dk(  rt'        d      S |dk(  rt'        d      S t%        dd|      |z  S |	dk(  rg|
dk(  rt'        d      S |st%        dd|
      |
z  S |dk(  rt%        dd|
      |
z  S |dk(  rt'        d      S |d k(  rt'        d!      S t%        d"d#|      |z  S |	dk(  rv|dk(  r|
dk(  rt'        d!      S |dk(  rt%        d$d%|
      |
z  S |r:|dk(  rt'        d&      S |d k(  r|	dz  }	t%        d'd(|	      |	z  S t%        d)d*|      |z  S t%        d$d%|
      |
z  S t%        d'd(|	      j)                  d+d,      t+        |	      z  S # t        t        f$ r t        |       cY S w xY w)-a  Return a natural representation of a timedelta or number of seconds.

    This is similar to `naturaltime`, but does not add tense to the result.

    The timedelta will be rounded to the nearest unit that makes sense.

    Args:
        value (datetime.timedelta, int or float): A timedelta or a number of seconds.
        months (bool): If `True`, then a number of months (based on 30.5 days) will be
            used for fuzziness between years.
        minimum_unit (str): The lowest unit that can be used.

    Returns:
        str (str or `value`): A natural representation of the amount of time
            elapsed unless `value` is not datetime.timedelta or cannot be
            converted to int (cannot be float due to 'inf' or 'nan').
            In that case, a `value` is returned unchanged.

    Raises:
        OverflowError: If `value` is too large to convert to datetime.timedelta.

    Examples:
        Compare two timestamps in a custom local timezone::

        ```pycon
        >>> import datetime as dt
        >>> from dateutil.tz import gettz

        >>> berlin = gettz("Europe/Berlin")
        >>> now = dt.datetime.now(tz=berlin)
        >>> later = now + dt.timedelta(minutes=30)

        >>> assert naturaldelta(later - now) == "30 minutes"
        True
        ```

    r   NzMinimum unit 'z' not supportedr:   m       >@r     %d microsecond%d microsecondsi@B %d millisecond%d millisecondsa momentza second<   	%d second
%d seconds  za minutezan hour	%d minute
%d minutes   za day%d hour%d hours%d day%d daysza month   za year%d month	%d monthsz1 year, %d dayz1 year, %d daysz1 year, 1 month%d year%d yearsz1 year, %d monthz1 year, %d months%d%s)r0   r   upperr(   r'   r&   r?   r<   r=   intfloatr@   strabsr5   r>   r;   microsecondsr   _replacer	   )r   monthsminimum_unitr2   tmpmsgmin_unitr6   
use_monthsyearsr5   
num_monthsmillisecondsminuteshourss                  r   r   r   _   s   T 
|!!#
$C
4<<!2!2D4E4EFF|nO<oH%&	J%LE BLL/E JJEJJ#E::Dtd{#JzdQh==A4,,,1C1Cd1J.0A5CUCUV(()
 4,,,D---$%:L:L2Xy2X Z=   %11D8.0A3|CTU"# Z= ==AZ= ==2[,FVV%%EMMB./G!|}$"}|#[,@7JJ5== %--$./Ez|#{z!Y
E:UBB	!19W:Xy$7$>>?Xy$7$>>?Y<X;[*=
JJ	!?tqyX;?-/@$G$NNQ*++R
 J>FF ,.A:N
 )+<dCdJJY
E2::4FRWXX} I& 	u:	s   :)O O*)O*c                r   ddl }t        |       } t        |      }|xs
 t               }t        | |      \  }}|t	        |       S t        | |j                   |j                  f      r||kD  }|rt        d      n
t        d      }	t        |||      }|t        d      k(  rt        d      S t	        |	|z        S )a+  Return a natural representation of a time in a resolution that makes sense.

    This is more or less compatible with Django's `naturaltime` filter.

    The time will be rounded to the nearest unit that makes sense.

    Args:
        value (datetime.datetime, datetime.timedelta, int or float): A `datetime`, a
            `timedelta`, or a number of seconds.
        future (bool): Ignored for `datetime`s and `timedelta`s, where the tense is
            always figured out based on the current time. For integers and floats, the
            return value will be past tense by default, unless future is `True`.
        months (bool): If `True`, then a number of months (based on 30.5 days) will be
            used for fuzziness between years.
        minimum_unit (str): The lowest unit that can be used.
        when (datetime.datetime): Point in time relative to which _value_ is
            interpreted.  Defaults to the current time in the local timezone.

    Returns:
        str: A natural representation of the input in a resolution that makes sense.
    r   N)r1   z%s from nowz%s agorK   r1   )	r0   _convert_aware_datetimer3   rB   ra   r<   r=   rd   r   )
r   futurerf   rg   whenr2   r1   rA   r6   agos
             r   r   r      s    8 #E*E"4(D
.$&C!%S1KD%|5z%"++r||45$!M
!H+C5E*xsU{r!   c                    ddl }t        | |j                         r5| j                  )|j                   j                  | j	                               } | S )zIConvert aware datetime to naive datetime and pass through any other type.r   N)r0   r<   tzinfofromtimestamp	timestamp)r   r2   s     r   rr   rr   ,  s>     %%%,,*B))%//*;<Lr!   c                   ddl }	  |j                  | j                  | j                  | j                        } | |j                  j                         z
  }|j                  dk(  rt        d      S |j                  dk(  rt        d      S |j                  dk(  rt        d      S | j                  |      S # t
        $ r t        |       cY S t        t        f$ r t        |       cY S w xY w)zReturn a natural day.

    For date values that are tomorrow, today or yesterday compared to
    present day return representing string. Otherwise, return a string
    formatted according to `format`.

    r   Ntodayr   tomorrow	yesterday)r0   rA   yearmonthdayAttributeErrorra   OverflowErrorr?   r{   r5   rd   strftime)r   formatr2   r6   s       r   r   r   7  s     

EKK; BGGMMO#EzzQzzzQ}zzR~>>&!!#  5z:& 5zs   2B4 4C&
C&%C&c                r   ddl }	  |j                  | j                  | j                  | j                        } t        | |j                  j                         z
        }|j                  dk\  rt        | d      S t        |       S # t
        $ r t        |       cY S t        t        f$ r t        |       cY S w xY w)zKLike `naturalday`, but append a year for dates more than ~five months away.r   Ngc@z%b %d %Y)r0   rA   r   r   r   r   ra   r   r?   r7   r{   r5   r   )r   r2   r6   s      r   r   r   W  s    

EKK; 5277==?23Ezz\!%,,e  5z:& 5zs   2B B6B65B6c                v    ||k(  rt        || |z        dfS ||v rd| fS t        | |      \  }}|t        |      fS )a  Divide `value` by `divisor`, returning the quotient and remainder.

    If `unit` is `minimum_unit`, the quotient will be the rounding of `value / divisor`
    according to the `format` string and the remainder will be zero. The rationale is
    that if `unit` is the unit of the quotient, we cannot represent the remainder
    because it would require a unit smaller than the `minimum_unit`.

    >>> from humanize.time import _quotient_and_remainder, Unit
    >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.DAYS, [], "%0.2f")
    (1.5, 0)

    If `unit` is in `suppress`, the quotient will be zero and the remainder will be the
    initial value. The idea is that if we cannot use `unit`, we are forced to use a
    lower unit, so we cannot do the division.

    >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [Unit.DAYS], "%0.2f")
    (0, 36)

    In other cases, return the quotient and remainder as `divmod` would do it.

    >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [], "%0.2f")
    (1, 12)

    r   )_rounding_by_fmtdivmodr_   )r   divisorunitrg   suppressr   qrs           r   _quotient_and_remainderr   i  sT    @ |8!;;x%x
 %!DAqc!f9r!   c                Z    | |v r&t         D ]  }|| kD  s	||vs|c S  d}t        |      | S )a  Return a minimum unit suitable that is not suppressed.

    If not suppressed, return the same unit:

    >>> from humanize.time import _suitable_minimum_unit, Unit
    >>> _suitable_minimum_unit(Unit.HOURS, []).name
    'HOURS'

    But if suppressed, find a unit greater than the original one that is not
    suppressed:

    >>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS]).name
    'DAYS'

    >>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS, Unit.DAYS]).name
    'MONTHS'
    z@Minimum unit is suppressed and no suitable replacement was found)r   r?   )rj   r   r   ri   s       r   _suitable_minimum_unitr     sE    $ 8 	Dh4x#7	 QoOr!   c                d    t        |      }t        D ]  }|| k(  r |S |j                  |        |S )a  Extend suppressed units (if any) with all units lower than the minimum unit.

    >>> from humanize.time import _suppress_lower_units, Unit
    >>> [x.name for x in sorted(_suppress_lower_units(Unit.SECONDS, [Unit.DAYS]))]
    ['MICROSECONDS', 'MILLISECONDS', 'DAYS']
    )setr   add)rj   r   r   s      r   _suppress_lower_unitsr     sC     8}H 8 O 	T
 Or!   c           
     :   t        | d      \  }}|t        |       S |D ch c]  }t        |j                             }}t        |j                            }t	        ||      }~t        ||      }|j                  }	|j                  }
|j                  }t        t              \  }}}}}}}}t        |	d||||      \  }}	t        |	d||||      \  }}	|	dz  dz  |
z   }
t        |
d||||      \  }	}
t        |
d||||      \  }}
t        |
d	||||      \  }}
|
d
z  |z   }t        |d
||||      \  }
}t        |d||||      \  }}|dk\  r||vr
|dz  }|
dz  }
|
d	k\  r||vr
|
d	z  }
|dz  }|d	k\  r||vr
|d	z  }|dz  }|dk\  r||vr
|dz  }|	dz  }	|	dk\  r||vr
|	dz  }	|dz  }|dk\  r||vr
|dz  }|dz  }dd|fdd|fdd|	fdd|fdd|fdd|
fdd|fdd|fg}g }t        t        t              |      D ]  \  }}|\  }}}|dkD  s|s||k(  rd|cxk  rd k  rn nd n
t        |      } t        |||       }!ddl}"||k(  r*|"j!                  |      d   dkD  r|!j#                  d!|      }!nW||k(  rR|"j!                  |      d   dk(  rt        |      }|!j#                  d!d"      }!|j%                  |!t'        |      z         |j%                  |!|z         ||k(  s n t)        |      dk(  r|d   S d#j+                  |dd$       }#|d$   }$t-        d%      |#|$fz  S c c}w )&a:  Return a precise representation of a timedelta or number of seconds.

    ```pycon
    >>> import datetime as dt
    >>> from humanize.time import precisedelta

    >>> delta = dt.timedelta(seconds=3633, days=2, microseconds=123000)
    >>> precisedelta(delta)
    '2 days, 1 hour and 33.12 seconds'

    ```

    A custom `format` can be specified to control how the fractional part
    is represented:

    ```pycon
    >>> precisedelta(delta, format="%0.4f")
    '2 days, 1 hour and 33.1230 seconds'

    ```

    Instead, the `minimum_unit` can be changed to have a better resolution;
    the function will still readjust the unit to use the greatest of the
    units that does not lose precision.

    For example setting microseconds but still representing the date with milliseconds:

    ```pycon
    >>> precisedelta(delta, minimum_unit="microseconds")
    '2 days, 1 hour, 33 seconds and 123 milliseconds'

    ```

    If desired, some units can be suppressed: you will not see them represented and the
    time of the other units will be adjusted to keep representing the same timedelta:

    ```pycon
    >>> precisedelta(delta, suppress=['days'])
    '49 hours and 33.12 seconds'

    ```

    Note that microseconds precision is lost if the seconds and all
    the units below are suppressed:

    ```pycon
    >>> delta = dt.timedelta(seconds=90, microseconds=100)
    >>> precisedelta(delta, suppress=['seconds', 'milliseconds', 'microseconds'])
    '1.50 minutes'

    ```

    If the delta is too small to be represented with the minimum unit,
    a value of zero will be returned:

    ```pycon
    >>> delta = dt.timedelta(seconds=1)
    >>> precisedelta(delta, minimum_unit="minutes")
    '0.02 minutes'

    >>> delta = dt.timedelta(seconds=0.1)
    >>> precisedelta(delta, minimum_unit="minutes")
    '0 minutes'

    ```
    T)r8   NrD   rE   rR   rO   iQ rL   g    .ArF   r      rW   rZ   r[   rX   rY   rU   rV   rS   rT   rP   rQ   rM   rN   rI   rJ   rG   rH   r   r   r\   r]   z, r}   z	%s and %s)rB   ra   r   r^   r   r   r5   r;   rc   listr   zipreversedr_   r   mathmodfre   appendr	   lenjoinrd   )%r   rg   r   r   rA   r6   ssuppress_setrj   r5   secsusecsr&   r'   r(   r)   r*   r+   r,   r-   rl   rf   rp   ro   msecsfmtstextsr   fmtsingular_txt
plural_txt	fmt_value
_fmt_valuefmt_txtr   headtails%                                        r   r   r     s	   P "%6KD%|5z-56DO6L6 L&&()H%h=H )<@L ::D==DEOSPLL,%vu  *c5(L&KE4 +dFHlFLFD "9td"D(ixvJD$ *dE8\6KE4 ,b'8\6MGT 3JE)sGX|VKD% +t\8\6LE5 ~'5	rzg\1
1"}l22
{t</	 rzfL0
!|\1"
 
J&	[&)	9d#	J&	lG,	lD)	,e4	,e4	D E$. 	c.1+j)q=48+;)/a/S^Jj*EGxDIIi$8$;a$?!//$799Y'*a/ #II!//$5Wx	'::;LL9,-8'* 5zQQx99U3BZ D9D[>T4L((y 7s   Lc                ^    | |z  }	 t        |      }|S # t        $ r t        |      }Y |S w xY w)al  Round a number according to the string format provided.

    The string format is the old printf-style string formatting.

    If we are using a format which truncates the value, such as "%d" or "%i", the
    returned value will be of type `int`.

    If we are using a format which rounds the value, such as "%.2f" or even "%.0f",
    we will return a float.
    )r_   r?   r`   )r   r   results      r   r   r     sA     e^FF L  fLs    ,,)r"   zdt.datetime)r6   dt.timedeltar"   r   )r   r   r1   dt.datetime | Noner8   boolr"   ztuple[Any, Any])Tr;   )r   zdt.timedelta | floatrf   r   rg   ra   r"   ra   )FTr;   N)r   z"dt.datetime | dt.timedelta | floatrs   r   rf   r   rg   ra   rt   r   r"   ra   )r   z)dt.datetime | dt.timedelta | float | Noner"   r   )z%b %d)r   dt.date | dt.datetimer   ra   r"   ra   )r   r   r"   ra   )r   r`   r   r`   r   r   rg   r   r   Iterable[Unit]r   ra   r"   ztuple[float, float])rj   r   r   r   r"   r   )rj   r   r   r   r"   z	set[Unit])r;   r.   z%0.2f)
r   zdt.timedelta | float | Nonerg   ra   r   zIterable[str]r   ra   r"   ra   )r   ra   r   r`   r"   zfloat | int)#__doc__
__future__r   enumr   	functoolsr   i18nr   rd   r   numberr	   TYPE_CHECKINGr0   r2   collections.abcr
   typingr   __all__r   r3   r7   rB   r   r   rr   r   r   r   r   r   r   r   r.   r!   r   <module>r      s  
 #  $   ( 4     .25''*'<@'': !WYWYWY WY 		WYx !#0-00 0 	0
 0 	0f4"@$*** * 	*
 * * *Z:$ " 	H)&H)H) H) 	H)
 	H)Vr!   