§
    øžyjxC  ã                  ó  — U d Z ddlmZ ddlZddlZddlZddl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 i Zded<   dD ]Z eeed¦  «        Ze�ee ee¦  «        <   Œ d)d„Zd*d„Zd+d„Zd,d„Zd-d.d„Zddœd/d „Zd0d"„Zd0d#„Zd1d&„Zd2d(„ZdS )3u  Shutdown forensics â€” capture context when the gateway receives SIGTERM/SIGINT.

The gateway's ``shutdown_signal_handler`` runs synchronously inside the
asyncio event loop.  We can't safely block it for long, but we DO want a
durable record of who/what triggered the shutdown so that "the gateway
keeps dying" incidents can be diagnosed after the fact.

This module exposes :func:`snapshot_shutdown_context`, a fast (<10ms),
non-blocking probe that returns a structured dict the signal handler can
log immediately, plus :func:`spawn_async_diagnostic`, a fire-and-forget
``ps`` walk that runs as a detached subprocess so it can't block teardown
even if /proc is wedged.

Anything that needs to wait (e.g. shelling out to ``ps aux``) belongs in
the async helper, never in the synchronous probe.
é    )ÚannotationsN)ÚPath)ÚAnyÚDictÚListÚOptionalzDict[int, str]Ú_SIGNAL_NAME_BY_NUM)ÚSIGTERMÚSIGINTÚSIGHUPÚSIGQUITÚSIGUSR1ÚSIGUSR2Úsigr   ÚreturnÚstrc                ó´   — | €dS 	 t          | ¦  «        }n&# t          t          f$ r t          | ¦  «        cY S w xY wt                               |d|› �¦  «        S )zBReturn a human-readable signal name (or ``str(sig)`` as fallback).NÚUNKNOWNzsignal#)ÚintÚ	TypeErrorÚ
ValueErrorr   r	   Úget)r   Úsig_ints     ú@/home/ragecks/.hermes/hermes-agent/gateway/shutdown_forensics.pyÚ_signal_namer   %   sl   € à
€{ØˆyðÝ�c‘(”(ˆˆøÝ•zÐ"ð ð ð Ý�3‰xŒxˆˆˆðøøøå×"Ò" 7Ð,?°gÐ,?Ð,?Ñ@Ô@Ð@s   † – 9¸9Úpidr   ÚkeyúOptional[str]c                óR  — 	 t          d| › d�d¬¦  «        5 }|D ]V}|                     |dz   ¦  «        r<|                     dd¦  «        d                              ¦   «         c cddd¦  «         S ŒW	 ddd¦  «         n# 1 swxY w Y   n# t          t
          t          f$ r Y nw xY wdS )zIRead a single field from /proc/<pid>/status.  Linux only; None elsewhere.ú/proc/z/statusúutf-8©Úencodingú:é   N)ÚopenÚ
startswithÚsplitÚstripÚFileNotFoundErrorÚPermissionErrorÚOSError)r   r   ÚfhÚlines       r   Ú_read_proc_fieldr/   0   s(  € ðÝÐ'˜3Ð'Ð'Ð'°'Ð:Ñ:Ô:ð 	9¸bØð 9ð 9�Ø—?’? 3¨¡9Ñ-Ô-ð 9ØŸ:š: c¨1Ñ-Ô-¨aÔ0×6Ò6Ñ8Ô8Ð8Ð8ð	9ð 	9ð 	9ð 	9ñ 	9ô 	9ð 	9ð 	9ð9ð9ð	9ð 	9ð 	9ñ 	9ô 	9ð 	9ð 	9ð 	9ð 	9ð 	9ð 	9øøøð 	9ð 	9ð 	9ð 	9øøõ �µÐ8ð ð ð Øˆðøøøàˆ4sA   ‚B
 —AA>Á#B
 Á0A>Á2B
 Á>BÂB
 ÂBÂB
 Â
B$Â#B$c                óD  — 	 t          d| › d�d¦  «        5 }|                     ¦   «         }ddd¦  «         n# 1 swxY w Y   n# t          t          t          f$ r Y dS w xY w|sdS |                     dd¦  «                             dd¬	¦  «                             ¦   «         S )
zLRead /proc/<pid>/cmdline as a printable string.  Linux only; None elsewhere.r    z/cmdlineÚrbNó    ó    r!   Úreplace)Úerrors)r&   Úreadr*   r+   r,   r4   Údecoder)   )r   r-   Údatas      r   Ú_read_proc_cmdliner9   <   sì   € ðÝÐ(˜3Ð(Ð(Ð(¨$Ñ/Ô/ð 	°2Ø—7’7‘9”9ˆDð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	øøå�µÐ8ð ð ð Øˆtˆtðøøøàð Øˆtà�<Š<˜ Ñ&Ô&×-Ò-¨g¸iÐ-ÑHÔH×NÒNÑPÔPÐPs,   ‚A –7«A ·;»A ¾;¿A ÁAÁAúDict[str, Any]c                óˆ  — d| i}| dk    r|S t          | d¦  «        }|�||d<   t          | d¦  «        }|�||d<   t          | d¦  «        }|�$	 t          |¦  «        |d	<   n# t          $ r Y nw xY wt          | d
¦  «        }|�!|r|                     ¦   «         d         n||d<   t	          | ¦  «        }|r|dd…         |d<   |S )zŒCompact /proc/<pid> snapshot: pid, ppid, state, uid, cmdline.

    Best-effort.  Missing fields are simply omitted rather than raising.
    r   r   ÚNameNÚnameÚStateÚstateÚPPidÚppidÚUidÚuidé,  Úcmdline)r/   r   r   r(   r9   )r   Úsummaryr=   r?   rA   rC   rE   s          r   Ú_proc_summaryrG   I   s  € ð
  % c˜l€GØ
ˆa‚x€xØˆÝ˜C Ñ(Ô(€DØÐØˆ�‰Ý˜S 'Ñ*Ô*€EØÐØ ˆ�ÑÝ˜C Ñ(Ô(€DØÐð	Ý! $™iœiˆG�F‰OˆOøÝð 	ð 	ð 	ØˆDð	øøøå
˜3 Ñ
&Ô
&€CØ
€à+.Ð7˜Ÿš™œ Qœ˜°Cˆ�‰Ý  Ñ%Ô%€GØð +à$ T c Tœ]ˆ�	ÑØ€Ns   ÁA! Á!
A.Á-A.Úreceived_signalc           
     óf  — t          j         ¦   «         }t          j        ¦   «         }t          j        ¦   «         }t          j        ¦   «         }||t          | ¦  «        | �t          | ¦  «        nd||t          |¦  «        t          |¦  «        dœ}t          j         	                    d¦  «        }|r||d<   t          j         	                    d¦  «        }|r||d<   t          |¦  «        p|dk    |d<   	 t          j        ¦   «         d	         |d
<   n# t          t          f$ r Y nw xY w	 t          |d¦  «        }|�c|dk    r]|                     ¦   «         rt          |¦  «        n||d<   |                     ¦   «         rt          t          |¦  «        ¦  «        nd|d<   n# t           t"          f$ r Y nw xY w	 t          j         	                    d¦  «        }	|	rÇt%          |	¦  «        dz  }
|
                     ¦   «         rF	 |
                     d¬¦  «        }|dd…         |d<   d|› �|v pd|› �|v |d<   n# t          $ r Y nw xY wt%          |	¦  «        dz  }|                     ¦   «         r5	 |                     d¬¦  «        }|dd…         |d<   n# t          $ r Y nw xY wn# t*          $ r Y nw xY w|S )a'  Fast (<10ms) snapshot of who/what is asking us to shut down.

    Captures:

    * The signal number/name (so SIGINT vs SIGTERM is visible)
    * Our own PID/ppid + parent process info from /proc (Linux)
    * Whether systemd is our parent (``ppid==1`` or ``INVOCATION_ID`` set)
    * Whether takeover/planned-stop markers exist (consumed lazily by the caller)
    * /proc/self limits + load average (1-min)
    * Wall-clock and monotonic timestamps for cross-correlating later phases

    Pure stdlib, never raises, never blocks on subprocesses.
    N)ÚtsÚts_monotonicÚsignalÚ
signal_numr   rA   ÚparentÚselfÚINVOCATION_IDÚsystemd_invocation_idÚJOURNAL_STREAMÚsystemd_journal_streamr%   Úunder_systemdr   Ú
loadavg_1mÚ	TracerPidÚ0Ú
tracer_pidÚtracerÚHERMES_HOMEz.gateway-takeover.jsonr!   r"   rD   Útakeover_markerz"target_pid": z'target_pid': Útakeover_marker_for_selfz.gateway-planned-stop.jsonÚplanned_stop_marker)ÚtimeÚ	monotonicÚosÚgetpidÚgetppidr   r   rG   Úenvironr   ÚboolÚ
getloadavgr,   ÚAttributeErrorr/   Úisdigitr   r   r   ÚexistsÚ	read_textÚ	Exception)rH   Únowr_   r   rA   ÚctxÚinvocation_idÚjournal_streamrY   Úhermes_home_strÚtakeover_pathÚrawÚplanned_stop_paths                r   Úsnapshot_shutdown_contextrs   h   s0  € õ Œ)‰+Œ+€CÝ”Ñ Ô €IÝ
Œ)‰+Œ+€CÝŒ:‰<Œ<€Dð Ø!Ý˜Ñ/Ô/Ø.=Ð.I•c˜/Ñ*Ô*Ð*ÈtØØÝ Ñ%Ô%Ý˜cÑ"Ô"ð	ð 	€Cõ ”J—N’N ?Ñ3Ô3€MØð 5Ø'4ˆÐ#Ñ$Ý”Z—^’^Ð$4Ñ5Ô5€NØð 7Ø(6ˆÐ$Ñ%Ý Ñ.Ô.Ð;°$¸!²)€CˆÑðÝœM™OœO¨AÔ.ˆˆLÑÐøÝ•^Ð$ð ð ð ØˆðøøøðÝ! # {Ñ3Ô3ˆØÐ &¨C¢- -Ø/5¯~ª~Ñ/?Ô/?Ð K¥ F¡¤ ÀVˆC�ÑØ:@¿.º.Ñ:JÔ:JÐT�M­#¨f©+¬+Ñ6Ô6Ð6ÐPTˆC�‰MøøÝ•zÐ"ð ð ð ØˆðøøøðÝœ*Ÿ.š.¨Ñ7Ô7ˆØð 	Ý  Ñ1Ô1Ð4LÑLˆMØ×#Ò#Ñ%Ô%ð 	ðØ'×1Ò1¸7Ð1ÑCÔC�CØ-0°°#°¬Y�CÐ)Ñ*à.¨Ð.Ð.°#Ð5ð 9Ø1¨CÐ1Ð1°SÐ8ð Ð2Ñ3Ð3øõ ð ð ð Ø�Dðøøøå $ _Ñ 5Ô 5Ð8TÑ TÐØ ×'Ò'Ñ)Ô)ð ðØ+×5Ò5¸wÐ5ÑGÔG�CØ14°T°c°T´�CÐ-Ñ.Ð.øÝð ð ð Ø�Dðøøøøøåð ð ð Øˆðøøøð €Js€   Ã5D ÄD&Ä%D&Ä*A5F  Æ F4Æ3F4Æ8AJ! È 4H5 È4J! È5
IÈ?J! ÉIÉ)J! É,#J ÊJ! Ê
JÊJ! ÊJÊJ! Ê!
J.Ê-J.g      @)Útimeout_secondsÚlog_pathr   Úsignal_namert   ÚfloatúOptional[int]c               óR  — 	 | j                              dd¬¦  «         n# t          $ r Y dS w xY wt          j        dk    rdS d|› dt          j        ¦   «         › d�}	 t          j        t          | ¦  «        t
          j	        t
          j
        z  t
          j        z  d¦  «        }n# t          $ r Y dS w xY w	 t          j        d	|d
›dd|g|t          j        t          j        dd¬¦  «        }nd# t           t          f$ rP 	 t          j        |¦  «         n# t          $ r Y nw xY wY 	 t          j        |¦  «         dS # t          $ r Y dS w xY ww xY w	 	 t          j        |¦  «         n:# t          $ r Y n.w xY w# 	 t          j        |¦  «         w # t          $ r Y w w xY wxY w|j        S )aœ  Fire-and-forget ``ps``-style snapshot written to ``log_path``.

    Runs as a detached subprocess so it can't block the asyncio event loop
    or compete with platform teardown.  The subprocess uses its own
    ``timeout`` so a wedged ``ps`` still self-cleans within
    ``timeout_seconds``.

    Returns the subprocess PID on success, ``None`` on failure.  Never
    raises.

    We deliberately avoid ``subprocess.run(["ps", "aux"])`` from inside the
    signal handler (the pre-existing pattern): on a busy host with hundreds
    of processes, ``ps aux`` can take >2s to walk /proc, during which the
    asyncio loop is frozen and adapter teardown can't begin.
    T)ÚparentsÚexist_okNÚwin32z echo '=== shutdown diagnostic @ zº ==='; echo '--- date ---'; date -u +%Y-%m-%dT%H:%M:%SZ; echo '--- ps auxf (top 60 by cpu) ---'; ps auxf --sort=-pcpu 2>/dev/null | head -60; echo '--- pstree of self ---'; pstree -plau a   2>/dev/null | head -40 || true; echo '--- /proc/loadavg ---'; cat /proc/loadavg 2>/dev/null || true; echo '--- recent dmesg (oom/killed) ---'; dmesg -T 2>/dev/null | tail -20 || journalctl --user -n 20 --no-pager 2>/dev/null | tail -20 || true; echo '=== end ==='i¤  Útimeoutz.0fÚbashz-c)ÚstdoutÚstderrÚstdinÚstart_new_sessionÚ	close_fds)rN   Úmkdirr,   ÚsysÚplatformr`   ra   r&   r   ÚO_WRONLYÚO_CREATÚO_APPENDÚ
subprocessÚPopenÚSTDOUTÚDEVNULLr*   Úcloser   )ru   rv   rt   ÚscriptÚfdÚprocs         r   Úspawn_async_diagnosticr’   Å   s3  € ð*ØŒ×Ò d°TÐÑ:Ô:Ð:Ð:øÝð ð ð Øˆtˆtðøøøõ „|�wÒÐØˆtð
	¨;ð 
	ð 
	õ
 œ	™œð
	ð 
	ð 
	ð ðõ ŒW•S˜‘]”]¥B¤Kµ"´*Ñ$<½r¼{Ñ$JÈEÑRÔRˆˆøÝð ð ð Øˆtˆtðøøøðõ ÔØ˜?Ð0Ð0°&¸$ÀÐGØÝÔ$ÝÔ$Ø"Øð
ñ 
ô 
ˆˆøõ �wÐ'ð ð ð ð	ÝŒH�R‰LŒLˆLˆLøÝð 	ð 	ð 	ØˆDð	øøøàð	ÝŒH�R‰LŒLˆLˆLˆLøÝð 	ð 	ð 	ØˆDˆDð	øøøðøøøð 	ð 	ÝŒH�R‰LŒLˆLˆLøÝð 	ð 	ð 	ØˆDð	øøøøð	ÝŒH�R‰LŒLˆLˆLøÝð 	ð 	ð 	ØˆDð	øøøøøøð Œ8€Osµ   ‚ Ÿ
-¬-ÁAB% Â%
B3Â2B3Â75C- Ã,E8 Ã-EÃ?DÄEÄ
D!ÄEÄ D!Ä!EÄ$E8 Ä&D< Ä<
E
Å	E
ÅEÅE8 ÅE( Å(
E5Å4E5Å8FÅ:FÆFÆ
FÆFÆFÆFrl   c                ó2  — |                       dd¦  «        }|                       d¦  «        pi }|                      dd¦  «        }|                      d¦  «        pd}|                      d¦  «        pd}|                       d¦  «        rd	nd
}|                       d¦  «        }t          |t          t          f¦  «        r|d›nd}g }	|                       d¦  «        �1|                       d¦  «        }
|	                     d|
rdnd› �¦  «         |                       d¦  «        �|	                     d¦  «         |                       d¦  «        r|	                     d| d         › �¦  «         |	rdd                     |	¦  «        z   nd}d|› d|› d|› d|› d|› |› d|›�S )z?Render a shutdown context dict as a single, scannable log line.rL   ú?rN   rE   z	(unknown)r=   r   rT   ÚyesÚnorU   z.2fr[   Nr\   ztakeover_marker_present=rO   Úotherr]   zplanned_stop_marker_present=yesrX   ztracer_pid=Ú Ú zsignal=z under_systemd=z parent_pid=z parent_name=z loadavg_1m=z parent_cmdline=)r   Ú
isinstancer   rw   ÚappendÚjoin)rl   r   rN   Ú
parent_cmdÚparent_nameÚ
parent_pidrT   ÚloadÚload_strÚextrasÚfor_selfÚ
extras_strs               r   Úformat_context_for_logr¥     sì  € à
�'Š'�(˜CÑ
 Ô
 €CØ�WŠW�XÑÔÐ$ "€FØ—’˜I {Ñ3Ô3€JØ—*’*˜VÑ$Ô$Ð+¨€KØ—’˜EÑ"Ô"Ð) c€JØ ŸWšW _Ñ5Ô5Ð?�E�E¸4€MØ�7Š7�<Ñ Ô €DÝ *¨4µ#µu°Ñ >Ô >ÐG�$ˆ}ˆ}ˆ}ÀC€HØ€FØ
‡w‚wÐ Ñ!Ô!Ð-Ø—7’7Ð5Ñ6Ô6ˆØ�ŠØH°Ð'F v v¸wÐHÐHñ	
ô 	
ð 	
ð ‡w‚wÐ$Ñ%Ô%Ð1Ø�ŠÐ7Ñ8Ô8Ð8Ø
‡w‚wˆ|ÑÔð 9Ø�ŠÐ7 C¨Ô$5Ð7Ð7Ñ8Ô8Ð8Ø-3Ð;�#˜Ÿš Ñ(Ô(Ñ(Ð(¸€Jð	)�#ð 	)ð 	)Ø&ð	)ð 	)à ð	)ð 	)ð #ð	)ð 	)ð ð		)ð
 ð	)ð 	)ð %ð	)ð 	)ðó    c                ól   — 	 t          j        | t          d¬¦  «        S # t          t          f$ r Y dS w xY w)zFJSON-serialise a context dict for structured ingestion.  Never raises.T)ÚdefaultÚ	sort_keysz{})ÚjsonÚdumpsr   r   r   )rl   s    r   Úcontext_as_jsonr¬   :  sE   € ðÝŒz˜#¥s°dÐ;Ñ;Ô;Ð;øÝ•zÐ"ð ð ð Øˆtˆtðøøøs   ‚ ž3²3Údrain_timeoutúOptional[Dict[str, Any]]c           	     ó¼  — t           j                             d¦  «        }|sdS d}	 t          dd¬¦  «        5 }|D ]\}d|v rV|                     ¦   «                              d¦  «        }t          |¦  «        D ]}|                     d¦  «        r|} nŒ|r nŒ]ddd¦  «         n# 1 swxY w Y   n# t          t          f$ r Y nw xY w|sdS d}dgg fD ]ï}	 t          j        d	g|¢d
‘|‘d‘ddddd¬¦  «        }	n"# t          t          j        t          f$ r Y ŒEw xY w|	j        dk    rŒU|	j                             ¦   «         D ]|}|                     d¦  «        re|                     dd¦  «        d                              ¦   «         }
|
                     ¦   «         rt%          |
¦  «        }nt'          |
¦  «        }|� nŒ}|� nŒð|€dS |dz  }d}| |z   }||| |||k     dœS )u.  At startup, sanity-check that systemd's TimeoutStopSec >= drain_timeout.

    When the gateway is run under a stale systemd unit file (e.g. the user
    upgraded hermes-agent but never re-ran ``hermes setup`` to regenerate
    the unit), ``TimeoutStopSec`` can be smaller than the configured
    ``restart_drain_timeout``.  Result: SIGTERM arrives, the drain starts,
    and systemd SIGKILLs the cgroup mid-drain â€” looks like a phantom kill
    in the journal because the journal only logs ``code=killed status=9``.

    Returns ``None`` when the alignment is fine OR we can't determine it
    (not running under systemd, ``systemctl`` unavailable, etc.).  Returns
    a dict with ``timeout_stop_sec`` + ``drain_timeout`` + ``mismatch``
    bool when we have data to report.

    Best-effort.  Never raises.
    rP   Nz/proc/self/cgroupr!   r"   z.serviceú/z--userÚ	systemctlÚshowz--property=TimeoutStopUSecTr4   g       @)Úcapture_outputÚtextr#   r5   r}   r   zTimeoutStopUSec=Ú=r%   g    €„.Ag      >@)ÚunitÚtimeout_stop_secr­   Úexpected_minÚmismatch)r`   rc   r   r&   r)   r(   ÚreversedÚendswithr,   r*   rŠ   ÚrunÚTimeoutExpiredÚ
returncoder   Ú
splitlinesr'   rg   r   Ú_parse_systemd_duration_to_us)r­   rm   Ú	unit_namer-   r.   ÚpartsÚpÚ
timeout_usÚflagÚresultÚvaluer·   ÚheadroomÚexpecteds                 r   Úcheck_systemd_timing_alignmentrÊ   B  sÐ  € õ" ”J—N’N ?Ñ3Ô3€MØð Øˆtð  $€IðåÐ%°Ð8Ñ8Ô8ð 
	¸BØð 	ð 	�à Ð%Ð%Ø ŸJšJ™LœL×.Ò.¨sÑ3Ô3�EÝ% e™_œ_ð "ð "˜ØŸ:š: jÑ1Ô1ð "Ø()˜IØ!˜Eð"ð !ð Ø˜øð
	ð 
	ð 
	ñ 
	ô 
	ð 
	ð 
	ð 
	ð 
	ð 
	ð 
	øøøð 
	ð 
	ð 
	ð 
	øøõ Õ&Ð'ð ð ð Øˆðøøøàð Øˆtð
 !%€JØ�˜RÐ ð ð ˆð	Ý”^ØÐU˜tÐU VÐU¨YÐUÐ8TÐUØ#¨$¸ÈÐ\_ðñ ô ˆFˆFøõ "¥:Ô#<½gÐFð 	ð 	ð 	ØˆHð	øøøàÔ Ò!Ð!Øà”M×,Ò,Ñ.Ô.ð 		ð 		ˆDØ�ŠÐ1Ñ2Ô2ð ØŸ
š
 3¨Ñ*Ô*¨1Ô-×3Ò3Ñ5Ô5�à—=’=‘?”?ð FÝ!$ U¡¤�J�Jå!>¸uÑ!EÔ!E�JØÐ)Ø�EøØÐ!ØˆEð "ð ÐØˆtà! KÑ/Ðð €HØ˜xÑ'€HàØ,Ø&Ø Ø$ xÒ/ðð ð sG   §B0 ¸A B$ÂB0 Â$B(Â(B0 Â+B(Â,B0 Â0CÃCÃ#C9Ã9DÄDrq   c                óê  — | sdS ddddddddœ}d}d	}d	}| d
z   D �]O}|                      ¦   «         s|dk    rp|rh|                     |                     ¦   «         ¦  «        }|�|s dS 	 |t          t	          |¦  «        |z  ¦  «        z  }n# t
          $ r Y  dS w xY wd	}d	}||z  }Œ�|                     ¦   «         r||z  }Œ§|rj|rh|                     |                     ¦   «         ¦  «        }|€ dS 	 |t          t	          |¦  «        |z  ¦  «        z  }n# t
          $ r Y  dS w xY wd	}d	}�Œ|r:|s8	 |t          t	          |¦  «        dz  ¦  «        z  }n# t
          $ r Y  dS w xY wd	}�ŒQ|dk    r|ndS )zÕParse 'TimeoutStopUSec=1min 30s' / '90s' style values to microseconds.

    systemd accepts a wide grammar; we cover the common cases (s, ms, min,
    h) and return None on anything unexpected.  Never raises.
    Nr%   iè  i@B i ‡“l    $'- )ÚusÚmsÚsÚsecÚminÚhÚhrr   r™   r˜   ú.)rg   r   Úlowerr   rw   r   Úisalpha)rq   ÚunitsÚtotal_usÚtokenÚdigitsÚchÚ
multipliers          r   rÀ   rÀ   ™  s  € ð ð ØˆtàØØØØØØðð €Eð €HØ€EØ€FØ�C‰ið  ñ  ˆØ�:Š:‰<Œ<ð 	˜2 š9˜9Øð 
à"ŸYšY u§{¢{¡}¤}Ñ5Ô5�
ØÐ%¨VÐ%Ø˜4˜4ð Ø¥¥E¨&¡M¤M°JÑ$>Ñ ?Ô ?Ñ?�H�HøÝ!ð  ð  ð  Ø˜4˜4˜4ð øøøà�Ø�Ø�b‰LˆFˆFØ�ZŠZ‰\Œ\ð 	Ø�R‰KˆEˆEØð 	˜ð 	ØŸš 5§;¢;¡=¤=Ñ1Ô1ˆJØÐ!Ø�t�tðØ�C¥ f¡¤°
Ñ :Ñ;Ô;Ñ;��øÝð ð ð Ø�t�t�tðøøøàˆFØˆE‰EØð 	˜Eð 	ðØ�C¥ f¡¤°	Ñ 9Ñ:Ô:Ñ:��øÝð ð ð Ø�t�t�tðøøøàˆFùØ !’|�|ˆ8ˆ8¨Ð-s6   Á("BÂ
BÂBÃ2"DÄ
D$Ä#D$Ä2"EÅ
E$Å#E$)r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   )r   r   r   r:   )N)rH   r   r   r:   )ru   r   rv   r   rt   rw   r   rx   )rl   r:   r   r   )r­   rw   r   r®   )rq   r   r   rx   ) Ú__doc__Ú
__future__r   rª   r`   rL   rŠ   r…   r^   Úpathlibr   Útypingr   r   r   r   r	   Ú__annotations__Ú_nameÚgetattrÚ_valr   r   r/   r9   rG   rs   r’   r¥   r¬   rÊ   rÀ   © r¦   r   ú<module>rå      sè  ððð ð ð" #Ð "Ð "Ð "Ð "Ð "à €€€Ø 	€	€	€	Ø €€€Ø Ð Ð Ð Ø 
€
€
€
Ø €€€Ø Ð Ð Ð Ð Ð Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,ð ')Ð Ð (Ð (Ð (Ñ (ØMð /ð /€EØˆ7�6˜5 $Ñ'Ô'€DØÐØ).Ð˜C˜C ™IœIÑ&øðAð Að Að Að	ð 	ð 	ð 	ð
Qð 
Qð 
Qð 
Qðð ð ð ð>Zð Zð Zð Zð ZðB !ð	Qð Qð Qð Qð Qð Qðhð ð ð ðBð ð ð ðTð Tð Tð Tðn5.ð 5.ð 5.ð 5.ð 5.ð 5.r¦   