§
    ›Çjâý  ã            	      óè  — U d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	m
Z
mZmZmZmZmZ g d¢Zeeef         Zeeeeef         ZdZ edd	h¦  «        Zd
ZdZ eeeh¦  «        Zd�d„ZdždŸd„Zd d„Zd¡d„Z G d„ d¦  «        Zd¢d"„Zd£d&„Z  ed'¬(¦  «         G d)„ d*¦  «        ¦   «         Z!e	d+ed*         f         Z" ed'¬(¦  «         G d,„ d-¦  «        ¦   «         Z# e$d.¦  «        Z% e$d/¦  «        Z&d¤d1„Z' ed'¬(¦  «         G d2„ d3¦  «        ¦   «         Z(	 	 d¥d¦d8„Z)	 džd§d:„Z*	 	 d¨d©d=„Z+dªd@„Z,ddAdBdCdDœd«dQ„Z-dCdd'dRœd¬dX„Z.d­d^„Z/d®d_„Z0d¯d`„Z1d°d±dd„Z2 ed'¬(¦  «         G de„ df¦  «        ¦   «         Z3d²di„Z4d²dj„Z5d²dk„Z6d²dl„Z7 ed'¬(¦  «         G dm„ dn¦  «        ¦   «         Z8 e8dodpe4¦  «         e8dqdre5¦  «         e8dsdte6¦  «         e8dudve7¦  «        fZ9dwe:dx<    e;dy„  e<e9e9d4d…         ¦  «        D ¦   «         ¦  «        s
J dz¦   «         ‚e9d{         j=        dBk    s
J d|¦   «         ‚dd}œd³d„Z>d€dd�œd´d„„Z?dµd‰„Z@dŠd‹dŒœd¶d�„ZAd·d‘„ZBddd’œd¸d•„ZCddd–œd¹d™„ZD ed'¬(¦  «         G dš„ d›¦  «        ¦   «         ZEdºdœ„ZFdS )»a«  Macro-scale pointer behaviour planning (pure, no I/O, no browser).

WHY THIS LAYER EXISTS
---------------------
How a single move from A to B is *shaped* is only half of what a pointer
stream shows. The other half is what the pointer does between the moves,
and where the moves end:

  * a pointer that is perfectly still except for the second it takes to
    slide from one control to the next is still, measurably, a pointer
    that exists only in order to click. Measured on the current path, the
    cursor is motionless for ~96% of a session;
  * if every movement terminates on a clickable element then the SET OF
    ENDPOINTS is itself a signature, and no amount of per-path polish
    removes it. A human parks the cursor on empty page area, drags it out
    of the text being read, and fidgets while a page scrolls.

So the interesting statistics here are not "is this curve pretty" but
"how often does the pointer move at all", "how long are the silences",
"where do the movements end" and "does the shape of all of that differ
between two sessions".

DESIGN: PLAN, DO NOT PERFORM
----------------------------
Every function below is pure: it takes a seed and geometry and returns a
timeline of :class:`Step` objects. Something else - the caller - walks
that timeline and dispatches it. Nothing here imports Playwright, opens a
socket or reads a clock. That is what makes the behaviour testable with
plain arithmetic instead of a live page, and it is why the numbers in the
tests are assertions rather than screenshots.

The walker is ``_cursor``: it turns a timeline into pointer events against
absolute deadlines. What is planned here and what actually reaches the wire
therefore differ, and deliberately so - see ``_cursor`` for the rule that
decides which planned events survive a machine that cannot deliver them all.

DESIGN: THIS MODULE PLANS *WHERE AND WHEN*, NOT *HOW A STROKE IS SHAPED*
------------------------------------------------------------------------
There are two scales, and exactly one owner each. ``_motion`` owns the shape
and the pacing of a single stroke from A to B. This module owns everything
above that: how many strokes an action is made of, where they aim, how long
the hand waits between them, and what it does when it is not aiming at
anything.

The seam is the ``render`` argument threaded through every planner below. It
takes a start, an end and a kind, and returns the steps of that one stroke.
It is REQUIRED, not defaulted. This module used to carry its own stroke model
as a fallback, which meant two intra-move laws could ship in one package and a
detector would see a different one depending on which call site ran. That model
was deleted on 2026-07-26 and the seam made mandatory, so a call site that
forgets the renderer is a TypeError rather than a silent second law. ``_cursor``
injects one backed by ``_motion``, and it is the only stroke model in force
everywhere. Two stroke models running side by side in one product would be
two measurably different families of movement inside one session.

DESIGN: EVERY PARAMETER COMES FROM THE SESSION SEED
---------------------------------------------------
Pause length, drift amplitude, pointing speed, where the speed peak sits,
how readily the hand overshoots, how often it moves for no reason: all of
it is drawn per session from the seed (:class:`PointerPersona`). A number
compiled into the package is the same number in every install and every
account, and a fixed shape is an invariant across every session of every
user - which is exactly the property a behavioural classifier wants. Two
seeds must look like two people; one seed must reproduce exactly.

PROVENANCE OF THE NUMBERS
-------------------------
Each constant below carries a comment saying where it comes from. Two
labels are used and they are not interchangeable:

  ``[lit]``   grounded in the human motor-control / HCI literature
              (Fitts' law and its Shannon form; the Meyer et al. 1988
              optimised-submovement account of overshoot-and-correct;
              Flash & Hogan 1985 minimum-jerk velocity profiles; the
              8-12 Hz physiological tremor band; heavy-tailed, roughly
              log-normal dwell times in reading and browsing).
  ``[judg]``  chosen by judgement. Plausible, bounded, and deliberately
              randomised per session so that being wrong about the centre
              of a range costs less - but not measured. Do not quote a
              ``[judg]`` number as if it were evidence.
é    )ÚannotationsN)Ú	dataclass)ÚAnyÚCallableÚDictÚIterableÚListÚOptionalÚSequenceÚTuple)ÚStepÚPointerPersonaÚTypingPersonaÚplan_typingÚplan_hesitationÚ
plan_clickÚ	act_nonceÚpopup_numberÚPageActsÚ	PlanStatsÚinitial_pointerÚlanding_pointÚ	plan_idleÚplan_scrollÚplan_approachÚplan_aimless_moveÚsteps_from_waypointsÚtail_withinÚ	summarizeÚBURST_GAP_MSç      i@ÚapproachÚcorrectÚwheelÚwaitÚseedÚintÚtagÚstrÚreturnc                ód   — d| dz  z  }|                      d¦  «        D ]}||z  }|dz  dz  }Œ|pdS )a-  FNV-1a mix - independent PRNG streams per logical bucket from one seed.

    The same idiom is used elsewhere in the package. Two different tags give
    two streams that advance independently, so adding a planner later cannot
    shift the numbers an existing planner produces for the same seed.
    l   %#D’s”_ ì   ÿÿ Úasciil   ³   l   ÿÿÿÿ l   ï>[= )Úencode)r&   r(   ÚhÚcs       úPC:\Projects\Historical\venv\Lib\site-packages\invisible_playwright/_behaviour.pyÚ	_sub_seedr2   ˆ   sS   € ð 	˜d ZÑ/Ñ0€AØ�ZŠZ˜Ñ Ô ð 5ð 5ˆØ	ˆQ‰ˆØ�ÑÐ"4Ñ4ˆˆØˆ?�
Ðó    Únonceúrandom.Randomc                óP   — t          j        t          | |› d|› �¦  «        ¦  «        S )Nú:)ÚrandomÚRandomr2   )r&   r(   r4   s      r1   Ú_rngr:   –   s*   € ÝŒ=� 4¨CÐ)9Ð)9°%Ð)9Ð)9Ñ:Ô:Ñ;Ô;Ð;r3   ÚpageÚnc                óL   — t          | ¦  «        dz  t          |¦  «        dz  z  S )zÍThe nonce of the `n`-th act of one kind on the session's `page`-th page.

    The page goes in the high bits, so two pages never share a nonce and the
    first page (0) keeps the plain count 1, 2, 3.
    é    r,   )r'   )r;   r<   s     r1   r   r   š   s$   € õ �‰IŒI˜‰O¥ A¡¤¨Ñ 3Ñ4Ð4r3   ÚopenerúOptional[int]Úkc                óx   — d| €dnt          | ¦  «        t          |¦  «        fz  }dt          d|¦  «        dz  z  S )u£  The number of the `k`-th page (1, 2, ...) the SITE opened from the page
    numbered `opener`, or, with `opener` None, the `k`-th one of the session
    whose opener is not a page we know.

    â›” A SEPARATE SPACE FROM THE PAGES THE SCRIPT ASKS FOR, and that is the
    point. Those are numbered 0, 1, 2 by the client in the order of the calls;
    a popup arrives when the engine says so, which no script controls, so a
    popup drawing from the same count would push every later `new_page()` one
    number further whenever it happened to land first (measured: an
    `asyncio.gather` of a click that opens a popup and a `new_page()`). Keyed
    by its opener and its rank among that opener's popups, a popup has a
    number its own script decides: the second popup the first page opened.

    Bit 62 set and a 62-bit hash below it: never one of the client's small
    numbers, and two popups collide with odds of 2**-62.
    zpopup:%s:%dNú-l            r   l   ÿÿÿÿ )r'   r2   )r?   rA   r(   s      r1   r   r   £   sA   € ð"  & .˜3˜3µc¸&±k´kÅ3ÀqÁ6Ä6ÐJÑ
J€CØ�	 ! SÑ)Ô)¨]Ñ;Ñ<Ð<r3   c                  ó(   — e Zd ZdZdZddd„Zdd„ZdS )r   u‡  Numbers the acts of one page, so no two acts of a session share a stream.

    â›” THE COUNT RESTARTS PER PAGE, THE PAGE NUMBER DOES NOT. These counters
    used to live as bare integers on each page's `Actions` and `Keyboard`, so
    every new page started from nonce 1 again: with one seed, the first field
    of every tab waited the same pause and was typed with the same intervals,
    and the first click of every tab was held for the same time. A site that
    sees two tabs of one session saw the same numbers twice. The page's
    number is now part of every nonce, which is what the client's cursor
    already did with its page ordinal (`_cursor.page_motion_seed`).

    â›” AND THE NUMBER IS GIVEN, NEVER COUNTED HERE. A page the script asks for
    carries the number the client reserved at the CALL (`Browser.
    _reserve_page_number` in the vendored client), a popup the one
    `popup_number` derives; the server's `PageDispatcher` holds it and hands
    it to the client in the page's initializer, where the cursor reads it.
    The server used to count pages itself as their dispatchers were built,
    and the cursor counted again at each page's first movement: two counters
    for one fact, and the server's followed the order in which the engine
    answered, so with `asyncio.gather` the first page of the call was page 1
    in 4 runs out of 10 ([B237]).

    Reproducible: the same seed and the same acts in the same pages give the
    same sequence. Per page rather than one count for the whole session for
    the cursor's reason: a single count would make each tab's numbers depend
    on how the acts of the tabs happened to interleave.
    )r;   Ú_countsr   r;   r'   r*   ÚNonec                ó<   — t          |¦  «        | _        i | _        d S ©N)r'   r;   rE   )Úselfr;   s     r1   Ú__init__zPageActs.__init__×   s   € Ý˜‘I”IˆŒ	Ø')ˆŒˆˆr3   Úactr)   c                ó|   — | j                              |d¦  «        dz   }|| j         |<   t          | j        |¦  «        S )z6The nonce for the next act of kind `act` on this page.r   é   )rE   Úgetr   r;   )rI   rK   r<   s      r1   ÚnextzPageActs.nextÛ   s<   € àŒL×Ò˜S !Ñ$Ô$ qÑ(ˆØˆŒ�SÑÝ˜œ AÑ&Ô&Ð&r3   N©r   )r;   r'   r*   rF   )rK   r)   r*   r'   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__rJ   rO   © r3   r1   r   r   ¸   sR   € € € € € ðð ð8 $€Ið*ð *ð *ð *ð *ð'ð 'ð 'ð 'ð 'ð 'r3   r   ÚvÚfloatÚloÚhic                ó&   — | |k     r|n	| |k    r|n| S rH   rV   )rW   rY   rZ   s      r1   Ú_clampr\   â   s    € Ø�R’�ˆ2ˆ2 A¨¢F F˜b˜b°Ð2r3   ÚrngÚmedianÚsigmac                óX   — |t          j        |                      d|¦  «        ¦  «        z  S )uÏ  A right-skewed draw whose MEDIAN is `median`.

    â›” The median, not the mean, and the distinction is the reason this helper
    exists rather than a `gauss` at each call site. Human timings - a keystroke
    gap, a pause, a movement time - have a floor and a long tail, so their mean
    sits above their typical value and a symmetric draw around the mean puts
    too much mass below the floor. `exp(gauss(log(m), s))` has median `m` by
    construction.
    ç        )ÚmathÚexpÚgauss)r]   r^   r_   s      r1   Ú_log_normalre   æ   s'   € ð •D”H˜SŸYšY s¨EÑ2Ô2Ñ3Ô3Ñ3Ð3r3   T)Úfrozenc                  óX   — e Zd ZU dZded<   ded<   ded<   ded<   dZded	<   dZded
<   dS )r   ap  One entry on the planned timeline.

    ``delay_ms`` is the wall time to wait BEFORE acting on this step, so a
    plan is dispatched as::

        for s in steps:
            sleep(s.delay_ms / 1000)
            if s.kind == "wheel":
                mouse.wheel(s.dx, s.dy)
            else:
                mouse.move(s.x, s.y)

    ``x``/``y`` are always the pointer position after the step - a wheel step,
    and a ``"wait"`` step which does nothing at all beyond consuming time,
    repeat the position they are dispatched at, so a consumer can track the
    cursor by reading the last step of any kind.

    A ``"wait"`` step exists so a plan accounts for ALL of the wall time it
    covers, including the stretches where the right answer is "the pointer
    does nothing". Without it the timeline would silently under-report its own
    duration and every occupancy figure computed from it would be inflated.

    ``kind`` is descriptive, never load-bearing for dispatch beyond the wheel
    case. It exists so tests (and the caller's logging) can ask questions like
    "what fraction of motion bursts ended on a control".
    rX   ÚxÚyÚdelay_msr)   Úkindra   ÚdxÚdyN)rQ   rR   rS   rT   Ú__annotations__rl   rm   rV   r3   r1   r   r   ÷   sZ   € € € € € € ðð ð6 €H€H�HØ€H€H�HØ€O€O�OØ€I€I�IØ€B€O€O€O�OØ€B€O€O€O�O€O€Or3   r   .c                  óà   — e Zd ZU dZded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   edd„¦   «         ZdS )r   ao  The parameters of one session's hand. Drawn from the session seed.

    Every field is a range, and the range is the honest statement of what we
    know: the centre is an estimate, the width is the admission that people
    differ. A single hardcoded value would be a constant shared by every
    install, which is the failure mode this module exists to remove.
    r'   r&   rX   Ú	sample_msÚ
fitts_a_msÚ
fitts_b_msÚmt_sigmaÚ	peak_fracÚ	curvatureÚ	tremor_pxÚdrift_pxÚreposition_pxÚfidget_scaleÚpause_median_msÚpause_sigmaÚovershoot_biasÚaimless_rateÚclick_dwell_median_msÚclick_dwell_sigmaÚdblclick_gap_median_msr*   ú'PointerPersona'c           	     óB  — t          |d¦  «        } | d6i d|“d|                     dd¦  «        “d|                     dd¦  «        “d	|                     d
d¦  «        “d|                     dd¦  «        “d|                     dd¦  «        “d|                     dd¦  «        “d|                     dd¦  «        “d|                     dd¦  «        “d|                     dd¦  «        “d|                     dd ¦  «        “d!|                     d"d#¦  «        “d$|                     d%d&¦  «        “d'|                     d(d)¦  «        “d*|                     d+d,¦  «        “d-|                     d.d/¦  «        “d0|                     d1d2¦  «        “d3|                     d4d5¦  «        “ŽS )7Nzpointer-personar&   rp   g      "@g      5@rq   ç     €V@g     @j@rr   g     @Z@g     `h@rs   gìQ¸…ëÁ?g¤p=
×£Ð?rt   g
×£p=
×?ç      à?ru   g{®Gáz„?gÛù~j¼t£?rv   çffffffÖ?çš™™™™™ù?rw   ç      @g      :@rx   g     €Q@ç     Àw@ry   çffffffæ?gÍÌÌÌÌÌ@rz   g     à•@g     À²@r{   g      è?ç      ô?r|   gš™™™™™á?g333333÷?r}   ç)\�Âõ(Ì?g¸…ëQ¸Þ?r~   g      M@g      _@r   çš™™™™™É?çš™™™™™Ù?r€   ç     ÀW@g     àj@rV   ©r:   Úuniform©Úclsr&   Úrs      r1   Ú	from_seedzPointerPersona.from_seed‡  sþ  € å�Ð(Ñ)Ô)ˆØˆsð 
ð 
ð 
Ø�ð
à—i’i  TÑ*Ô*Ð*ð
ð —y’y  uÑ-Ô-Ð-ð
ð —y’y ¨Ñ.Ô.Ð.ð	
ð
 —Y’Y˜t TÑ*Ô*Ð*ð
ð —i’i  dÑ+Ô+Ð+ð
ð —i’i  uÑ-Ô-Ð-ð
ð —i’i  dÑ+Ô+Ð+ð
ð —Y’Y˜s DÑ)Ô)Ð)ð
ð Ÿ)š) D¨%Ñ0Ô0Ð0ð
ð Ÿš 3¨Ñ,Ô,Ð,ð
ð ŸIšI f¨fÑ5Ô5Ð5ð
ð Ÿ	š	 $¨Ñ-Ô-Ð-ð
ð Ÿ9š9 T¨4Ñ0Ô0Ð0ð
ð Ÿš 4¨Ñ.Ô.Ð.ð
ð" #$§)¢)¨D°%Ñ"8Ô"8Ð"8ð#
ð$  Ÿiši¨¨dÑ3Ô3Ð3ð%
ð& $%§9¢9¨T°5Ñ#9Ô#9Ð#9ð'
ð 	
r3   N)r&   r'   r*   r�   )rQ   rR   rS   rT   rn   Úclassmethodr”   rV   r3   r1   r   r   -  s+  € € € € € € ðð ð €I€I�Ið ÐÐÑð ÐÐÑØÐÐÑð
 €O€O�Oð
 ÐÐÑð ÐÐÑð
 ÐÐÑð €O€O�Oð ÐÐÑð ÐÐÑð
 ÐÐÑØÐÐÑð ÐÐÑð
 ÐÐÑð !Ð Ð Ñ ØÐÐÑð "Ð!Ð!Ñ!àð
ð 
ð 
ñ „[ð
ð 
ð 
r3   r   z*`12345qwertasdfgzxcvb~!@#$%QWERTASDFGZXCVBz467890-=yuiop[]\hjkl;'nm,./^&*()_+YUIOP{}|HJKL:"NM<>?Úchc                ó2   — | t           v rdS | t          v rdS dS )NÚLÚRú?)Ú
_LEFT_HANDÚ_RIGHT_HAND)r–   s    r1   Ú_handr�   º  s'   € Ø	�ZÐÐØˆsØ	�[ÐÐØˆsØˆ3r3   c                  ó¢   — e Zd ZU dZded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ded<   ded<   ded<   edd„¦   «         Zdd„ZdS )r   u'  The parameters of one session's typing hand. Drawn from the session seed.

    Same shape as :class:`PointerPersona` and for the same reason: every field
    is a range, because the centre is an estimate and the width is the
    admission that people differ. A single hardcoded value would be a constant
    shared by every install.

    â›” It is drawn on its OWN tagged stream (`typing-persona`), so adding it
    does not move a single number any existing seed produces for the pointer.
    That property is why `_sub_seed` takes a tag at all.
    r'   r&   rX   Údwell_median_msÚdwell_sigmaÚgap_median_msÚ	gap_sigmaÚalternate_hand_factorÚsame_hand_factorÚsame_key_factorÚhesitation_rateÚhesitation_median_msÚhesitation_sigmar*   ú'TypingPersona'c                óÞ  — t          |d¦  «        } | ||                     dd¦  «        |                     dd¦  «        |                     dd¦  «        |                     dd	¦  «        |                     d
d¦  «        |                     dd¦  «        |                     dd¦  «        |                     dd¦  «        |                     dd¦  «        |                     dd¦  «        ¬¦  «        S )Nztyping-personag      O@g     €]@r‹   gáz®GáÚ?rŽ   g     `m@gÃõ(\�ÂÕ?g×£p=
×ã?g®Gáz®ç?gq=
×£pí?g¤p=
×£ð?g×£p=
×ó?rŠ   g      ü?g{®Gáz”?gìQ¸…ë±?ç     @z@g     ˆ“@r�   r‰   )r&   rŸ   r    r¡   r¢   r£   r¤   r¥   r¦   r§   r¨   r�   r‘   s      r1   r”   zTypingPersona.from_seedö  sØ   € å�Ð'Ñ(Ô(ˆØˆsØØŸIšI d¨EÑ2Ô2ØŸ	š	 $¨Ñ-Ô-ØŸ)š) D¨%Ñ0Ô0Ø—i’i  dÑ+Ô+Ø"#§)¢)¨D°$Ñ"7Ô"7ØŸYšY t¨TÑ2Ô2ØŸIšI d¨DÑ1Ô1ØŸIšI d¨DÑ1Ô1Ø!"§¢¨5°&Ñ!9Ô!9ØŸYšY t¨TÑ2Ô2ð
ñ 
ô 
ð 	
r3   r]   r5   c                ó8   — t          || j        | j        ¦  «        S )zÂOne stop to think, in milliseconds, drawn from `rng`.

        The only place a hesitation's distribution is written: `plan_typing`
        and `plan_hesitation` both draw through here.
        )re   r§   r¨   )rI   r]   s     r1   Úhesitation_mszTypingPersona.hesitation_ms  s   € õ ˜3 Ô 9¸4Ô;PÑQÔQÐQr3   N)r&   r'   r*   r©   )r]   r5   r*   rX   )rQ   rR   rS   rT   rn   r•   r”   r­   rV   r3   r1   r   r   Â  så   € € € € € € ð
ð 
ð €I€I�Ið
 ÐÐÑØÐÐÑð ÐÐÑØÐÐÑð
 !Ð Ð Ñ ØÐÐÑØÐÐÑð ÐÐÑØÐÐÑð ÐÐÑàð
ð 
ð 
ñ „[ð
ð Rð Rð Rð Rð Rð Rr3   r   rM   ÚpersonaÚclicksúList[Tuple[float, float]]c                ó  — t          | j        d|¦  «        }g }t          t          d|¦  «        ¦  «        D ]U}t	          || j        | j        ¦  «        }||dz
  k    rdnt	          || j        d¦  «        }|                     ||f¦  «         ŒV|S )uG  One `(dwell_ms, gap_ms)` per press of a click or a double click.

    `dwell_ms` is how long the button stays down; `gap_ms` is the wait before
    the NEXT press, and is zero for the last one because the pause after a
    click belongs to whatever happens next.

    â›” SAME SHAPE AS `plan_typing`, AND FOR THE SAME REASON. A press with no
    duration is a press no hand made, whether it is a finger on a key or a
    finger on a button: `mouseup.timeStamp - mousedown.timeStamp` came back as
    the cost of one protocol round trip. The double click had the matching
    defect one level up - two presses with nothing between them, delivered as a
    `dblclick` anyway because the event is born from `clickCount` rather than
    from the interval, so the page saw a double click no operating system would
    have accepted as one.
    ÚclickrM   ra   g333333Ó?)	r:   r&   ÚrangeÚmaxre   r~   r   r€   Úappend)r®   r¯   r4   r“   ÚoutÚiÚdwellÚgaps           r1   r   r     s�   € õ" 	ˆWŒ\˜7 EÑ*Ô*€AØ%'€CÝ•3�q˜&‘>”>Ñ"Ô"ð !ð !ˆÝ˜A˜wÔ<Ø#Ô5ñ7ô 7ˆà˜6 A™:’o�oˆsˆsÝ  7Ô#AÀ4ÑHÔHð 	à�
Š
�E˜3�<Ñ Ô Ð Ð Ø€Jr3   Útextc                ó€  — t          |j        d|¦  «        }g }t          | ¦  «        D �]\  }}t          ||j        |j        ¦  «        }|t          | ¦  «        dz
  k    r|                     |df¦  «          nÆ| |dz            }t          ||j        |j	        ¦  «        }	||k    r|	|j
        z  }	nAt          |¦  «        t          |¦  «        }}
|
dk    r|dk    r|	|
|k    r|j        n|j        z  }	|                     ¦   «         |j        k     r|	|                     |¦  «        z  }	|                     ||	f¦  «         �Œ|S )uT  One `(dwell_ms, gap_ms)` per character of `text`.

    `dwell_ms` is how long that key stays down; `gap_ms` is the wait before the
    NEXT key goes down, and is zero for the last character because the pause
    after the last keystroke belongs to whatever happens next, not to typing.

    â›” THE PLAN IS COMPUTED WHERE THE SEED IS, which is here, and carried to the
    engine with the text. The engine holds no seed and decides no timing: it
    obeys. That is the same division the cursor already uses, and it is what
    keeps one session's rhythm from being a property of the machine.
    ÚtypingrM   ra   rš   )r:   r&   Ú	enumeratere   rŸ   r    Úlenrµ   r¡   r¢   r¥   r�   r£   r¤   r8   r¦   r­   )rº   r®   r4   r“   r¶   r·   r–   r¸   Únxtr¹   ÚaÚbs               r1   r   r   ,  sJ  € õ 	ˆWŒ\˜8 UÑ+Ô+€AØ%'€CÝ˜4‘”ð !ñ !‰ˆˆ2Ý˜A˜wÔ6¸Ô8KÑLÔLˆØ•�D‘	”	˜A‘ÒÐØ�JŠJ˜˜s�|Ñ$Ô$Ð$ØˆEØ�1�q‘5ŒkˆÝ˜!˜WÔ2°GÔ4EÑFÔFˆØ�Š9ˆ9Ø�7Ô*Ñ*ˆCˆCå˜‘9”9�e C™jœjˆqˆAØ�CŠxˆx˜A šH˜HØ¸¸aº¸˜Ô5Ð5Ø$Ô5ñ7�à�8Š8‰:Œ:˜Ô/Ò/Ð/Ø�7×(Ò(¨Ñ+Ô+Ñ+ˆCØ�
Š
�E˜3�<Ñ Ô Ð Ñ Ø€Jr3   rK   Útimesc           	     ó    ‡ ‡— t          ‰ j        ||¦  «        Št          ˆ ˆfd„t          t	          d|¦  «        ¦  «        D ¦   «         ¦  «        S )aø  How long this typist stops before `act`, in milliseconds: `times` of
    its hesitations, drawn on the stream for `act` and `nonce`.

    The same hand `plan_typing` pauses with in the middle of a word, so the
    pause before a field and the pause inside it are one person's. Each act
    has its own tagged stream, so adding an act cannot move a number another
    act or the typing itself draws for the same seed; the nonce makes two acts
    of the same kind in one session two different pauses.
    c              3  óB   •K  — | ]}‰                      ‰¦  «        V — Œd S rH   )r­   )Ú.0Ú_r®   r“   s     €€r1   ú	<genexpr>z"plan_hesitation.<locals>.<genexpr>[  s1   øè è € ÐFÐF¨Aˆw×$Ò$ QÑ'Ô'ÐFÐFÐFÐFÐFÐFr3   rM   )r:   r&   Úsumr³   r´   )r®   rK   r4   rÂ   r“   s   `   @r1   r   r   O  sO   øø€ õ 	ˆWŒ\˜3 Ñ&Ô&€AÝÐFÐFÐFÐFÐFµµs¸1¸e±}´}Ñ1EÔ1EÐFÑFÔFÑFÔFÐFr3   ÚdistanceÚtarget_wc                ó  — t          d|¦  «        }t          j        t          |d¦  «        |z  dz   ¦  «        }| j        | j        |z  z   }|t          j        |                     d| j        ¦  «        ¦  «        z  }t          |dd¦  «        S )av  Movement time for a pointing motion. [lit] Fitts, Shannon form.

    ``target_w`` is the effective width of what is being aimed at along the
    direction of travel. A movement that aims at nothing in particular passes
    a large width, which is why parking the cursor is fast and hitting a small
    button is slow - the property a fixed ~1 s duration cannot express.
    r‡   ç      ð?ra   ç      N@g     p·@)	r´   rb   Úlog2rq   rr   rc   rd   rs   r\   )r®   r]   rÉ   rÊ   ÚwÚidxÚmts          r1   Ú	_fitts_msrÒ   b  s„   € õ 	ˆC�ÑÔ€AÝ
Œ)•C˜ #Ñ&Ô&¨Ñ*¨SÑ0Ñ
1Ô
1€CØ	Ô	˜gÔ0°3Ñ6Ñ	6€BØ�$Œ(�3—9’9˜S 'Ô"2Ñ3Ô3Ñ
4Ô
4Ñ4€Bõ �"�d˜FÑ#Ô#Ð#r3   g     €k@rÌ   ra   )Úduration_msrÊ   Únoise_scaleÚlead_msÚstartÚPointÚendrk   ÚboundsÚrenderÚRendererrÓ   úOptional[float]rÔ   rÕ   ú
List[Step]c               ó$   —  |||||
||¬¦  «        S )a	  One stroke, drawn by whoever owns stroke shape in this configuration.

    ``target_w`` IS forwarded: Fitts' law needs the width of the thing being
    hit, and two points do not contain it. The renderer implements the law and
    was being fed a per-seed constant, so a stroke to a 20 px control and one
    to a 200 px control took the same time. Handing it the box is giving the
    model a fact, not overriding its pacing.

    ``duration_ms``/``noise_scale`` are NOT forwarded. Those are pacing, and a
    renderer that owns pacing owns it completely; a caller that set half of it
    would produce a stroke that is neither model's. That distinction survived
    the deletion of the built-in model - it is about which layer knows what,
    not about which model wins.
    )rk   rÕ   rÙ   rÊ   rV   )r®   r]   rÖ   rØ   rk   rÙ   rÚ   rÓ   rÊ   rÔ   rÕ   s              r1   Ú_legrß   u  s+   € ðF ˆ6�%˜ 4°ÀØ#ð%ñ %ô %ð %r3   )rÕ   rÙ   Ú
skip_firstÚrawúIterable[Any]úOptional[Point]rà   Úboolc          	     ó–  — g }t          |¦  «        }d}t          | ¦  «        D �]¤\  }}	t          |	dd¦  «        }
|
�Tt          |	d¦  «        rDt          |
¦  «        t          |	j        ¦  «        }}t          t          |	dd¦  «        pd¦  «        }nct          |	¦  «        }t          |d         ¦  «        t          |d         ¦  «        }}t          |¦  «        dk    rt          |d         ¦  «        nd}|dk    r5|r3|t          |d¦  «        z  }t          |¦  «        t          |¦  «        f}�Œ|t          |d¦  «        z  }|�.t          |d|d         ¦  «        }t          |d|d         ¦  «        }t          |¦  «        t          |¦  «        f}||k    r|d	k     r�Œz| 
                    t          ||||¬
¦  «        ¦  «         d}|}�Œ¦|S )aV  Adapt a foreign waypoint stream to this module's :class:`Step`.

    Accepts either objects carrying ``x`` / ``y`` / ``dt_ms`` or plain
    ``(x, y, dt_ms)`` triples, which is what lets a renderer be plugged in
    without this module importing it.

    ``skip_first`` drops the leading waypoint: a generator that returns a path
    inclusive of both endpoints starts on the pointer's current position, and
    dispatching that would be an event with zero displacement.

    Two adjacent waypoints that round to the same device pixel *and* are closer
    together than a device could report them are merged. A duplicate that is
    genuinely separated in time is left alone, because "no two consecutive
    events ever share a pixel" is as much an invariant as "every event is
    0.5 px off" - a hand holding still really does report the same pixel twice.

    The threshold is one millisecond: two points scheduled in the same instant
    are one sample written twice, while 40 ms apart is a hand holding still.

    Raising it to the 8 ms sampling floor was TRIED on 2026-07-26 and reverted,
    because it did not do what it was meant to: the duplicate rate through the
    macro path only moved from 0.098 to 0.095 (the in-binary generator is
    0.081). The duplicates are not merge-threshold artefacts - they come from
    the small reading-and-drifting movements the macro layer plans, whose
    displacements round to the same device pixel while being genuinely
    separated in time. Fixing them means changing those movements, not this
    merge. Recorded so the next person does not re-try the same lever.
    Nrh   ri   Údt_msra   r   rM   é   rÌ   ©rh   ri   rj   rk   )rX   r½   ÚgetattrÚhasattrri   Útupler¾   r´   Úroundr\   rµ   r   )rá   rk   rÕ   rÙ   rà   r¶   ÚpendingÚlast_keyr·   Úprh   ÚpxÚpyÚdtÚseqÚkeys                   r1   r   r   œ  s­  € ðH €CÝ�G‰nŒn€GØ*.€HÝ˜#‘”ð ñ ‰ˆˆ1Ý�A�s˜DÑ!Ô!ˆØˆ=�W Q¨™_œ_ˆ=Ý˜1‘X”X�u Q¤S™zœz�ˆBÝ•w˜q '¨3Ñ/Ô/Ð6°3Ñ7Ô7ˆBˆBå˜‘(”(ˆCÝ˜3˜qœ6‘]”]¥E¨#¨a¬&¡M¤M�ˆBÝ"% c¡(¤(¨Q¢, ,•�s˜1”v‘”�°CˆBØ�Š6ˆ6�jˆ6Ø•s˜2˜s‘|”|Ñ#ˆGÝ˜b™	œ	¥5¨¡9¤9Ð-ˆHÙØ•3�r˜3‘<”<ÑˆØÐÝ˜˜C ¨¤Ñ+Ô+ˆBÝ˜˜C ¨¤Ñ+Ô+ˆBÝ�R‰yŒy�% ™)œ)Ð$ˆØ�(Š?ˆ?˜w¨š}˜}ÙØ�
Š
•4˜" ¨W¸4Ð@Ñ@Ô@ÑAÔAÐAØˆØˆ‰Ø€Jr3   ÚstepsúSequence[Step]Ú	budget_msÚanchorÚviewportc           	     ó€  ‡ — |dk    s‰ sg S d„ t          ‰ ¦  «        D ¦   «         }|sg S t          |¦  «        dz
  }d}t          t          |¦  «        dz
  dd¦  «        D ]E}‰ ||                  j        }||z   |k    r|t          |¦  «        dz
  k    r n||z  }|}||k    r nŒFˆ fd„||d…         D ¦   «         }	||         dz
  }
|
dk    r‰ |
         j        ‰ |
         j        fn|	d         j        dz
  |	d         j        f}|d         |d         z
  |d         |d         z
  }}g }d}|	D ]“}t          |j        |z   |j        |z   f|¦  «        }t          |d         ¦  «        t          |d         ¦  «        f}||k    rŒU|                     t          |d         |d         |j        |j
        ¬	¦  «        ¦  «         |}Œ”|S )
a&  The last ``budget_ms`` of a plan, re-anchored on the current position.

    A caller cannot travel back in time: when a plan covers a stretch of wall
    clock that has ALREADY passed, the only honest thing it can dispatch is the
    end of it. Taking the tail keeps the plan's own distribution of episode
    kinds and gaps instead of inventing a compressed one, and re-anchoring
    keeps the displacements while moving them to wherever the pointer actually
    is - the plan's absolute coordinates belong to a history that did not
    happen.
    ra   c                ó4   — g | ]\  }}|j         t          v¯|‘ŒS rV   )rk   Ú_NON_MOTION_KINDS)rÅ   r·   Úss      r1   ú
<listcomp>ztail_within.<locals>.<listcomp>ë  s)   € ÐPÐPÐP‘D�A�q°´Õ>OÐ0OÐ0OˆaÐ0OÐ0OÐ0Or3   rM   éÿÿÿÿc                ó    •— g | ]
}‰|         ‘ŒS rV   rV   )rÅ   r·   rõ   s     €r1   rþ   ztail_within.<locals>.<listcomp>ø  s   ø€ Ð-Ð-Ð-˜ˆE�!ŒHÐ-Ð-Ð-r3   Nr   rÌ   rè   )r½   r¾   r³   rj   rh   ri   Ú_in_viewportrì   rµ   r   rk   )rõ   r÷   rø   rù   ÚmotionrÖ   ÚusedÚjÚcostÚkeptÚprevÚoriginrl   rm   r¶   rî   rý   rï   rô   s   `                  r1   r   r   Ý  s  ø€ ð �CÒÐ˜uÐØˆ	ØPÐP�I eÑ,Ô,ÐPÑPÔP€FØð Øˆ	Ý�‰KŒK˜!‰O€EØ€DÝ•3�v‘;”; ‘? B¨Ñ+Ô+ð ð ˆØ�V˜A”YÔÔ(ˆØ�$‰;˜Ò"Ð" q­C°©K¬K¸!©OÒ';Ð';ØˆEØ�‰ˆØˆØ�9ÒÐØˆEð à-Ð-Ð-Ð-˜f U V VœnÐ-Ñ-Ô-€Dð �%Œ=˜1Ñ€DØ/3°qªy¨yˆe�DŒkŒm˜U 4œ[œ]Ð+Ð+ØˆQŒŒ	�C‰˜˜aœœð?€Fð �AŒY˜ œÑ" F¨1¤I°°q´	Ñ$9ˆ€BØ€Cð
 +/€HØð ð ˆÝ˜!œ# ™( A¤C¨"¡HÐ-¨xÑ8Ô8ˆÝ�Q�q”T‰{Œ{�E ! A¤$™KœKÐ(ˆØ�(Š?ˆ?ØØ�
Š
•4˜!˜Aœ$ ! A¤$°´À!Ä&ÐIÑIÔIÑJÔJÐJØˆˆØ€Jr3   c                ó<  — |\  }}t          | d¦  «        }|                     ¦   «         dk     r8|                     d|z  d|z  ¦  «        |                     d|z  d|z  ¦  «        fS |                     d|z  d|z  ¦  «        |                     d	|z  d
|z  ¦  «        fS )aq  A plausible seeded resting position for the cursor at page load.

    Never the viewport origin. A pointer whose first movement of every
    session departs from (0, 0) says the session began with no pointer state
    at all, which no real navigation produces: the cursor is wherever the
    previous interaction left it.

    [judg] Two cases, with weights chosen by reasoning rather than
    measurement: the user arrived by clicking a link on the previous page (so
    the cursor sits somewhere in the content area), or by using browser chrome
    - address bar, a bookmark, a tab - which leaves it near the top edge.
    zpointer-origing�Âõ(\�â?g
×£p=
Ç?g=
×£p=ê?g¸…ëQ¸¾?gö(\�Âõè?g{®Gáz´?g
×£p=
ç?g{®Gázt?g
×£p=
·?)r:   r8   r�   )r&   rù   rÏ   r/   r“   s        r1   r   r     sž   € ð �D€A€qÝˆTÐ#Ñ$Ô$€AØ‡x‚x�z„z�DÒÐØ—	’	˜$ ™( D¨1¡HÑ-Ô-¨q¯yªy¸À¹À4È!Á8Ñ/LÔ/LÐMÐMØ�IŠI�d˜Q‘h  q¡Ñ)Ô)¨1¯9ª9°U¸Q±YÀÀqÁÑ+IÔ+IÐJÐJr3   c                ó¬   — t          j        | j        ¦  «        }t          t          j        |                     || j        ¦  «        ¦  «        dd¦  «        S )a  One idle pause. [lit] log-normal: mostly short, with a genuine tail.

    Clipped to [180 ms, 75 s]. The floor keeps a pause distinguishable from a
    within-burst sampling gap; the ceiling stops a single draw from swallowing
    a whole session. Both are [judg].
    g     €f@g    €Oò@)rb   Úlogrz   r\   rc   rd   r{   )r®   r]   Úmus      r1   Ú	_pause_msr  -  sC   € õ 
Œ�'Ô)Ñ	*Ô	*€BÝ•$”(˜3Ÿ9š9 R¨Ô)<Ñ=Ô=Ñ>Ô>ÀÀwÑOÔOÐOr3   ç      @rï   Úmarginc                ót   — |\  }}t          | d         |||z
  ¦  «        t          | d         |||z
  ¦  «        fS )Nr   rM   )r\   )rï   rù   r  rÏ   r/   s        r1   r  r  8  s>   € Ø�D€A€qÝ�1�Q”4˜  V¡Ñ,Ô,­f°Q°q´T¸6À1ÀvÁ:Ñ.NÔ.NÐOÐOr3   c                  ób   — e Zd ZU dZded<   ded<   ded<   ded	<   d
ed<   ded<   ded<   dd„ZdS )Ú_IdleContextzùEverything an episode needs, and the only way it changes the plan.

    ``get_pos`` rather than a position: a settle emits several twitches and each
    one starts where the last ended, so the episode has to see the cursor move
    as it emits.
    r   r®   r5   r]   r×   rù   rÛ   rÚ   rX   Úpause_mszCallable[[], Point]Úget_poszCallable[[List[Step]], None]ÚemitÚampr*   c                ó   — | j                              ddt          j        z  ¦  «        }|                      ¦   «         }t          |d         |t          j        |¦  «        z  z   |d         |t          j        |¦  «        z  z   f| j        ¦  «        S )z>A destination ``amp`` px away in a uniformly random direction.ra   ç       @r   rM   )	r]   r�   rb   Úpir  r  ÚcosÚsinrù   )rI   r  ÚangÚposs       r1   Únudgez_IdleContext.nudge]  sw   € àŒh×Ò˜s C­$¬'¡MÑ2Ô2ˆØ�lŠl‰nŒnˆÝØ�ŒV�c�DœH S™MœMÑ)Ñ)¨3¨q¬6°C½$¼(À3¹-¼-Ñ4GÑ+GÐHØŒMñ
ô 
ð 	
r3   N)r  rX   r*   r×   )rQ   rR   rS   rT   rn   r  rV   r3   r1   r  r  L  s„   € € € € € € ðð ð ÐÐÑØÐÐÑØ€O€O�OØÐÐÑØ€O€O�OØ Ð Ð Ñ Ø&Ð&Ð&Ñ&ð
ð 
ð 
ð 
ð 
ð 
r3   r  r0   rF   c                ó  — | j         }t          | j                             dd¦  «        ¦  «        D ]Ñ}|                      | j        j        | j                             dd¦  «        z  ¦  «        }t          | j        | j        |  	                    ¦   «         |d| j
        | j                             dd¦  «        | j        j        z  | j        |¬¦	  «	        }| j                             d	d
¦  «        }|                      |¦  «         ŒÒdS )z«1-3 near-invisible adjustments, a pixel or two.

    The hand is resting on the mouse; [lit] 8-12 Hz tremor plus the fact that
    mouse friction swallows most of it.
    rM   é   rÌ   g      @Úsettleç      D@ç      ^@©rk   rÚ   rÓ   rÙ   rÕ   rÍ   g      y@N)r  r³   r]   Úrandintr  r®   rv   r�   rß   r  rÚ   ry   rù   r  )r0   ÚleadrÆ   ÚdestÚsegs        r1   Ú_idle_settler)  g  sâ   € ð Œ:€DÝ�1”5—=’=  AÑ&Ô&Ñ'Ô'ð ð ˆØ�wŠw�q”yÔ*¨Q¬U¯]ª]¸3ÀÑ-DÔ-DÑDÑEÔEˆå�1”9˜aœe Q§Y¢Y¡[¤[°$¸XØœ(Ø œuŸ}š}¨T°5Ñ9Ô9¸A¼IÔ<RÑRØœ*¨dð4ñ 4ô 4ˆð Œu�}Š}˜T 5Ñ)Ô)ˆØ	�Šˆs‰Œˆˆðð r3   c                ó�  — |                       | j        j        | j                             dd¦  «        z  ¦  «        }|                      t          | j        | j        |                      ¦   «         |d| j        t          | j                             dd¦  «        | j        j
        z  d¦  «        | j        | j        ¬¦	  «	        ¦  «         dS )	züA slow, small displacement of a few to a few tens of px.

    Not an aimed movement - a hand relaxing - so it is slow for its amplitude.
    [judg] 200-900 ms, persona-scaled and capped so a very fidgety persona
    still cannot creep for seconds.
    r�   çš™™™™™@Údriftr!   g      Œ@g      ™@r$  N)r  r®   rw   r]   r�   r  rß   r  rÚ   Úminry   rù   r  ©r0   r'  s     r1   Ú_idle_driftr/  y  sµ   € ð �7Š7�1”9Ô%¨¬¯ª°c¸3Ñ(?Ô(?Ñ?Ñ@Ô@€DØ‡F‚F�4�”	˜1œ5 !§)¢)¡+¤+¨t¸'Ø”xÝ ¤§¢¨e°UÑ ;Ô ;Ø"#¤)Ô"8ñ!9Ø:@ñBô Bà”z¨1¬:ð	7ñ 7ô 7ñ 8ô 8ð 8ð 8ð 8r3   c                ó(  — |                       | j        j        | j                             dd¦  «        z  ¦  «        }|                      t          | j        | j        |                      ¦   «         |d| j        d| j	        | j
        ¬¦	  «	        ¦  «         dS )a!  Parking the cursor somewhere else entirely - out of the paragraph being
    read, towards a scrollbar, off to one side. Ends NOWHERE by construction.

    ``target_w`` huge: parking is not aimed at anything, so it is fast for its
    distance - the opposite end of Fitts from a click.
    r…   r†   Úparkr«   ©rk   rÚ   rÊ   rÙ   rÕ   N)r  r®   rx   r]   r�   r  rß   r  rÚ   rù   r  r.  s     r1   Ú
_idle_parkr3  ˆ  s†   € ð �7Š7�1”9Ô*¨Q¬U¯]ª]¸4ÀÑ-EÔ-EÑEÑFÔF€DØ‡F‚F�4�”	˜1œ5 !§)¢)¡+¤+¨t¸&Ø”x¨%¸¼
Øœ
ð$ñ $ô $ñ %ô %ð %ð %ð %r3   c                ó  — | j                              dd¦  «        | j                              ¦   «         dk     rdndz  }|                      ¦   «         }t	          |d         |z   |d         | j                              dd¦  «        z   f| j        ¦  «        }|                      t          | j	        | j         ||d	| j
        t          |¦  «        | j                              d
d¦  «        z  d| j        | j        ¬¦
  «
        ¦  «         dS )zDA slow mostly-horizontal sweep, the cursor loosely following a line.rÍ   g     @u@r„   rM   rÿ   r   ra   ç       @Útracer+  ç      @r«   )rk   rÚ   rÓ   rÊ   rÙ   rÕ   N)r]   r�   r8   r  r  rd   rù   r  rß   r®   rÚ   Úabsr  )r0   Úspanr  r'  s       r1   Ú_idle_tracer:  •  sñ   € àŒ5�=Š=˜˜uÑ%Ô%¨a¬e¯lªl©n¬n¸sÒ.BÐ.B¨¨ÈÑK€DØ
�)Š)‰+Œ+€CÝ˜˜Qœ $™¨¨A¬°´·²¸SÀ#Ñ1FÔ1FÑ(FÐGØœ
ñ$ô $€Dà‡F‚F�4�”	˜1œ5 # t°'À!Ä(Ý ™IœI¨¬¯ª°c¸3Ñ(?Ô(?Ñ?Ø q¤z¸1¼:ðGñ Gô Gñ Hô Hð Hð Hð Hr3   c                  ó.   — e Zd ZU ded<   ded<   ded<   dS )Ú_IdleEpisoder)   ÚnamerX   ÚuptozCallable[[_IdleContext], None]ÚplanN)rQ   rR   rS   rn   rV   r3   r1   r<  r<     s0   € € € € € € à€I€I�IØ€K€K�KØ(Ð(Ð(Ñ(Ð(Ð(r3   r<  r!  gq=
×£pÝ?r,  çš™™™™™é?r1  g®Gázî?r6  g)\�Âõ(ð?ztuple[_IdleEpisode, ...]Ú_IDLE_EPISODESc              #  ó<   K  — | ]\  }}|j         |j         k     V — Œd S rH   )r>  )rÅ   rÀ   rÁ   s      r1   rÇ   rÇ   ²  s.   è è € Ð
OÐ
O™t˜q !ˆ1Œ6�A”FŠ?Ð
OÐ
OÐ
OÐ
OÐ
OÐ
Or3   z>cumulative weights must increase, or an episode is unreachablerÿ   zEthe last episode must catch every roll, or plan_idle can emit nothing)r4   r  c          	     ó  ‡‡‡— t          | d|¦  «        }g Š|ŠdŠdˆˆˆfd„}	 t          ||¦  «        }	‰|	z   |k    rnn‰}
|                     ¦   «         }t          |||||	ˆfd	„|¬
¦  «        }t          D ]$}||j        k     r|                     |¦  «          nŒ%‰|
k    r‰|	z  Š‰|k    rnŒˆ|t          d„ ‰D ¦   «         ¦  «        z
  }|dk    r7‰                     t          ‰d         ‰d         |t          ¬¦  «        ¦  «         ‰S )aé  Plan what the pointer does during ``duration_ms`` of "reading".

    This is the piece that has no counterpart today: between two clicks the
    current behaviour is exactly nothing. The plan here is a sequence of
    (pause, small action) episodes:

      settle      1-3 near-invisible adjustments, a pixel or two. The hand is
                  resting on the mouse; [lit] 8-12 Hz tremor plus the fact
                  that mouse friction swallows most of it.
      drift       a slow, small displacement of a few to a few tens of px.
      reposition  parking the cursor somewhere else entirely - out of the
                  paragraph being read, towards a scrollbar, off to one side.
                  This one ends NOWHERE by construction.
      trace       a slow mostly-horizontal sweep, the cursor loosely following
                  a line of text.

    Weights are [judg]: small fidgets dominate, deliberate repositioning is
    occasional. The point is the shape, not the exact split - and every
    amplitude scales with the session's persona, so the split a detector could
    measure is not the same split in the next session.

    The plan covers exactly ``duration_ms``: when the next pause would overrun
    the budget the episodes stop and the leftover time is emitted as a single
    ``"wait"`` step. Silence is a legitimate outcome of an idle period - it
    just has to be accounted for rather than dropped, or every activity
    fraction computed from the timeline comes out too high.
    Úidlera   r(  rÝ   r*   rF   c                ó¦   •— | sdS ‰                      | ¦  «         | d         j        | d         j        fŠ‰t          d„ | D ¦   «         ¦  «        z  ŠdS )z>Append a planned segment and advance the clock and the cursor.Nrÿ   c              3  ó$   K  — | ]}|j         V — Œd S rH   ©rj   ©rÅ   rý   s     r1   rÇ   z*plan_idle.<locals>.emit.<locals>.<genexpr>ë  s$   è è € Ð/Ð/ a�q”zÐ/Ð/Ð/Ð/Ð/Ð/r3   )Úextendrh   ri   rÈ   )r(  Úelapsedr  rõ   s    €€€r1   r  zplan_idle.<locals>.emitâ  sa   ø€ ð ð 	ØˆFØ�Š�SÑÔÐØ�2ŒwŒy˜#˜bœ'œ)Ð$ˆð 	•3Ð/Ð/¨3Ð/Ñ/Ô/Ñ/Ô/Ñ/ˆˆˆr3   Tc                 ó   •— ‰ S rH   rV   )r  s   €r1   ú<lambda>zplan_idle.<locals>.<lambda>ö  s   ø€ ¨3€ r3   )r®   r]   rù   rÚ   r  r  r  c              3  ó$   K  — | ]}|j         V — Œd S rH   rG  rH  s     r1   rÇ   zplan_idle.<locals>.<genexpr>
  s$   è è € Ð ;Ð ;° ¤Ð ;Ð ;Ð ;Ð ;Ð ;Ð ;r3   r7  r   rM   rè   )r(  rÝ   r*   rF   )r:   r  r8   r  rA  r>  r?  rÈ   rµ   r   Ú
_WAIT_KIND)r&   r®   r  rù   rÓ   r4   rÚ   r“   r  ÚpauseÚbeforeÚrollÚctxÚepisodeÚresidualrJ  r  rõ   s                  @@@r1   r   r   ¸  s�  øøø€ õJ 	ˆT�6˜5Ñ!Ô!€AØ€EØ
€CØ€Gð	0ð 	0ð 	0ð 	0ð 	0ð 	0ð 	0ð 	0ðÝ˜' 1Ñ%Ô%ˆØ�U‰?˜kÒ)Ð)ØØˆà�xŠx‰zŒzˆÝ 7°¸HØ"(°5Ø#. ; ; ;°Tð;ñ ;ô ;ˆõ &ð 	ð 	ˆGØ�g”lÒ"Ð"Ø—’˜SÑ!Ô!Ð!Ø�ð #ð �fÒÐð �uÑˆGØ�kÒ!Ð!Øð)ð: �SÐ ;Ð ;°UÐ ;Ñ ;Ô ;Ñ;Ô;Ñ;€HØ�3‚€Ø�Š•T˜C œF c¨!¤f°xÝ)ð+ñ +ô +ñ 	,ô 	,ð 	,à€Lr3   g      Y@)Útick_dyr4   ÚticksrU  c               óœ  — t          | d|¦  «        }g }	|}
t          t          |d¦  «        ¦  «        D �]™}|r|                     dd¦  «        n|                     dd¦  «        }|	                     t          |
d         |
d         |t          ||                     dd	¦  «        z  ¬
¦  «        ¦  «         |                     ¦   «         dk     �r |j        |                     dd¦  «        z  }|                     ddt          j
        z  ¦  «        }t          |
d         |t          j        |¦  «        z  z   |
d         |t          j        |¦  «        z  z   f|¦  «        }t          |||
|d||                     dd¦  «        ||                     dd¦  «        ¬¦	  «	        }|r/|	                     |¦  «         |d         j        |d         j        f}
�Œ›|rü|                     ¦   «         dk     rä|j        |                     dd¦  «        z  }|                     ddt          j
        z  ¦  «        }t          |
d         |t          j        |¦  «        z  z   |
d         |t          j        |¦  «        z  z   f|¦  «        }t          |||
|d||                     dd¦  «        ||                     dd¦  «        ¬¦	  «	        }|	                     |¦  «         |	S )a_  Plan a scroll burst with the pointer motion that goes with it.

    A hand that is turning a wheel is a hand resting on a mouse, and a mouse
    under a moving finger does not hold perfectly still: the wheel finger
    flexes, the palm shifts, and the cursor creeps by a pixel or several.
    A wheel event stream with a byte-identical pointer position throughout is
    a hand that is not attached to the mouse.

    Returns a single interleaved timeline: ``kind == "wheel"`` steps carry the
    scroll delta in ``dy`` and repeat the current pointer position, everything
    else is a pointer move.

    [lit] a notched wheel produces discrete detents, so ticks are discrete and
    the inter-tick gap is short. [judg] 55-115 ms between detents while
    spinning, a creep of a pixel or two per tick, and an occasional larger
    settle when the burst ends.
    Úscrollr   g     €K@ç     À\@rƒ   ç     @p@rM   g333333ë?gffffffò?)rh   ri   rj   rk   rm   r„   rÌ   r‡   ra   r  Úscroll_driftg      >@r5  r"  r$  rÿ   g…ëQ¸Õ?r@  g      @r,  r#  rˆ   rÍ   g      t@)r:   r³   r´   r�   rµ   r   Ú_WHEEL_KINDr8   rv   rb   r  r  r  r  rß   rI  rh   ri   rw   )r&   r®   r  rù   rV  rU  r4   rÚ   r“   rõ   r  r·   r¹   r  r  r'  r(  s                    r1   r   r     sº  € õ8 	ˆT�8˜UÑ#Ô#€AØ€EØ
€CÝ•3�u˜a‘=”=Ñ!Ô!ð -ñ -ˆØ()ÐEˆa�iŠi˜˜eÑ$Ô$Ð$¨q¯yªy¸¸uÑ/EÔ/EˆØ�Š•T˜C œF c¨!¤f°sÝ*Ø$ q§y¢y°°tÑ'<Ô'<Ñ<ð>ñ >ô >ñ 	?ô 	?ð 	?ð �8Š8‰:Œ:˜ÒÑØÔ# a§i¢i°°SÑ&9Ô&9Ñ9ˆCØ—)’)˜C ¥t¤w¡Ñ/Ô/ˆCÝØ�Q”˜#¥¤¨¡¤Ñ-Ñ-¨s°1¬v¸½d¼hÀs¹m¼mÑ8KÑ/KÐLØñô ˆDõ �w  3¨°>È&Ø#$§9¢9¨T°4Ñ#8Ô#8Ø&°·	²	¸#¸tÑ0DÔ0DðFñ Fô FˆCð ð -Ø—’˜SÑ!Ô!Ð!Ø˜2”w”y # b¤'¤)Ð,�ùð ð 
�—’‘”˜dÒ"Ð"ØÔ §¢¨3°Ñ!4Ô!4Ñ4ˆØ�iŠi˜˜S¥4¤7™]Ñ+Ô+ˆÝØ�ŒV�c�DœH S™MœMÑ)Ñ)¨3¨q¬6°C½$¼(À3¹-¼-Ñ4GÑ+GÐHØñ
ô 
ˆõ �7˜A˜s D¨w¸vØ Ÿyšy¨°Ñ6Ô6Ø"¨A¯IªI°d¸EÑ,BÔ,BðDñ Dô Dˆð 	�Š�SÑÔÐØ€Lr3   ÚboxÚBoxÚuxÚuyc                óZ   — | \  }}}}t          ||z  ¦  «        t          ||z  ¦  «        z   S )zEExtent of a rectangle along the direction of travel - the W in Fitts.)r8  )r]  r_  r`  rÆ   rÏ   r/   s         r1   Ú_support_widthrb  [  s.   € à�J€A€qˆ!ˆQÝˆq�2‰v‰;Œ;�˜Q ™V™œÑ$Ð$r3   rŒ   r�   )ÚspreadÚkeeprc  rd  c               ó  — | \  }}}}||dz  z   ||dz  z   }	}t          |                     |||z  ¦  «        |||z  z
  |||z  z   ¦  «        }
t          |                     |	||z  ¦  «        |	||z  z
  |	||z  z   ¦  «        }|
|fS )a  Where inside a control the pointer actually stops.

    [judg] Gaussian about the centre with sigma = ``spread`` of the box side,
    clipped to the middle ``2 * keep`` of it, so the landing is inside, biased
    to the middle, and essentially never the exact geometric centre. Landing on
    the centre pixel of every control is a stronger signal than any curve
    shape: it is one exact number, it is the same number for every install,
    and any handler can read it off a single event.

    The default clip is tight on purpose. This point is also handed to the
    automation layer as the click position, and a point far out towards a
    border is a point that a rounded corner, a rotated element or an inline box
    that does not fill its bounding rectangle can fail to contain.
    r  )r\   rd   )r]  r]   rc  rd  ÚbxÚbyÚbwÚbhÚcxÚcyrh   ri   s               r1   r   r   a  s™   € ð  �N€BˆˆB�Ø�"�s‘(‰]˜B  c¡™Mˆ€BÝˆs�yŠy˜˜R &™[Ñ)Ô)¨2°°r±	©>¸2ÀÀrÁ	¹>ÑJÔJ€AÝˆs�yŠy˜˜R &™[Ñ)Ô)¨2°°r±	©>¸2ÀÀrÁ	¹>ÑJÔJ€AØˆqˆ6€Mr3   Úwidthc                ó°   — t          j        t          |d¦  «        t          |d¦  «        z  dz   ¦  «        }dd|z  z   | j        z  }t	          |dd¦  «        S )a!  Probability that this movement overshoots and needs a correction.

    [lit] Meyer et al.'s optimised-submovement account: pointing is a fast
    ballistic primary submovement plus, when the primary misses, one or more
    slower corrective submovements. Corrections get more likely as the index
    of difficulty rises - far targets and small targets. [judg] the intercept
    and slope below, and the persona multiplier; they are set so that an easy
    move (ID ~ 1) corrects rarely and a hard one (ID ~ 6) corrects most of the
    time.
    rÌ   r‡   çš™™™™™¹?gÃõ(\�Âµ?g¸…ëQ¸ž?g)\�Âõ(ì?)rb   rÎ   r´   r|   r\   )r®   rÉ   rl  rÐ   rï   s        r1   Úovershoot_probabilityro  x  sW   € õ Œ)•C˜ #Ñ&Ô&­¨U°C©¬Ñ8¸3Ñ>Ñ
?Ô
?€CØ	�˜‘Ñ	˜wÔ5Ñ5€AÝ�!�T˜4Ñ Ô Ð r3   )r4   ÚlandingÚtargetrp  c               óÆ  — t          | d|¦  «        }t          ||¦  «        }	|€|	n|}|d         |d         z
  |d         |d         z
  }}
t          j        |
|¦  «        }|dk     rg S |
|z  ||z  }}t	          t          |||¦  «        d¦  «        }g }|                     ¦   «         t          |||¦  «        k     �rót          | 	                    dd|z  ¦  «        ¦  «        | 
                    d	d¦  «        z   }t          |d
t	          dd|z  ¦  «        ¦  «        }| 	                    dd|z  ¦  «        }t          |d         ||z  z   ||z  z
  |d         ||z  z   ||z  z   f|¦  «        }|t          ||||d|t	          |dz  d¦  «        |¬¦  «        z  }|r|d         j        |d         j        fn|}t          | 	                    dd¦  «        dd¦  «        }t          ||||d||||¬¦	  «	        }||z  }|r¶|                     ¦   «         dk     ržt          |d         | 	                    dd¦  «        z   |d         | 	                    dd¦  «        z   f|¦  «        }|t          ||||d|| 
                    dd¦  «        |t          | 	                    dd¦  «        dd¦  «        ¬¦	  «	        z  }�n4|                     ¦   «         dk     �rt          t          | 	                    dd|z  ¦  «        ¦  «        d	z   d	t	          dd |z  ¦  «        ¦  «        }|d         ||z  z
  |d         ||z  z
  f}|t          ||||d|t	          |d
z  d!¦  «        |¬¦  «        z  }|r|d         j        |d         j        fn|}|t          ||||d|| 
                    d"d#¦  «        |t          | 	                    d$d¦  «        dd¦  «        ¬¦	  «	        z  }n|t          ||||d|||¬¦  «        z  }|S )%aû  Plan a movement that ends on a control, the way a hand ends on one.

    ``landing`` overrides where inside the control the pointer stops. The
    caller passes it when it also has to tell the automation layer where to
    click: the two must be the same point, or the pointer lands on one pixel
    and the click is dispatched at another.

    Three outcomes, in decreasing order of frequency for hard targets:

      overshoot + correct   the primary submovement carries past the target,
                            the eye catches it, a short corrective submovement
                            comes back. [lit] Meyer et al. 1988.
      undershoot + settle   the primary stops short and the hand creeps in.
      straight in           one submovement, lands, done.

    The dwell between the primary and the correction is not padding: [lit]
    visually-guided correction cannot start before roughly 100-150 ms of
    feedback delay, so the gap exists in real pointing and its absence is
    itself informative.
    r"   Nr   rM   rÌ   r‡   ra   g
×£p=
§?g      ø?r  r5  g{®GázÄ?r…   r  g      d@©rk   rÚ   rÊ   rÙ   rÿ   g     @_@r"  g     €F@g     €q@r#   r2  r‹   r†   g      I@g     @`@g     €[@rZ  r$  gìQ¸…ë¡?rn  r#  rÍ   g     Àg@rY  )r:   r   rb   Úhypotr´   rb  r8   ro  r8  rd   r�   r\   r  rß   rh   ri   )r&   r®   r  rq  rù   r4   rp  rÚ   r“   Údrawnrl   rm   Údistr_  r`  rl  rõ   ÚoverÚlateralÚpastr  r¸   ÚcorrÚmicroÚshortÚstops                             r1   r   r   ‰  s[  € õ> 	ˆT�:˜uÑ%Ô%€AÝ˜& !Ñ$Ô$€EØ�ˆeˆe¨G€GØ�QŒZ˜& œ)Ñ# W¨Q¤Z°&¸´)Ñ%;ˆ€BÝŒ:�b˜"ÑÔ€DØˆc‚z€zØˆ	Ø�$‰Y˜˜T™	ˆ€BÝ•˜v r¨2Ñ.Ô.°Ñ4Ô4€Eà€EØ‡x‚x�z„zÕ)¨'°4¸Ñ?Ô?Ò?Ñ?õ �1—7’7˜3 ¨¡Ñ-Ô-Ñ.Ô.°·²¸3ÀÑ1DÔ1DÑDˆÝ�d˜C¥ S¨$°©+Ñ!6Ô!6Ñ7Ô7ˆØ—'’'˜#˜t d™{Ñ+Ô+ˆÝØ�QŒZ˜"˜t™)Ñ# b¨7¡lÑ2Ø�QŒZ˜"˜t™)Ñ# b¨7¡lÑ2ð4àñ
ô 
ˆð 	•�g˜q &¨$°ZÈÝ" 5¨3¡;°Ñ6Ô6¸xðIñ Iô Iñ 	Iˆà,1Ð=ˆu�RŒyŒ{˜E "œIœKÐ(Ð(°vˆå�q—w’w˜u dÑ+Ô+¨T°5Ñ9Ô9ˆÝ�G˜Q  W°9ÀVØ"¨8¸UðDñ Dô Dˆà�‰ˆð ð 	M�A—H’H‘J”J Ò%Ð%Ý Ø˜”˜aŸgšg c¨3Ñ/Ô/Ñ/°¸´¸a¿gºgÀcÈ3Ñ>OÔ>OÑ1OÐPØñô ˆEð •T˜' 1 g¨u¸9Ø!'°Q·Y²Y¸tÀUÑ5KÔ5KØ!)Ý"(¨¯ª°¸Ñ)=Ô)=¸tÀUÑ"KÔ"KðMñ Mô Mñ MˆEùð 
�Š‰Œ�dÒ	Ñ	Ý•s˜1Ÿ7š7 3¨°©Ñ5Ô5Ñ6Ô6¸Ñ<¸cÝ˜3  t¡Ñ,Ô,ñ.ô .ˆà˜”
˜R %™ZÑ'¨°¬°b¸5±jÑ)@ÐAˆØ•�g˜q &¨$°ZÈÝ" 5¨3¡;°Ñ6Ô6¸xðIñ Iô Iñ 	Iˆà,1Ð=ˆu�RŒyŒ{˜E "œIœKÐ(Ð(°vˆØ•�g˜q # w°YÀvØ"#§)¢)¨D°%Ñ"8Ô"8ÀÝ$ Q§W¢W¨U°DÑ%9Ô%9¸4ÀÑGÔGðIñ Iô Iñ 	Iˆˆð 	•�g˜q &¨'¸
Ø#¨e¸HðFñ Fô Fñ 	Fˆà€Lr3   )Úavoidr4   r~  úOptional[Sequence[Box]]c          
     ó‚  ‡— t          | d|¦  «        }|\  }}	t          |pd¦  «        }
|dz  |	dz  f}t          d¦  «        D ]Y}|                     d|z  d|z  ¦  «        |                     d|	z  d|	z  ¦  «        fŠ‰}t	          ˆfd„|
D ¦   «         ¦  «        s nŒZt          |||t          ||¦  «        d|d	|¬
¦  «        S )a×  Plan a movement whose endpoint is not on anything.

    If every movement in a session terminates on a clickable element, the
    endpoints alone identify the session regardless of how good the paths
    between them are. ``avoid`` is the list of control boxes the caller knows
    about; the destination is redrawn until it falls outside all of them
    (bounded retries - if the viewport really is wall-to-wall controls we take
    the last draw rather than loop).
    ÚaimlessrV   r  é   g{®Gáz¤?g¸…ëQ¸î?c              3  ó†   •K  — | ];\  }}}}|‰d          cxk    o||z   k    nc o|‰d         cxk    o||z   k    nc V — Œ<dS )r   rM   NrV   )rÅ   rf  rg  rh  ri  Úcands        €r1   rÇ   z$plan_aimless_move.<locals>.<genexpr>  sŒ   øè è € ð 0ð 0Ù%�r˜2˜r 2ð ˜˜aœÐ+Ð+Ò+Ð+ B¨¡GÒ+Ð+Ð+Ð+ÐH°°d¸1´gÐ0HÐ0HÒ0HÐ0HÀÀbÁÒ0HÐ0HÐ0HÐ0Hð 0ð 0ð 0ð 0ð 0ð 0r3   r1  rˆ   rs  )r:   Úlistr³   r�   Úanyrß   r  )r&   r®   r  rù   r~  r4   rÚ   r“   rÏ   r/   Úboxesr'  rÆ   r„  s                @r1   r   r   è  s  ø€ õ& 	ˆT�9˜eÑ$Ô$€AØ�D€A€qÝ��˜"ÑÔ€EØ�‰G�Q˜‘WÐ€DÝ�2‰YŒYð ð ˆØ—	’	˜$ ™( D¨1¡HÑ-Ô-¨q¯yªy¸À¹À4È!Á8Ñ/LÔ/LÐMˆØˆÝð 0ð 0ð 0ð 0Ø).ð0ñ 0ô 0ñ 0ô 0ð 	àˆEð	õ �˜˜F¥L°°xÑ$@Ô$@Ø F°UÀ8ðMñ Mô Mð Mr3   c                  ó‚   — e Zd ZU dZded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ded<   ded<   ded<   dS )r   zFDescriptive statistics of a planned timeline. No I/O, pure arithmetic.rX   Útotal_msÚ	active_msÚactive_fractionr'   Ún_stepsÚn_movesÚn_wheelÚn_burstsÚn_duplicate_positionsÚbursts_on_controlÚon_control_fractionÚlongest_pause_msN)rQ   rR   rS   rT   rn   rV   r3   r1   r   r     s�   € € € € € € àPÐPà€O€O�OØÐÐÑØÐÐÑØ€L€L�LØ€L€L�LØ€L€L�LØ€M€M�MØÐÐÑØÐÐÑØÐÐÑØÐÐÑÐÐr3   r   c                ó¤  — d}d}dx}x}x}x}}d}d}	d}
d}| D ]ê}||j         z  }|j        t          v rD|j        t          k    r|dz  }|
r|dz  }|t          v r|dz  }d}
t          ||j         ¦  «        }d}	Œ^|dz  }|j         t          k    r|
r||j         z  }n,|
r|dz  }|t          v r|dz  }t          ||j         ¦  «        }d}
|j        }t          |j        ¦  «        t          |j	        ¦  «        f}|	�||	k    r|dz  }|}	Œë|
r|dz  }|t          v r|dz  }t          |||dk    r||z  ndt          | ¦  «        ||||||r||z  nd|¬¦  «        S )	a>  Reduce a timeline to the numbers worth asserting on.

    ``active_ms`` is wall time spent inside a burst of motion: the delay of a
    move step counts as active when it is short enough to be part of a
    continuous movement (``BURST_GAP_MS``). The long delay that opens a burst
    is the pause before it and counts as still. Applied to the behaviour this
    module replaces - one ~1 s movement every twenty-odd seconds and nothing
    in between - this measure yields the ~4% that motivated the work, so the
    "after" number is comparable to the "before" number.
    ra   r   NFÚ rM   T)r‰  rŠ  r‹  rŒ  r�  rŽ  r�  r�  r‘  r’  r“  )rj   rk   rü   r\  Ú_ON_CONTROL_KINDSr´   r    rì   rh   ri   r   r¾   )rõ   ÚtotalÚactiveÚmovesr$   ÚburstsÚdupsÚon_ctrlÚlongest_pauseÚprev_posÚin_burstÚlast_move_kindrý   r  s                 r1   r   r   ,  sé  € ð €EØ€FØ./Ð/€EÐ/ˆEÐ/�FÐ/˜T GØ€MØ*.€HØ€HØ€Nàð ð ˆØ�”ÑˆØŒ6Õ&Ð&Ð&ØŒv�Ò$Ð$Ø˜‘
�ð ð !Ø˜!‘�Ø!Õ%6Ð6Ð6Ø˜q‘L�GØ �Ý ¨q¬zÑ:Ô:ˆMð ˆHØØ�‰
ˆØŒ:�Ò%Ð%¨(Ð%Ø�a”jÑ ˆFˆFàð !Ø˜!‘�Ø!Õ%6Ð6Ð6Ø˜q‘L�GÝ ¨q¬zÑ:Ô:ˆMØˆHØœˆÝ�Q”S‰zŒz�5 ¤™:œ:Ð&ˆØÐ C¨8¢O OØ�A‰IˆDØˆˆØð Ø�!‰ˆØÕ.Ð.Ð.Ø�q‰LˆGåØØØ,1°AªI¨I˜ %™˜¸3Ý�E‘
”
ØØØØ"Ø!Ø28ÐA˜W vÑ-Ð-¸cØ&ðñ ô ð r3   )r&   r'   r(   r)   r*   r'   rP   )r&   r'   r(   r)   r4   r'   r*   r5   )r;   r'   r<   r'   r*   r'   )r?   r@   rA   r'   r*   r'   )rW   rX   rY   rX   rZ   rX   r*   rX   )r]   r5   r^   rX   r_   rX   r*   rX   )r–   r)   r*   r)   )rM   r   )r®   r   r¯   r'   r4   r'   r*   r°   )rº   r)   r®   r   r4   r'   r*   r°   )r   rM   )
r®   r   rK   r)   r4   r'   rÂ   r'   r*   rX   )
r®   r   r]   r5   rÉ   rX   rÊ   rX   r*   rX   )r®   r   r]   r5   rÖ   r×   rØ   r×   rk   r)   rÙ   r×   rÚ   rÛ   rÓ   rÜ   rÊ   rX   rÔ   rX   rÕ   rX   r*   rÝ   )rá   râ   rk   r)   rÕ   rX   rÙ   rã   rà   rä   r*   rÝ   )
rõ   rö   r÷   rX   rø   r×   rù   r×   r*   rÝ   )r&   r'   rù   r×   r*   r×   )r®   r   r]   r5   r*   rX   )r  )rï   r×   rù   r×   r  rX   r*   r×   )r0   r  r*   rF   )r&   r'   r®   r   r  r×   rù   r×   rÓ   rX   r4   r'   rÚ   rÛ   r*   rÝ   )r&   r'   r®   r   r  r×   rù   r×   rV  r'   rU  rX   r4   r'   rÚ   rÛ   r*   rÝ   )r]  r^  r_  rX   r`  rX   r*   rX   )
r]  r^  r]   r5   rc  rX   rd  rX   r*   r×   )r®   r   rÉ   rX   rl  rX   r*   rX   )r&   r'   r®   r   r  r×   rq  r^  rù   r×   r4   r'   rp  rã   rÚ   rÛ   r*   rÝ   )r&   r'   r®   r   r  r×   rù   r×   r~  r  r4   r'   rÚ   rÛ   r*   rÝ   )rõ   rö   r*   r   )GrT   Ú
__future__r   rb   r8   Údataclassesr   r¼   r   r   r   r   r	   r
   r   r   Ú__all__rX   r×   r^  r    Ú	frozensetr–  r\  rN  rü   r2   r:   r   r   r   r\   re   r   rÛ   r   Úsetr›   rœ   r�   r   r   r   r   rÒ   rß   r   r   r   r  r  r  r)  r/  r3  r:  r<  rA  rn   ÚallÚzipr>  r   r   rb  r   ro  r   r   r   r   rV   r3   r1   ú<module>r¨     s>  ððPð Pð Pðb #Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø !Ð !Ð !Ð !Ð !Ð !ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð €ð. 	ˆe�UˆlÔ€ØˆE�5˜% Ð&Ô'€ð €ð �I˜z¨9Ð5Ñ6Ô6Ð ð €Ø€
Ø�I˜{¨JÐ7Ñ8Ô8Ð ðð ð ð ð<ð <ð <ð <ð <ð5ð 5ð 5ð 5ð=ð =ð =ð =ð*''ð ''ð ''ð ''ð ''ñ ''ô ''ð ''ðT3ð 3ð 3ð 3ð
4ð 
4ð 
4ð 
4ð" €�$ÐÑÔð!ð !ð !ð !ð !ñ !ô !ñ Ôð!ð\ �C˜˜fœÐ%Ô&€ð €�$ÐÑÔðp
ð p
ð p
ð p
ð p
ñ p
ô p
ñ Ôðp
ðP ˆSÐ=Ñ>Ô>€
ØˆcÐJÑKÔK€ðð ð ð ð €�$ÐÑÔðJRð JRð JRð JRð JRñ JRô JRñ ÔðJRðZ 78Øðð ð ð ð ð: ð ð  ð  ð  ð  ðF DEØ!"ðGð Gð Gð Gð Gð&$ð $ð $ð $ð8 $(ØØØð$%ð $%ð $%ð $%ð $%ð $%ðV Ø"Øð>ð >ð >ð >ð >ð >ðB1ð 1ð 1ð 1ðpKð Kð Kð Kð0Pð Pð Pð PðPð Pð Pð Pð Pð( €�$ÐÑÔð
ð 
ð 
ð 
ð 
ñ 
ô 
ñ Ôð
ð4ð ð ð ð$8ð 8ð 8ð 8ð
%ð 
%ð 
%ð 
%ðHð Hð Hð Hð €�$ÐÑÔð)ð )ð )ð )ð )ñ )ô )ñ Ôð)ð €L�˜4 Ñ.Ô.Ø€L�˜$ Ñ,Ô,Ø€L�˜˜zÑ*Ô*Ø€L�˜$ Ñ,Ô,ð	,€ð ð ð ñ ð €sÐ
OÐ
O s s¨>¸>È!È"È"Ô;MÑ'NÔ'NÐ
OÑ
OÔ
OÑOÔOð Fð FØDñFô FÐOà�bÔÔ Ò$Ð$Ð$ØKñ %Ô$Ð$ð ðVð Vð Vð Vð Vð VðH Øð?ð ?ð ?ð ?ð ?ð ?ðL%ð %ð %ð %ð DHØ $ðð ð ð ð ð ð.!ð !ð !ð !ð0 Ø#ðXð Xð Xð Xð Xð XðJ &*ØðMð Mð Mð Mð Mð Mðf €�$ÐÑÔðð ð ð ð ñ ô ñ Ôðð Dð Dð Dð Dð Dð Dr3   