§
    ›ÇjcF  ã                  ó\  — U d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	m
Z
mZ 	 ddlmZ n# e$ r dZY nw xY we� e eedd¦  «        ¦  «        ndZd	Zd
ZdZdZdaded<   dadad6d„Z G d„ d¦  «        Z G d„ d¦  «        Z G d„ d¦  «        Zd7d„Zd8d$„Z d9d(„Z!dd)dddd*œd:d4„Z"g d5¢Z#dS );uÌ  The delivery discipline of a timed pointer plan, apart from any clock.

â›” WHY THIS IS ITS OWN MODULE. The rules below - absolute deadlines from one
``t0``, drop rather than send late, never two events in one instant - used to
live welded into an ``async`` loop in :mod:`._cursor`, which is the only place
that could run them. That made them unavailable to the one other place that
moves a pointer: the drag, inside the in-process Juggler server, which is
synchronous. A drag therefore moved with no discipline at all - two events, both
at the destination - and the alternative was to write the rules a second time
in synchronous form.

So the rules live here, as a state machine with no clock of its own, and the two
callers supply the clock and the sleeping. :class:`Pacer` decides WHAT happens
next; a driver decides HOW to wait. There is one definition of the discipline
and two ways of obeying it, rather than two definitions that agree until one of
them is edited.
é    )ÚannotationsN)ÚAnyÚIterableÚListÚOptionalÚTupleé   )Ú_motionÚSAMPLE_FLOOR_MSg       @ÚINVPW_CURSOR_TIMERÚsleepÚemitÚdoner   Ú_winmmFÚreturnc                 óv  — t           rt          S da t          j                             t
          ¦  «        pd                     ¦   «                              ¦   «         dv rd S t          j	         
                    d¦  «        sd S 	 dd l} |                      d¦  «        an# t          t          f$ r d aY nw xY wt          S )NTÚ )ÚoffÚ0ÚfalseÚwinr   Úwinmm)Ú_winmm_triedr   ÚosÚenvironÚgetÚ	TIMER_ENVÚstripÚlowerÚsysÚplatformÚ
startswithÚctypesÚWinDLLÚOSErrorÚImportError)r#   s    úMC:\Projects\Historical\venv\Lib\site-packages\invisible_playwright/_pacing.pyÚ_timer_resolution_availabler(   B   s¼   € åð ÝˆØ€LÝ
Œ
�Š•yÑ!Ô!Ð' R×.Ò.Ñ0Ô0×6Ò6Ñ8Ô8Ð<QÐQÐQØˆtÝŒ<×"Ò" 5Ñ)Ô)ð ØˆtðØˆˆˆà—’˜wÑ'Ô'ˆˆøÝ•[Ð!ð ð ð Øˆˆˆðøøøå€Ms   ÂB ÂB1Â0B1c                  ó"   — e Zd ZdZd
d„Zdd„Zd	S )Ú
fine_timera  Raise the system timer resolution for the length of one burst.

    The depth counter is module-global on purpose: the client's cursor and the
    server's drag can be inside one at the same time, and the resolution must
    come back down once, when the last of them leaves.
    r   ú'fine_timer'c                ó°   — t          ¦   «         }|�Et          dk    r0	 |                     d¦  «         n# t          t          f$ r | cY S w xY wt          dz  a| S ©Nr   r	   )r(   Ú_timer_period_depthÚtimeBeginPeriodr%   ÚAttributeError)ÚselfÚdlls     r'   Ú	__enter__zfine_timer.__enter__\   sr   € å)Ñ+Ô+ˆØˆ?Ý" aÒ'Ð'ð Ø×'Ò'¨Ñ*Ô*Ð*Ð*øÝ¥Ð0ð  ð  ð  Ø�K�K�Kð øøøå 1Ñ$ÐØˆs   �3 ³A	ÁA	Úexcr   ÚNonec                óÆ   — t           dk    rd S t           dz  a t           dk    r<t          �7	 t                               d¦  «         d S # t          t          f$ r Y d S w xY wd S d S r-   )r.   r   ÚtimeEndPeriodr%   r0   )r1   r4   s     r'   Ú__exit__zfine_timer.__exit__h   s�   € å !Ò#Ð#ØˆFÝ˜qÑ ÐÝ !Ò#Ð#­Ð(:ðÝ×$Ò$ QÑ'Ô'Ð'Ð'Ð'øÝ�^Ð,ð ð ð Ø��ðøøøð $Ð#Ð(:Ð(:s   «A ÁAÁAN)r   r+   )r4   r   r   r5   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r3   r8   © ó    r'   r*   r*   T   sF   € € € € € ðð ð
ð 
ð 
ð 
ð	ð 	ð 	ð 	ð 	ð 	r>   r*   c                  óD   — e Zd ZdZdZ	 	 ddd„Zedd„¦   «         Zdd„ZdS )ÚEvz#One dispatchable instant of a plan.)Út_msÚxÚyÚkindÚdxÚdyÚmoveç        rA   ÚfloatrB   rC   rD   ÚstrrE   rF   r   r5   c                óÜ   — t          |¦  «        | _        t          |¦  «        | _        t          |¦  «        | _        || _        t          |¦  «        | _        t          |¦  «        | _        d S ©N)rI   rA   rB   rC   rD   rE   rF   )r1   rA   rB   rC   rD   rE   rF   s          r'   Ú__init__zEv.__init__{   sN   € å˜$‘K”KˆŒ	Ý�q‘”ˆŒÝ�q‘”ˆŒØˆŒ	Ý˜‘)”)ˆŒÝ˜‘)”)ˆŒˆˆr>   Úboolc                ó   — | j         dk    S )NÚwheel)rD   ©r1   s    r'   Úis_wheelzEv.is_wheel„   s   € àŒy˜GÒ#Ð#r>   c                ó<   — d| j         | j        | j        | j        fz  S )NzEv(%.1f, %.1f, %.1f, %s))rA   rB   rC   rD   rQ   s    r'   Ú__repr__zEv.__repr__ˆ   s   € Ø)¨T¬Y¸¼ÀÄÈÌ	Ð,RÑRÐRr>   N)rG   rH   rH   )rA   rI   rB   rI   rC   rI   rD   rJ   rE   rI   rF   rI   r   r5   )r   rN   )r   rJ   )	r9   r:   r;   r<   Ú	__slots__rM   ÚpropertyrR   rT   r=   r>   r'   r@   r@   v   sx   € € € € € Ø-Ð-à6€IàDJØ.1ðð ð ð ð ð ð$ð $ð $ñ „Xð$ðSð Sð Sð Sð Sð Sr>   r@   c                  ó\   — e Zd ZdZdZdZdZdZdeddœdd„Z	dd„Z
dd„Zd d„Zd!d„Zd!d„ZdS )"ÚPaceru©	  Walk a timeline against ABSOLUTE deadlines, deciding only WHAT is next.

    Every deadline is measured from one ``t0`` - the clock reading handed to the
    first :meth:`step` - so oversleeping on one event does not push the next one
    out: lateness cannot accumulate.

    When the platform cannot deliver an event on time - Windows quantises a short
    sleep to the system timer, so a 12 ms request routinely returns after 16 -
    the event is DROPPED rather than sent late: an event is skipped when the
    NEXT event is already due, because sending it then would be sending two
    events at one instant and would push the whole rest of the movement
    backwards. What survives is a stream whose timestamps still land where the
    plan put them.

    â›” BUT ONLY WHILE THE DROP STAYS SMALL IN SPACE. A dropped event hands its
    distance to the next one that goes out, and that rule alone had no ceiling:
    on a loaded machine nearly every point was overtaken, the destination
    survived, and one event carried 89% of an 820 px journey with a timestamp
    exactly where the plan put it - a plausible rhythm wrapped around a jump
    no device makes. So an event may be dropped only if the event AFTER it lies
    within REACH of the last position actually sent, where reach is twice the
    plan's largest step: the one overslept sample the timer case produces
    merges two steps into one, and that is what is allowed. Beyond it the event
    is sent late instead, still no closer to the previous one than the floor,
    and the plan overruns its budget by however much the machine is behind. A
    hand that is slowed down is a hand; a hand that teleports is not. [B214]

    The last event is never dropped (it is where the movement ends) and neither
    is a wheel notch (it carries a delta nobody else will send). ``origin`` is
    where the pointer is before the first event: the reach of the first drops
    is measured from there, and without it from the first event of the plan.

    Usage, from either a synchronous or an asynchronous driver::

        pacer = Pacer(evs)
        while True:
            what, arg = pacer.step(clock())
            if what == DONE:
                break
            if what == SLEEP:
                sleep(arg)
            elif emitter_for(arg) is None:
                pacer.dropped()          # nothing can carry this one
            else:
                emit(arg)
                pacer.emitted(clock())
    ÚdeadlineÚgapr   )
Ú_evsÚ
_emit_lastÚ_min_gapÚ_iÚ_phaseÚ_t0Ú
_last_emitÚ_refÚ_reachÚ	deliveredTN)Ú	emit_lastÚ
min_gap_msÚoriginÚevsúIterable[Ev]re   rN   rf   rI   rg   úOptional[Tuple[float, float]]r   r5   c          
     óü  — t          |¦  «        | _        || _        t          |¦  «        dz  | _        d| _        | j        | _        d | _        d | _	        |�*t          |d         ¦  «        t          |d         ¦  «        fn,| j        r$| j        d         j
        | j        d         j        fnd | _        dt          d„ t          | j        | j        dd …         ¦  «        D ¦   «         d¬¦  «        z  | _        d| _        d S )Nç     @�@r   r	   g       @c              3  óh   K  — | ]-\  }}t          |j        |j        |j        |j        ¦  «        V — Œ.d S rL   )Ú	_distancerB   rC   )Ú.0ÚaÚbs      r'   ú	<genexpr>z!Pacer.__init__.<locals>.<genexpr>Ü   sP   è è € ð 8ð 8Ù��Aõ �q”s˜AœC ¤ a¤cÑ*Ô*ð 8ð 8ð 8ð 8ð 8ð 8r>   rH   )Údefault)Úlistr[   r\   rI   r]   r^   Ú	_DEADLINEr_   r`   ra   rB   rC   rb   ÚmaxÚziprc   rd   )r1   rh   re   rf   rg   s        r'   rM   zPacer.__init__É   s  € õ # 3™iœiˆŒ	Ø#ˆŒÝ˜jÑ)Ô)¨FÑ2ˆŒØˆŒØ”nˆŒØ$(ˆŒØ+/ˆŒð 5;Ð4F�U�6˜!”9ÑÔ�u V¨A¤YÑ/Ô/Ð0Ð0Ø6:´iÐI�4”9˜Q”<”> 4¤9¨Q¤<¤>Ð2Ð2ÀTð 	Œ	ð �Cð8ð 8Ý˜TœY¨¬	°!°"°"¬Ñ6Ô6ð8ñ 8ô 8ØADðFñ Fô Fñ FˆŒð ˆŒˆˆr>   ÚiÚintc                ó  — | j         |         }|t          | j         ¦  «        dz
  k    s|j        rdS | j         |dz            }| j        €dS t	          | j        d         | j        d         |j        |j        ¦  «        | j        dz   k    S )z?May event *i* be skipped, handing its distance to the next one?r	   FNTr   g•Ö&è.>)r[   ÚlenrR   rb   rn   rB   rC   rc   )r1   rx   ÚevÚnxts       r'   Ú
_droppablezPacer._droppableá   sƒ   € àŒY�qŒ\ˆØ•�D”I‘” Ñ"Ò"Ð" b¤kÐ"Ø�5ØŒi˜˜A™ÔˆØŒ9ÐØ�4Ý˜œ 1œ t¤y°¤|°S´U¸C¼EÑBÔBØŒ{˜TÑ!ò"ð 	"r>   ÚnowúTuple[str, Any]c                ó  — | j         €|| _         t          | j        ¦  «        }| j        |k     �rV| j        | j                 }| j        |dz
  k    }|                      | j        ¦  «        }| j        | j        k    rŠ| j         |j        dz  z   |z
  }|dk    r| j        | _        t          |fS |rL| j        dz   |k     r>|| j         | j        | j        dz            j        dz  z   k    r|  
                    ¦   «          ŒÔ| j        | _        | j        | j        k    rX| j        �E| j        || j        z
  z
  }|dk    r-|r|  
                    ¦   «          �Œ'| j        | _        t          |fS | j        | _        |r| j        s|| _        n	t          |fS t           dfS )zàWhat to do at *now*: ``(SLEEP, seconds)``, ``(EMIT, ev)`` or
        ``(DONE, None)``.

        After ``(EMIT, ev)`` the driver must report back with :meth:`emitted` or
        :meth:`dropped` before stepping again.
        Nr	   rl   r   )r`   r{   r[   r^   r~   r_   ru   rA   Ú_GAPÚSLEEPÚ_advancera   r]   Ú_EMITr\   ÚEMITÚDONE)r1   r   Únr|   ÚlastÚ	droppableÚwaitÚbehinds           r'   Ústepz
Pacer.stepì   s�  € ð Œ8ÐØˆDŒHÝ�”	‰NŒNˆØŒg˜Šk‰kØ”˜4œ7Ô#ˆBØ”7˜a !™eÒ#ˆDØŸš¨¬Ñ0Ô0ˆIàŒ{˜dœnÒ,Ð,Ø”x "¤'¨FÑ"2Ñ2°SÑ8�Ø˜!’8�8ð #'¤)�D”KÝ! 4˜=Ð(Øð  $¤'¨A¡+°¢/ /Ø 4¤8¨d¬i¸¼À!¹Ô.DÔ.IÈFÑ.RÑ#RÒRÐRØ—M’M‘O”O�OØØ"œi�”àŒ{˜dœiÒ'Ð'ð ”?Ð.Ø!œ]¨c°D´OÑ.CÑD�FØ ’z�zØ$ð %Ø ŸMšM™OœO˜OÙ$Ø&*¤j˜œÝ % v˜Ð.Ø"œj�”àð ˜DœOð Ø�”ØÝ˜"�:ÐÝ�dˆ|Ðr>   c                ó¦   — | xj         dz  c_         || _        | j        | j                 }|j        |j        f| _        |                      ¦   «          dS )z4The event :meth:`step` handed out went out at *now*.r	   N)rd   ra   r[   r^   rB   rC   rb   r„   )r1   r   r|   s      r'   ÚemittedzPacer.emitted  sG   € àˆŒ˜!ÑˆŒØˆŒØŒY�t”wÔˆØ”T˜2œ4�LˆŒ	Ø�Š‰Œˆˆˆr>   c                ó.   — |                       ¦   «          dS )zºThe event :meth:`step` handed out could not be carried.

        It leaves ``_last_emit`` alone deliberately: nothing was sent, so
        nothing has to be spaced away from it.
        N)r„   rQ   s    r'   ÚdroppedzPacer.dropped&  s   € ð 	�Š‰Œˆˆˆr>   c                ó>   — | xj         dz  c_         | j        | _        d S )Nr	   )r^   ru   r_   rQ   s    r'   r„   zPacer._advance.  s   € ØˆŒ�1‰ˆŒØ”nˆŒˆˆr>   )
rh   ri   re   rN   rf   rI   rg   rj   r   r5   )rx   ry   r   rN   )r   rI   r   r€   )r   rI   r   r5   )r   r5   )r9   r:   r;   r<   ru   r‚   r…   rU   ÚMIN_EVENT_INTERVAL_MSrM   r~   r�   r�   r‘   r„   r=   r>   r'   rX   rX   Ž   sÇ   € € € € € ð.ð .ðf €IØ€DØ€Eð>€Ið @DØ%:Ø9=ðð ð ð ð ð ð0	"ð 	"ð 	"ð 	"ð0ð 0ð 0ð 0ðdð ð ð ðð ð ð ð%ð %ð %ð %ð %ð %r>   rX   Úx0rI   Úy0Úx1Úy1c                ó*   — || z
  dz  ||z
  dz  z   dz  S )Né   g      à?r=   )r”   r•   r–   r—   s       r'   rn   rn   3  s"   € Ø�"‰W˜‰N˜b 2™g¨!™^Ñ+°Ñ3Ð3r>   rB   rC   ÚwúOptional[float]ÚhúTuple[float, float]c                óÊ   — |r|s| |fS t          t          | d¦  «        t          |¦  «        dz
  ¦  «        t          t          |d¦  «        t          |¦  «        dz
  ¦  «        fS )u¦  Keep a waypoint somewhere an event can actually land.

    â›” NOT A TIDINESS MEASURE. A pointer event outside the viewport is not
    merely ignored: the browser parks the cursor at the origin, so one waypoint
    off the edge teleports the pointer to (0, 0) in the middle of a movement. A
    curved path near an edge goes outside on its own, without the caller aiming
    anywhere strange.

    Unknown size means unknown, so nothing is clamped: guessing a viewport would
    move points that were fine.

    The endpoint is the caller's to emit unclamped - it is where the movement
    has to end - so callers apply this to the waypoints and not to the
    destination.
    rH   g      ð?)Úminrv   rI   )rB   rC   rš   rœ   s       r'   Úclamp_to_viewportr    7  sd   € ð" ð �Að Ø�!ˆtˆå�C��3‰KŒK�˜q™œ C™Ñ(Ô(Ý�C��3‰KŒK�˜q™œ C™Ñ(Ô(ðð r>   rh   úList[Ev]Úbudget_sc                óp  — | sg S | d         j         }|dk    r&||dz  k    r|dz  |z  }| D ]}|xj         |z  c_         Œg }t           }t          | ¦  «        D ]Þ\  }}|r0|j        s)|d         j        s|j         |d         j         k    r||d<   Œ7|t	          | ¦  «        dz
  k    }|j        p|p|j         |z
  t          k    }	|	sŒl|rT|rR|j        sK|d         j        s>|j         |z
  t          k     r+|                     ¦   «          |r|d         j         nt           }|                     |¦  «         |j         }Œß|S )aÄ  Fit a timeline inside ``budget_s`` and inside what hardware can report.

    Two rules, in this order:

    * if the plan is longer than the budget, every timestamp is scaled - the
      same movement performed faster, not a movement that stops half way;
    * events closer together than :data:`MIN_EVENT_INTERVAL_MS` are then
      DROPPED, not squeezed. Scaling alone is what produced impossible event
      rates: the waypoint count never changed, so a tighter cap simply meant
      more events per second, without limit. The last event of the timeline
      and every wheel notch survive regardless - the first is where the
      movement has to end, the second carries a delta that would be lost.
    éÿÿÿÿr   rl   r	   )rA   r“   Ú	enumeraterR   r{   ÚpopÚappend)
rh   r¢   ÚtotalÚscaler|   ÚoutÚlast_trx   Úis_lastÚkeeps
             r'   Úfit_timeliner®   P  s¡  € ð ð Øˆ	Ø�ŒGŒL€EØ�!‚|€|˜ ¨6Ñ 1Ò1Ð1Ø˜FÑ" eÑ+ˆØð 	ð 	ˆBØˆGŒG�uÑˆGŒGˆGØ€CÝ#Ð#€FÝ˜3‘”ð ð ‰ˆˆ2Øð 	�r”{ð 	¨3¨r¬7Ô+;ð 	Ø”G˜s 2œwœ|Ò+Ð+ð ˆC�‰GØØ•s˜3‘x”x !‘|Ò#ˆàŒKð 9Øð9àŒw˜ÑÕ#8Ò8ð 	ð
 ð 	ØØð 	E�sð 	E 2¤;ð 	E°s¸2´wÔ7Gð 	EÐ\^Ô\cÐflÑ\lõ  pEò  ]Eð  ]Eð �GŠG‰IŒIˆIØ%(ÐD�S˜”W”\�\Õ/DÐ.DˆFØ�
Š
�2‰ŒˆØ”ˆˆØ€Jr>   T)Ú
emit_wheelre   r   r   rg   ri   Ú	emit_mover¯   re   rN   r   rg   rj   ry   c               óB  — t          | ¦  «        } | sdS |�|nt          j        }|�|nt          j        }t	          | ||¬¦  «        }	t          ¦   «         5  	 |	                      |¦   «         ¦  «        \  }
}|
t          k    rn€|
t          k    r ||¦  «         ŒD|j	        r.|€|	 
                    ¦   «          Œb ||j        |j        ¦  «         n ||j        |j        ¦  «         |	                      |¦   «         ¦  «         Œ¬	 ddd¦  «         n# 1 swxY w Y   |	j        S )a*  The SYNCHRONOUS driver of :class:`Pacer`. Returns events sent.

    The asynchronous one lives in :mod:`._cursor`, because it has to ``await``
    both the sleep and the emit. This one exists for the in-process Juggler
    server, whose ops are ordinary blocking calls; the decisions are the pacer's
    in both cases.

    ``now`` and ``sleep`` are injectable so a test can drive a whole timeline
    without waiting for it. ``origin`` is where the pointer is before the plan
    starts, the reference for the pacer's reach until something is sent.
    r   N)re   rg   )rt   ÚtimeÚperf_counterr   rX   r*   r�   r‡   rƒ   rR   r‘   rE   rF   rB   rC   r�   rd   )rh   r°   r¯   re   r   r   rg   Úclockr‹   ÚpacerÚwhatÚargs               r'   Údriver¸   ƒ  so  € õ ˆs‰)Œ)€CØð ØˆqØ�?ˆCˆC­Ô(9€EØÐ%ˆ5ˆ5­4¬:€DÝ�# °6Ð:Ñ:Ô:€EÝ	‰Œð #ð #ð	#ØŸ
š
 5 5¡7¤7Ñ+Ô+‰IˆD�#Ø•tŠ|ˆ|ØØ•uŠ}ˆ}Ø��S‘	”	�	ØØŒ|ð (ØÐ%Ø—M’M‘O”O�OØØ�
˜3œ6 3¤6Ñ*Ô*Ð*Ð*à�	˜#œ% ¤Ñ'Ô'Ð'Ø�MŠM˜%˜%™'œ'Ñ"Ô"Ð"ð	#ð ð	#ð #ð #ñ #ô #ð #ð #ð #ð #ð #ð #øøøð #ð #ð #ð #ð  Œ?Ðs   ÁB.DÄDÄD)r‡   r†   r@   r“   rX   rƒ   r   r    r¸   r®   r*   )r   r   )
r”   rI   r•   rI   r–   rI   r—   rI   r   rI   )
rB   rI   rC   rI   rš   r›   rœ   r›   r   r�   )rh   r¡   r¢   rI   r   r¡   )rh   ri   r°   r   r¯   r   re   rN   r   r   r   r   rg   rj   r   ry   )$r<   Ú
__future__r   r   r    r²   Útypingr   r   r   r   r   r   r
   Ú_motion_modÚ	ExceptionrI   Úgetattrr“   r   rƒ   r†   r‡   r   Ú__annotations__r   r.   r(   r*   r@   rX   rn   r    r®   r¸   Ú__all__r=   r>   r'   ú<module>rÀ      s2  ððð ð ð" #Ð "Ð "Ð "Ð "Ð "à 	€	€	€	Ø 
€
€
€
Ø €€€Ø 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7ðØ(Ð(Ð(Ð(Ð(Ð(Ð(øØð ð ð Ø€K€K€Kðøøøð Ðð 
€Eˆ'ˆ'�+Ð0°#Ñ
6Ô
6Ñ7Ô7Ð7Ø$'ð ð !€	ð 	€Ø€Ø€ð
 €Ð Ð Ð Ñ Ø€ØÐ ðð ð ð ð$ð ð ð ð ñ ô ð ðDSð Sð Sð Sð Sñ Sô Sð Sð0b%ð b%ð b%ð b%ð b%ñ b%ô b%ð b%ðJ4ð 4ð 4ð 4ðð ð ð ð20ð 0ð 0ð 0ðf CGØ ¨TÀØ26ð$ð $ð $ð $ð $ð $ðNð ð €€€s   ¥, ¬6µ6