§
    ®	Êjç)  ã                  ó¨   — d Z ddlmZ ddlZddlmZmZmZmZ d%d
„Z	d&d„Z
d'd„Zd(d„Zd)d„Zd(d„Zd*d„Zd+d„Zd,d-d„Zd.d„Zd(d„Zd/d „Zd0d#„Zd1d$„ZdS )2uµ  Turning protocol values into Python ones, and back.

â›” THESE ARE LEAVES, WHICH IS WHY THEY COULD MOVE AT ALL. Not one of them
mentions a dispatcher class: they take a value and return a value. `server.py`
holds a mutually recursive object graph - a page makes frames, a frame makes
element handles, a handle points back at its frame - and splitting THAT across
modules buys navigation with import cycles, which is a bad trade. These do not
have the problem, and they were scattered BETWEEN the classes: reading
`ElementHandleDispatcher` you fell into `_serialize` on the way to
`FrameDispatcher`.

They are re-exported from `server.py`, so nothing that imported them from
there has to move.
é    )ÚannotationsN)ÚAnyÚDictÚListÚOptionalÚ
expressionÚstrÚargumentr   Úreturnc                ó(   — dt          | |¦  «        z  S )aH  Wrap an expression so it can always be CALLED with the argument.

    <M> PLAYWRIGHT SENDS BOTH FORMS DOWN THE SAME FIELD. `page.evaluate("1+1")`
    and `page.evaluate("() => document.title")` arrive as the same
    `expression` string, and the client does not say which is which. Evaluating
    the raw string works for the first and, for the second, produces a FUNCTION
    OBJECT: no error, no exception, and the caller gets None back for a call
    that looked fine.

    Measured on 2026-08-27: `page.evaluate("() => !!x")` answered None, and the
    assertion that caught it read like the browser had changed behaviour.

    So the string is wrapped and the result called if it turned out to be a
    function. Deciding by shape - does it start with `(` or `function` or
    `async` - is the version that gets it wrong: `(1+2)` starts with a
    parenthesis and is not a function.

    <M> THE ARGUMENT GOES IN HERE, IN THE SAME PASS, AND THAT IS THE WHOLE
    POINT. It used to be spelled `r(ARG)` and the caller substituted it
    afterwards with `.replace("ARG", ...)` - over a string that already held
    the caller's expression. So every uppercase `ARG` a caller wrote was
    rewritten to the argument's JSON, inside their own code, silently.

    Measured on 2026-09-14 by driving it: `'CARGO'.length` answered 6 instead
    of 5, because the source that ran was `'CnullO'.length`; a selector
    `[data-role='TARGET']` became `[data-role='TnullET']` and matched nothing;
    `/ARGH/` became `/nullH/`; and `const ARG = 5` was a SyntaxError. The three
    letters need only appear inside a longer word - MARGIN, LARGE, CHARGE - and
    three of those four failures are silent, which is the bad kind.

    A format string is only scanned where the format string itself is, so the
    expression is an ARGUMENT to `%` and never a place `%` looks.
    z(() => { %s })())Ú_invocation)r   r
   s     úVC:\Projects\Muse2API\.venv\Lib\site-packages\invisible_playwright/_juggler/_marshal.pyÚ_as_callabler      s   € ðD ¥¨J¸Ñ AÔ AÑAÐAó    Ú	receiversc           
     ót   — d| ›dd                      |t          j        |t          ¬¦  «        fz   ¦  «        ›d�S )a£  The statements that evaluate the caller's expression and, when it is a
    function, call it with `receivers` first and the argument last.

    <M> THE ONLY PLACE THAT SPELLS THE CALL. The main-world wrapper above and
    the three element-scoped ones (`handle.evaluate`, `eval_on_selector`,
    `eval_on_selector_all`) used to write it out each on its own, and that is
    how the argument reached `handle.evaluate` and was dropped by the other
    two: a callback reading its second parameter got `undefined` there.

    The main-world output is pinned byte for byte by
    `test_the_argument_does_not_rewrite_the_expression.py`, because that one
    runs as the page.
    zconst r = (z');  return typeof r === 'function' ? r(z, )Údefaultz) : r;)ÚjoinÚjsonÚdumpsr	   )r   r
   r   s      r   r   r   :   sE   € € ð ˆzˆzØ�yŠy˜¥d¤j°Å3Ð&GÑ&GÔ&GÐ%IÑIÑJÔJÐJÐJðLð Mr   Úparamsr   Úreceiverc                óp   — t          | d         t          |                      d¦  «        ¦  «        |¦  «        S )z˜The body of an element-scoped wrapper: the caller's function called
    with `receiver` and the caller's argument, Playwright's `fn(element, arg)`.
    r   Úarg)r   Ú_deserializeÚget)r   r   s     r   Ú
_called_onr   M   s6   € õ �v˜lÔ+­\¸&¿*º*ÀUÑ:KÔ:KÑ-LÔ-LØñ!ô !ð !r   c                ó(   — dt          | d¦  «        z  S )z†The declaration `handle.evaluate` and `eval_on_selector` both send: one
    element, then the argument. Both run in the utility world.z(injected, el) => { %s }Úel)r   ©r   s    r   Ú_element_functionr!   U   s   € ð &­
°6¸4Ñ(@Ô(@Ñ@Ð@r   Úvaluec                ó´  — t          | t          ¦  «        s| S d| v rd| v rt          | d         ¦  «        S dd„ fdd„ fdd„ ffD ]\  }}|| v r || |         ¦  «        c S Œd	| v rHd
d
t          d¦  «        t          d¦  «        t          d¦  «        dœ                     | d	         ¦  «        S d| v rd„ | d         D ¦   «         S d| v rd„ | d         D ¦   «         S d
S )zCThe tagged union Playwright sends for an ARGUMENT, back to a value.r"   ÚhandlesÚnc                ó   — | S ©N© ©Úvs    r   ú<lambda>z_deserialize.<locals>.<lambda>a   ó   € ¨€ r   Úsc                ó   — | S r'   r(   r)   s    r   r+   z_deserialize.<locals>.<lambda>a   s   € ¸Q€ r   Úbc                ó   — | S r'   r(   r)   s    r   r+   z_deserialize.<locals>.<lambda>b   r,   r   r*   NÚnanÚinfz-inf)ÚnullÚ	undefinedÚNaNÚInfinityz	-InfinityÚac                ó,   — g | ]}t          |¦  «        ‘ŒS r(   ©r   )Ú.0Úxs     r   ú
<listcomp>z _deserialize.<locals>.<listcomp>j   s   € Ð4Ð4Ð4 A•˜Q‘”Ð4Ð4Ð4r   Úoc                óF   — i | ]}|d          t          |d         ¦  «        “ŒS ©Úkr*   r9   )r:   Úes     r   ú
<dictcomp>z _deserialize.<locals>.<dictcomp>l   s*   € ÐAÐAÐA°��#”� Q s¤VÑ,Ô,ÐAÐAÐAr   )Ú
isinstanceÚdictr   Úfloatr   )r"   ÚtagÚconverts      r   r   r   [   s)  € å�e�TÑ"Ô"ð ØˆØ�%ÐÐ˜I¨Ð.Ð.Ý˜E 'œNÑ+Ô+Ð+Ø˜{˜{Ð+¨c°;°;Ð-?Ø˜{˜{Ð+ð-ð 'ð '‰ˆˆWà�%ˆ<ˆ<Ø�7˜5 œ:Ñ&Ô&Ð&Ð&Ð&ð à
ˆe€|€|Ø¨4½¸e¹¼Ý! %™LœLÝ" 6™]œ]ð,ð ,ç,/ªC°°c´
©O¬Oð	<ð ˆe€|€|Ø4Ð4¨¨s¬Ð4Ñ4Ô4Ð4Ø
ˆe€|€|ØAÐA°e¸C´jÐAÑAÔAÐAØˆ4r   c                ón   — t          | d         t          |                      d¦  «        ¦  «        ¦  «        S )zþThe expression, callable, with the caller's argument placed in it.

    <M> THE ONLY PLACE THAT BUILDS THIS. `wait_for_function` used to repeat the
    two lines inline, which is how one of the two could have been fixed and the
    other left alone.
    r   r   )r   r   r   r    s    r   Ú_with_argumentrI   p   s-   € õ ˜˜|Ô,­l¸6¿:º:ÀeÑ;LÔ;LÑ.MÔ.MÑNÔNÐNr   c                ó*   — t          j        | ¦  «        S )uj  A Python string as a JavaScript literal.

    â›” `json.dumps` and never manual quoting: the html handed to `set_content`
    is arbitrary, and a single quote, a backslash or a line separator inside it
    would close the literal early. That exact defect - an apostrophe closing a
    single-quoted JavaScript string - broke the driver bundle on 2026-08-24.
    )r   r   ©r"   s    r   Ú
_js_stringrL   z   s   € õ Œ:�eÑÔÐr   úOptional[str]c                óH   — t          | t          ¦  «        rd| v r| d         S d S )NÚguid)rC   rD   rK   s    r   Ú_guid_ofrP   …   s+   € Ý�%�ÑÔð  6¨U ? ?Ø�VŒ}ÐØˆ4r   ÚcounterúOptional[Dict]c                ó  ‡— ‰€ddiŠ| €ddiS t          | t          ¦  «        rd| iS t          | t          t          f¦  «        rd| iS t          | t          ¦  «        rd| iS t          | t
          t          f¦  «        r'‰dxx         dz  cc<   ˆfd	„| D ¦   «         ‰d         d
œS t          | t          ¦  «        r9‰dxx         dz  cc<   ˆfd„|                      ¦   «         D ¦   «         ‰d         dœS dt	          | ¦  «        iS )uG  A Python value in the shape `parse_result` expects.

    â›” Playwright does not send bare JSON: it sends a tagged union, and
    `_connection.parse_value` reads the TAG. A bare `True` where `{"b": true}`
    is expected does not raise - it falls through to the object branch and comes
    back as something else entirely.
    Nr%   r   r*   r3   r/   r-   é   c                ó0   •— g | ]}t          |‰¦  «        ‘ŒS r(   ©Ú
_serialize)r:   r;   rQ   s     €r   r<   z_serialize.<locals>.<listcomp>¦   s#   ø€ Ð<Ð<Ð<°•j  GÑ,Ô,Ð<Ð<Ð<r   )r7   Úidc                ó<   •— g | ]\  }}|t          |‰¦  «        d œ‘ŒS )r?   rV   )r:   r@   r*   rQ   s      €r   r<   z_serialize.<locals>.<listcomp>©   s?   ø€ ð 1ð 1ð 1Ù˜!˜Qð ¥J¨q°'Ñ$:Ô$:Ð;Ð;ð 1ð 1ð 1r   )r=   rX   )	rC   ÚboolÚintrE   r	   ÚlistÚtuplerD   Úitems)r"   rQ   s    `r   rW   rW   ‹   sP  ø€ ð €Ø˜�(ˆØ€}Ø�Vˆ}ÐÝ�%�ÑÔð Ø�Uˆ|ÐÝ�%�#�u˜Ñ&Ô&ð Ø�Uˆ|ÐÝ�%�ÑÔð Ø�Uˆ|ÐÝ�%�$¥˜Ñ'Ô'ð 	Rð 	�ˆˆŒ˜Ñˆˆ‰Ø<Ð<Ð<Ð<°eÐ<Ñ<Ô<ÀGÈCÄLÐQÐQÐQÝ�%�ÑÔð FØ�ˆˆŒ˜Ñˆˆ‰ð1ð 1ð 1ð 1Ø"'§+¢+¡-¤-ð1ñ 1ô 1Ø8?À¼ðFð Fð 	Fà•�U‘”ÐÐr   úList[Dict[str, str]]c           
     ó.  — t          | t          ¦  «        rd„ |                      ¦   «         D ¦   «         S g }| pg D ]Z}t          |t          ¦  «        rCd|v r?|                     |d         t	          |                     dd¦  «        ¦  «        dœ¦  «         Œ[|S )u®  Headers as the ARRAY of pairs the client expects, never a dict.

    â›” `RawHeaders` iterates over `[{"name": ..., "value": ...}]` and a dict
    iterates over its KEYS, so handing one over does not raise: it produces a
    header list whose every value is missing, and `response.headers` comes back
    full of empty strings. Juggler already sends the array form; this exists so
    a caller-built dict cannot slip through.
    c                ó8   — g | ]\  }}|t          |¦  «        d œ‘ŒS )©Únamer"   )r	   )r:   r@   r*   s      r   r<   z"_headers_array.<locals>.<listcomp>¹   s*   € ÐEÐEÐE±°°A˜¥S¨¡V¤VÐ,Ð,ÐEÐEÐEr   rc   r"   Ú rb   )rC   rD   r^   Úappendr	   r   )ÚrawÚoutÚentrys      r   Ú_headers_arrayri   ¯   sª   € õ �#•tÑÔð FØEÐE¸¿º¹¼ÐEÑEÔEÐEØ
€CØ�˜ð ?ð ?ˆÝ�e�TÑ"Ô"ð 	? v°  Ø�JŠJ  f¤Ý!$ U§Y¢Y¨w¸Ñ%;Ô%;Ñ!<Ô!<ð>ð >ñ ?ô ?ð ?øà€Jr   c                óÄ   — |                       d¦  «        p|                       d¦  «        pd                     ¦   «         }dddddddd	d
ddddœ                      |d¦  «        S )u"  â›” Juggler says `cause`, Playwright says `resourceType`, and the two
    vocabularies only partly overlap. An unmapped cause becomes `other`, which
    is what upstream does too - guessing a nicer name would make
    `request.resource_type` disagree with itself between the two transports.ÚcauseÚinternalCauserd   ÚdocumentÚ
stylesheetÚscriptÚimageÚfontÚmediaÚxhrÚfetchÚ	websocketÚother)rm   Úsubdocumentrn   ro   rp   Úimagesetrq   rr   Úxmlhttprequestrt   ru   Úbeacon)r   Úlower)r   rk   s     r   Ú_resource_typer|   Â   su   € ð
 �ZŠZ˜Ñ Ô ÐE F§J¢J¨Ñ$?Ô$?ÐEÀ2×LÒLÑNÔN€Eà¨zØ"¨hØ gØ Ø¨'Ø ¨Gðð ÷ 
‚cˆ%�ÑÔðr   rc   r[   c                ó:   — ddddœ                      | pdd¦  «        S )Nr   rT   é   )ÚleftÚmiddleÚrightr   ©r   )rc   s    r   Ú_buttonrƒ   Ò   s&   € Ø ¨QÐ/Ð/×3Ò3°D°N¸FÀAÑFÔFÐFr   Úargsr\   c                ón  — g }| D �]}t          |t          ¦  «        s#|                     t          |¦  «        ¦  «         Œ;d|v r)|                     t          |d         ¦  «        ¦  «         Œh|                     d¦  «        r)|                     t          |d         ¦  «        ¦  «         Œ¦|                     d¦  «        r)|                     t          |d         ¦  «        ¦  «         Œä|                     t          |                     d¦  «        pd¦  «        ¦  «         �Œd                     |¦  «        S )uÞ   â›” The console arguments arrive as remote objects, not as text. Reading
    `value` works for a primitive and gives nothing for an object, so the
    preview is used when there is one - which is what the driver shows too.r"   ÚpreviewÚunserializableValueÚtypeÚobjectú )rC   rD   re   r	   r   r   )r„   Úpiecesr7   s      r   Ú_console_textrŒ   Ö   s  € ð €FØð 
:ñ 
:ˆÝ˜!�TÑ"Ô"ð 		:Ø�MŠM�#˜a™&œ&Ñ!Ô!Ð!Ð!Ø˜ˆ\ˆ\Ø�MŠM�#˜a œj™/œ/Ñ*Ô*Ð*Ð*Ø�UŠU�9ÑÔð 	:Ø�MŠM�#˜a 	œlÑ+Ô+Ñ,Ô,Ð,Ð,Ø�UŠUÐ(Ñ)Ô)ð 	:Ø�MŠM�#˜aÐ 5Ô6Ñ7Ô7Ñ8Ô8Ð8Ð8à�MŠM�#˜aŸeše F™mœmÐ7¨xÑ8Ô8Ñ9Ô9Ð9Ñ9Ø�8Š8�FÑÔÐr   c                óè   — | pi } |                       d¦  «        pd|                       d¦  «        p|                       d¦  «        pd|                       d¦  «        p|                       d¦  «        pddœS )	u±   â›” ALWAYS a location, never None: `_browser_context.py` casts it and
    falls back only on a missing KEY, so a null here becomes an AttributeError
    somewhere else entirely.Úurlrd   Ú
lineNumberÚliner   ÚcolumnNumberÚcolumn)rŽ   r�   r‘   r‚   )rf   s    r   Ú	_locationr“   é   sy   € ð ˆ)�€CØ—7’7˜5‘>”>Ð' RØŸ'š' ,Ñ/Ô/ÐG°3·7²7¸6±?´?ÐGÀaØŸGšG NÑ3Ô3ÐM°s·w²w¸xÑ7HÔ7HÐMÈAðOð Oð Or   )r   r	   r
   r   r   r	   )r   r	   r
   r   r   r	   r   r	   )r   r   r   r	   r   r	   )r   r   r   r	   )r"   r   r   r   )r"   r	   r   r	   )r"   r   r   rM   r'   )r"   r   rQ   rR   r   r   )r   r_   )rc   rM   r   r[   )r„   r\   r   r	   )r   r   )Ú__doc__Ú
__future__r   r   Útypingr   r   r   r   r   r   r   r!   r   rI   rL   rP   rW   ri   r|   rƒ   rŒ   r“   r(   r   r   ú<module>r—      s“  ððð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,ð"Bð "Bð "Bð "BðJMð Mð Mð Mð&!ð !ð !ð !ðAð Að Að Aðð ð ð ð*Oð Oð Oð Oðð ð ð ðð ð ð ð ð  ð  ð  ð  ðHð ð ð ð&ð ð ð ð Gð Gð Gð Gðð ð ð ð&Oð Oð Oð Oð Oð Or   