Ë
    âß²jBI  ã            
       óö  — d Z ddlZddlZddlmZ ddlmZ ddlmZ ddlm	Z	m
Z
mZmZ ddlmZ dd	lmZmZmZ dd
lmZ ddlmZmZ  ej0                  e«      ZdZ ej8                  dej:                  «      ZdZdee    de!fd„Z" ed¬«       G d„ d«      «       Z#dededee	eef      dee#   fd„Z$dee    de!fd„Z%dee    de!fd„Z&dedee    fd„Z'e G d „ d!«      «       Z(d"ede d#e d$e!de f
d%„Z) G d&„ d'«      Z*y)(zÈDelivery routing for cron job outputs and agent responses, by target: explicit ("telegram:123456789"),
platform home channel ("telegram"), origin (back to where the job was created), or local (files).é    N)ÚPath)Údatetime)Ú	dataclass)ÚDictÚListÚOptionalÚAny)Úget_hermes_homeé   )ÚPlatformÚGatewayConfigÚPlatformConfig)ÚSessionSource)ÚDeadTargetRegistryÚclassify_dead_errori   zv^[\s*_~`]*\(?\s*(silent|silence|no\s+response|no\s+reply)\s*\.?\)?[\s*_~`]*$|^[\s*_~`]*[\U0001F507\.\u2026]+[\s*_~`]*$)Ú	thread_idÚmessage_thread_idÚdirect_messages_topic_idÚ!telegram_direct_messages_topic_idÚcontentÚreturnc                 ó    — | r| j                  «       nd}t        |«      xr. t        |«      dk  xr t        t        j	                  |«      «      S )zKTrue when ``content`` is *only* a silence-narration token (length-guarded).Ú é@   )ÚstripÚboolÚlenÚ_SILENCE_NARRATIONÚmatch)r   Ústrippeds     ú5/home/ubuntu/.hermes/hermes-agent/gateway/delivery.pyÚ_is_silence_narrationr"   !   s@   € á")ˆw�}‰}Œ¨r€HÜ�‹>Ò^œc (›m¨rÑ1Ò^´dÔ;M×;SÑ;SÐT\Ó;]Ó6^Ð^ó    T)Úfrozenc                   óx   — e Zd ZU dZeed<   ee   ed<   eed<   e	de
fd„«       Zdeded	ed
eeeef      def
d„Zy)ÚDeliveryTransportz:Resolved live transport for one logical delivery platform.ÚadapterÚconfigÚtransport_platformr   c                 ó<   — | j                   t        j                  k(  S ©N)r)   r   ÚRELAY©Úselfs    r!   Úis_relayzDeliveryTransport.is_relay.   s   € à×&Ñ&¬(¯.©.Ñ8Ð8r#   Úlogical_platformÚchat_idr   Úmetadatac              ƒ   ó°   K  — | j                   r| j                  j                  ||||¬«      n| j                  j                  |||¬«      ƒ d{  –—† S 7 Œ­w)zBSend through this transport while preserving the logical platform.©r2   N)r/   r'   Úsend_for_platformÚsend)r.   r0   r1   r   r2   s        r!   r6   zDeliveryTransport.send2   s[   è ø€ ð Ÿšð —l‘l×4Ñ4Ð5EÀwÐPWÐbjÐ4ÔkØ,0¯L©L×,=Ñ,=¸gÀwÐYaÐ,=Ó,b÷dð 	dð dús   ‚AAÁAÁAN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   Ú__annotations__r   r   r   Úpropertyr   r/   Ústrr   r6   © r#   r!   r&   r&   '   sq   … áDØƒLØ�^Ñ$Ó$Ø Ó àð9˜$ò 9ó ð9ðd¨8ð d¸cð dÈCð dØ% d¨3°¨8¡nÑ5ðdØ:=ôdr#   r&   Úplatformr(   Úadaptersc                 óÈ  — |xs i }|j                  | «      |j                  j                  | «      }}|�|�|j                  rt        ||| «      S |j                  t        j
                  «      |j                  j                  t        j
                  «      }}t        |dd«      }|�<|�|j                  r.t        |«      r# || «      rt        ||t        j
                  «      S y)aT  Resolve a logical platform to its live delivery transport. A concrete native adapter always wins;
    Relay is eligible only when its authenticated transport explicitly advertises that it fronts the
    logical platform, so restart-time delivery is independent of per-chat caches without letting Relay
    hijack unrelated platform targets.NÚfronts_platform)ÚgetÚ	platformsÚenabledr&   r   r,   ÚgetattrÚcallable)	r?   r(   r@   Úlive_adaptersÚnativeÚnative_configÚrelayÚrelay_configrB   s	            r!   Úresolve_delivery_transportrM   9   sÍ   € ð ’N €MØ)×-Ñ-¨hÓ7¸×9IÑ9I×9MÑ9MÈhÓ9WˆM€Fð Ð˜}Ð4¸×8MÒ8MÜ  ¨¸ÓAÐAØ'×+Ñ+¬H¯N©NÓ;¸V×=MÑ=M×=QÑ=QÔRZ×R`ÑR`Ó=aˆ<€EÜ˜eÐ%6¸Ó=€OØÐ˜|Ð3°|×7KÒ7KÜ˜Ô)©o¸hÔ.GÜ  ¨´h·n±nÓEÐEØr#   r1   c                 óJ   — 	 t        | «      dkD  S # t        t        f$ r Y yw xY w)u  True when ``chat_id`` is a positive int â€” Telegram's private-chat shape (groups/channels are negative).
    Single source of truth, reused by the handoff seed path in ``gateway/run.py`` so handoff-created DM
    topics key the same way as inbound DM-topic messages.r   F©ÚintÚ	TypeErrorÚ
ValueError)r1   s    r!   Ú#looks_like_telegram_private_chat_idrS   M   s-   € ðÜ�7‹|˜aÑÐøÜ”zÐ"ò Ùðús   ‚ �"¡"Úvaluec                 óH   — 	 t        | «      d uS # t        t        f$ r Y yw xY w)NFrO   )rT   s    r!   Ú_looks_like_intrV   W   s-   € ðÜ�5‹z Ð%Ð%øÜ”zÐ"ò Ùðús   ‚ �! !Úresultc                 óŒ   ‡ — t        ‰ t        «      r‰ j                  ndˆ fd„	} |dd«      durdS t         |d«      xs d«      S )	z`Error string of a failed SendResult object / plain result dict ("" if none), or None on success.Nc                 ó   •— t        ‰| |«      S r+   )rF   )ÚnameÚdefaultrW   s     €r!   ú<lambda>z$_send_result_error.<locals>.<lambda>`   s   ø€ ÔRYÐZ`ÐbfÐhoÓRp€ r#   ÚsuccessTFÚerrorr   r+   )Ú
isinstanceÚdictrC   r=   )rW   rC   s   ` r!   Ú_send_result_errorra   ^   s?   ø€ ä" 6¬4Ô0ˆ&�*Š*Ô7p€CÙ�y $Ó'¨uÑ4ˆ4ÐQ¼#¹cÀ'»lÒ>PÈbÓ:QÐQr#   c                   ó¦   — e Zd ZU dZeed<   dZee   ed<   dZ	ee   ed<   dZ
eed<   dZeed<   dZee   ed	<   edd
edee   dd fd„«       Zdefd„Zy)ÚDeliveryTargetzWOne target: "origin", "local", "telegram" (home channel) or "telegram:123456[:thread]".r?   Nr1   r   FÚ	is_originÚis_explicitÚunknown_platformÚtargetÚoriginr   c                 óú  — |j                  «       }|j                  «       dk(  rD|r* | |j                  |j                  |j                  d¬«      S  | t
        j                  d¬«      S |j                  dd«      }	 t        |d   j                  «       «      }t        |«      d	kD  r( | ||d	   t        |«      dkD  r|d   d¬«      S d
d¬«      S  | |¬«      S # t        $ r  | t
        j                  |¬«      cY S w xY w)zOParse "origin" | "local" | "<platform>" | "<platform>:<chat_id>[:<thread_id>]".rh   T)r?   r1   r   rd   )r?   rd   ú:é   r   )r?   rf   r   N)r?   r1   r   re   )r?   )
r   Úlowerr?   r1   r   r   ÚLOCALÚsplitrR   r   )Úclsrg   rh   Úpartsr?   s        r!   ÚparsezDeliveryTarget.parser   sý   € ð —‘“ˆØ�<‰<‹>˜XÒ%áñ  §¡¸&¿.¹.ÐTZ×TdÑTdÐptÔuð QÙ#&´·±È$Ô#OðQð
 —‘˜S !Ó$ˆð	IÜ  a¡§¡Ó 0Ó1ˆHô �u“: ’>ñ ˜X¨u°Q©xÌsÐSXËzÐ\]Ê~À5ÈÁ8ÐuyÔzð 	?ÐcgÐuyÔzð 	?Ù'*°HÔ'=ð	?øô ò 	IÙ¤§¡ÀÔHÒHð	Iús   Á;C Ã!C:Ã9C:c                 ó.  — | j                   ry| j                  �| j                  S | j                  t        j                  k(  ry| j                  j
                  | j                  | j                  r| j                  ndg}dj                  d„ |D «       «      S )zConvert back to string format.rh   NÚlocalrj   c              3   ó&   K  — | ]	  }|sŒ|–— Œ y ­wr+   r>   )Ú.0Úps     r!   ú	<genexpr>z+DeliveryTarget.to_string.<locals>.<genexpr>�   s   è ø€ Ò.˜aªAœÑ.ùs   ‚Š)	rd   rf   r?   r   rm   rT   r1   r   Újoin)r.   rp   s     r!   Ú	to_stringzDeliveryTarget.to_string„   ss   € à�>Š>ØØ× Ñ Ð,Ø×(Ñ(Ð(Ø�=‰=œHŸN™NÒ*ØØ—‘×$Ñ$ d§l¡lÀdÇlÂl°D·N²NÐX\Ð]ˆØ�x‰xÑ. 5Ô.Ó.Ð.r#   r+   )r7   r8   r9   r:   r   r;   r1   r   r=   r   rd   r   re   rf   Úclassmethodr   rq   ry   r>   r#   r!   rc   rc   d   s…   … áaØÓØ!€GˆX�c‰]Ó!Ø#€Iˆx˜‰}Ó#Ø€IˆtÓØ€K�Óð
 '+Ð�h˜s‘mÓ*àñ?˜3ð ?¨°Ñ(?ð ?ÐK[ò ?ó ð?ð"	/˜3ô 	/r#   rc   r'   rZ   Úrefreshc             ƒ   óÄ   K  — |rdndt        | dd«      }}|€t        d|› d�«      ‚ |||fi |rddini ¤Žƒ d{  –—† }|st        d	|› d
|› d�«      ‚t        |«      S 7 Œ#­w)zSCreate (or force-recreate) a named Telegram private DM topic; return its thread id.r{   ÚcreateÚensure_dm_topicNzTelegram adapter cannot z named private DM topicsÚforce_createTz
Failed to z Telegram private DM topic 'ú')rF   ÚRuntimeErrorr=   )r'   r1   rZ   r{   Úverbr~   r   s          r!   Ú_ensure_named_dm_topicrƒ   �   s‡   è ø€ á)0™I°hÄÈÐQbÐdhÓ@iˆ/€DØÐÜÐ5°d°VÐ;SÐTÓUÐUÙ% g¨tÑcÑRY¸ÈÑ8NÐ_aÑc×c€IÙÜ˜Z¨ vÐ-IÈ$ÈÈqÐQÓRÐRÜˆy‹>Ðð dús   ‚8A ºA»$A c                   óF  — e Zd ZdZ	 	 ddedeeef   dee	   fd„Z
	 	 ddedee   d	ee   d
ee   deeeef      deeef   fd„Zded	ee   d
ee   deeeef      deeef   f
d„Zded	edefd„Zdefd„Zdeded	edefd„Z	 ddededeeeef      dee   deeef   f
d„Zy)ÚDeliveryRouterzGResolves delivery targets and dispatches messages to platform adapters.Nr(   r@   Údead_targetsc                 óx   — || _         |xs i | _        t        «       dz  dz  | _        |xs
 t	        «       | _        y )NÚcronÚoutput)r(   r@   r
   Ú
output_dirr   r†   )r.   r(   r@   r†   s       r!   Ú__init__zDeliveryRouter.__init__ž   s9   € àˆŒØ š BˆŒÜ)Ó+¨fÑ4°xÑ?ˆŒØ(Ò@Ô,>Ó,@ˆÕr#   r   ÚtargetsÚjob_idÚjob_namer2   r   c              ƒ   ó”  K  — i }|D �]œ  }|j                   �$dd|j                   › �dœ||j                  «       <   Œ4|j                  t        j                  k7  xr |j
                  }|r‡| j                  j                  |j                  j                  |j
                  «      rMt        j                  d|j                  j                  |j
                  «       ddddœ||j                  «       <   Œè	 |j                  t        j                  k(  r| j                  ||||«      }	nl| j                  |||«      ƒ d{  –—† }	|j
                  rEt        |	«      €:| j                  j                  |j                  j                  |j
                  «       d	|	d
œ||j                  «       <   �ŒŸ |S 7 Œp# t        $ r‘}
|rt!        t#        |
«      «      nd}|rM| j                  j%                  |j                  j                  |j
                  |› dt#        |
«      dd › �¬«       dt#        |
«      dœ||j                  «       <   Y d}
~
�Œ9d}
~
ww xY w­w)zRDeliver content to all targets; returns per-target results keyed by target string.NFzunknown_platform: )r]   r^   zHSkipping delivery to known-dead target %s:%s (send to it again to clear)Údead_targetz'target previously confirmed unreachable)r]   Úskippedr^   T)r]   rW   z: éx   )Úreason)rf   ry   r?   r   rm   r1   r†   Úis_deadrT   ÚloggerÚinfoÚ_deliver_localÚ_deliver_to_platformra   ÚclearÚ	Exceptionr   r=   Ú	mark_dead)r.   r   rŒ   r�   rŽ   r2   Úresultsrg   ÚtrackedrW   ÚeÚ	dead_kinds               r!   ÚdeliverzDeliveryRouter.deliver¥   s  è ø€ ð ˆØó 	RˆFØ×&Ñ&Ð2à$Ð1CÀF×D[ÑD[ÐC\Ð/]ñ/_�˜×(Ñ(Ó*Ñ+àð —o‘o¬¯©Ñ7ÒJ¸F¿N¹NˆGÙ˜4×,Ñ,×4Ñ4°V·_±_×5JÑ5JÈFÏNÉNÔ[Ü—‘ÐfØ"ŸO™O×1Ñ1°6·>±>ôCà:?ÈMØ8añ/c�˜×(Ñ(Ó*Ñ+àðRØ—?‘?¤h§n¡nÒ4Ø!×0Ñ0°¸&À(ÈHÓU‘Fà#'×#<Ñ#<¸VÀWÈhÓ#W×W�FØ—~’~Ô*<¸VÓ*DÐ*LØ×)Ñ)×/Ñ/°·±×0EÑ0EÀvÇ~Á~ÔVØ:>È&Ñ.Q�˜×(Ñ(Ó*Ó+ð-	Rð< ˆð Xùô ò Rá;BÔ/´°A³Ô7È�	ÙØ×%Ñ%×/Ñ/°·±×0EÑ0EÀvÇ~Á~Ø:C¸ÀBÄsÈ1ÃvÈdÈsÀ|ÀnÐ7Uð 0ô Wà:?Ì#ÈaË&Ñ.Q�˜×(Ñ(Ó*×+ûðRüsE   ‚C-IÃ0AF+Ä8F)Ä9A+F+Æ$IÆ)F+Æ+	IÆ4BI È:IÉ IÉIc           	      ó  — t        j                  «       j                  d«      }| j                  |xs dz  |› d�z  }|j                  j                  dd¬«       |rd|› �nddd	t        j                  «       j                  d
«      › �g}||rd|› �gng z  }||xs i j                  «       D ��	cg c]  \  }}	d|› d|	› �‘Œ c}	}ddd|gz   z  }|j                  dj                  |«      d¬«       t        |«      |dœS c c}	}w )zSave content to local files.ú%Y%m%d_%H%M%SÚmiscz.mdT©ÚparentsÚexist_okz# z# Delivery Outputr   z**Timestamp:** z%Y-%m-%d %H:%M:%Sz**Job ID:** z**z:** z---ú
úutf-8©Úencoding)ÚpathÚ	timestamp)
r   ÚnowÚstrftimerŠ   ÚparentÚmkdirÚitemsÚ
write_textrx   r=   )
r.   r   r�   rŽ   r2   r¬   Úoutput_pathÚlinesÚkeyrT   s
             r!   r—   zDeliveryRouter._deliver_localÉ   s  € ô —L‘L“N×+Ñ+¨OÓ<ˆ	Ø—o‘o¨Ò)9°6Ñ:À	¸{È#Ð=NÑNˆØ×Ñ× Ñ ¨¸Ð Ô=Ù$,�2�h�Z‘Ð2EÀrØ"¤8§<¡<£>×#:Ñ#:Ð;NÓ#OÐ"PÐQðSˆà©f�L  Ð)Ñ*¸"Ñ<ˆØ¸8º>Àr×:PÑ:PÓ:R×S©J¨C°�B�s�e˜4 ˜wÒ'ÓSÐWYÐ[`ÐbdÐfmÐVnÑnÑnˆØ×Ñ˜tŸy™y¨Ó/¸'ÐÔBÜ˜KÓ(°yÑAÐAùó Ts   Â/C>c                 óÞ   — t        j                  «       j                  d«      }t        «       dz  dz  |› d|› d�z  }|j                  j                  dd¬«       |j                  |d¬	«       |S )
z7Save full cron output to disk and return the file path.r¢   rˆ   r‰   Ú_z.txtTr¤   r¨   r©   )r   r­   r®   r
   r¯   r°   r²   )r.   r   r�   r¬   r«   s        r!   Ú_save_full_outputz DeliveryRouter._save_full_outputÖ   sh   € ä—L‘L“N×+Ñ+¨OÓ<ˆ	ÜÓ  6Ñ)¨HÑ4¸&¸ÀÀ9À+ÈTÐ7RÑRˆØ�‰×Ñ $°ÐÔ6Ø�‰˜¨'ˆÔ2Øˆr#   c                 óB   — t        t        | j                  dd«      «      S )zMfilter silence narration based on gateway config without checking process envÚfilter_silence_narrationT)r   rF   r(   r-   s    r!   Ú!_filter_silence_narration_enabledz0DeliveryRouter._filter_silence_narration_enabledÞ   s   € ä”G˜DŸK™KÐ)CÀTÓJÓKÐKr#   r'   c           	      óà  — t        |«      t        k  r|S d}	 | j                  ||«      }t        |dd«      r$|r t        j                  dt        |«      |«       |S |xs | j                  ||«      }d|› d�}t        j                  dt        |«      |«       |dt        d	t        t        |«      z
  «       |z   S # t        $ r+}t        j                  dt        |«      ||«       Y d}~Œ¾d}~ww xY w)
u   Audit-save oversized cron output; truncate it for non-chunking adapters. Above MAX_PLATFORM_OUTPUT
        the full output is always written to disk as an audit trail, best-effort â€” a failed save (full disk,
        permissions) never blocks delivery. Non-chunking adapters then get the content truncated with a
        footer pointing to the saved file; ``splits_long_messages`` adapters receive the full payload.Nua   Audit save failed for cron output (%d chars, job=%s): %s â€” delivery proceeds without audit copyÚsplits_long_messagesFuQ   Cron output preserved for chunking adapter (%d chars) â€” full output saved to %sz'

... [truncated, full output saved to ú]u4   Cron output truncated (%d chars) â€” full output: %sr   )	r   ÚMAX_PLATFORM_OUTPUTr¸   ÚOSErrorr•   ÚwarningrF   r–   Úmax)r.   r'   r   r�   Ú
saved_pathÚexcÚfooters          r!   Ú_cap_oversized_outputz$DeliveryRouter._cap_oversized_outputâ   s  € ô
 ˆw‹<Ô.Ò.ØˆNØ%)ˆ
ð	^Ø×/Ñ/°¸Ó@ˆJô �7Ð2°EÔ:ÙÜ—‘ð 6Ü7:¸7³|ÀZôQàˆNð  ÒJ 4×#9Ñ#9¸'À6Ó#Jˆ
Ø<¸Z¸LÈÐJˆÜ�‰ÐJÌCÐPWËLÐZdÔeØÐAœ˜AÔ2´S¸³[Ñ@ÓAÐBÀVÑKÐKøô ò 	^Ü�N‰Nð BÜCFÀwÃ<ÐQWÐY\÷^ñ ^ûð	^ús   ˜B9 Â9	C-Ã!C(Ã(C-rg   Ú	transportc              ƒ   óf  ‡K  — |€+t        |j                  | j                  | j                  «      }|€"t	        d|j                  j
                  › �«      ‚|j                  s#t	        d|j                  j
                  › d�«      ‚|j                  }| j                  |||xs i j                  dd«      «      }d|xs i v }| j                  «       rL|sJt        |«      r?t        j                  d|j                  j
                  |j                  |dd «       d	d
ddœS t        |xs i «      Š|j                  r%| j                  j!                  |j                  «      nd}|�[|j                  |j                  k(  rB‰j#                  d|j$                  fd|j&                  ffD ��	ci c]  \  }}	|	sŒ	||	“Œ c}	}«       d}
|j(                  }|r§t+        ˆfd„t,        D «       «      s�|‰d<   |j                  t.        j0                  k(  rmt3        |j                  «      rXt5        |«      s,|}
t7        ||j                  |d¬«      ƒ d{  –—† ‰d<   d	‰d<   n!‰j                  d«      €t9        d«      ‚d	‰d<   dD ]…  }|j;                  |j                  |j                  |‰xs d¬«      ƒ d{  –—† }t=        |«      }|s|�|
rd|j?                  «       vr n+t7        ||j                  |
d	¬«      ƒ d{  –—† ‰d<   d	‰d<   Œ‡ �&t9        |xs |j                  j
                  › d�«      ‚S c c}	}w 7 Œè7 Œ†7 ŒB­w)a·  Deliver content to a messaging platform.

        ``transport`` carries an already-authorized transport past resolution:
        the cron live lane resolved and authorized it per target (including the
        SharedRouteAdapters satellite grant), and re-resolving from the plain
        adapters dict cannot re-derive that grant under satellite config
        (#115656). Omitted (None) preserves resolution for every other caller.
        NzNo adapter configured for zNo chat ID for z	 deliveryr�   Úunknownz6Dropped silence-narration outbound to %s (chat=%s): %ré(   TÚsilence_narrationF)r]   ÚfilteredÚ	deliveredÚuser_idÚscope_idc              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­wr+   r>   )ru   rµ   Úsend_metadatas     €r!   rw   z6DeliveryRouter._deliver_to_platform.<locals>.<genexpr>&  s   øè ø€ Ò V¸# ¨Ô!5Ñ Vùs   ƒr   )r{   Ú"telegram_dm_topic_created_for_sendÚtelegram_reply_to_message_idzyTelegram private DM topic delivery requires telegram_reply_to_message_id; send to the bare chat or provide a reply anchorÚ telegram_dm_topic_reply_fallback)FTr4   zthread not foundz delivery failed) rM   r?   r(   r@   rR   rT   r1   r'   rÆ   rC   r»   r"   r•   rÁ   r`   r/   Úget_home_channelÚupdaterÎ   rÏ   r   ÚanyÚ_THREAD_ROUTING_KEYSr   ÚTELEGRAMrS   rV   rƒ   r�   r6   ra   rl   )r.   rg   r   r2   rÇ   r'   Úis_cron_artifactÚhomeÚkÚvÚnamed_topicr   ÚretryrW   r^   rÑ   s                  @r!   r˜   z#DeliveryRouter._deliver_to_platformû   s(  øè ø€ ð ÐÜ2°6·?±?ÀDÇKÁKÐQU×Q^ÑQ^Ó_ˆIØÐÜÐ9¸&¿/¹/×:OÑ:OÐ9PÐQÓRÐRØ�~Š~Ü˜¨v¯©×/DÑ/DÐ.EÀYÐOÓPÐPØ×#Ñ#ˆØ×,Ñ,¨W°gÀÂÈB×?SÑ?SÐT\Ð^gÓ?hÓiˆð $¨ª°BÐ7ÐØ×1Ñ1Ô3Ñ<LÔQfÐgnÔQoÜ�N‰NÐSØ!Ÿ?™?×0Ñ0°&·.±.À'È#È2À,ôPà#Ð1DÐSXÑYÐYä˜Xš^¨Ó,ˆØ@I×@RÒ@Rˆt�{‰{×+Ñ+¨F¯O©OÔ<ÐX\ˆØÐ §¡°·±Ò >Ø× Ñ °YÀÇÁÐ4MÐPZÐ\`×\iÑ\iÐOjÐ3k×!q©4¨1¨aÒop ! Q¡$Ó!qÔrð &*ˆØ×$Ñ$ˆ	ÙœSÓ VÔAUÔ VÔVØ)2ˆM˜+Ñ&Ø�‰¤(×"3Ñ"3Ò3Ô8[Ð\b×\jÑ\jÔ8kÜ& yÔ1à"+�KÜ7MÈgÐW]×WeÑWeÐgpÐzô  8A÷  2A�M +Ñ.ØJN�MÐ"FÒGØ"×&Ñ&Ð'EÓFÐNô 'ðJóð ð
 IM�MÐ"DÑEà"ò 	GˆEØ$Ÿ>™>¨&¯/©/¸6¿>¹>È7Ð]jÒ]rÐnr˜>Ós×sˆFÜ& vÓ.ˆEÙ˜˜©[Ð<NÐV[×VaÑVaÓVcÑ<cÙä/EÀgÈvÏ~É~Ð_jÐtxÔ/y×)yˆM˜+Ñ&ØBFˆMÐ>Ò?ð	Gð ÐÜ˜uÒR¨6¯?©?×+@Ñ+@Ð*AÐAQÐ(RÓSÐSØˆùóC "rð 2Aøð tøð
 *zúsK   ƒFL1Æ"
L%
Æ-L%
Æ2BL1ÉL+ÉA#L1Ê&L-Ê'AL1Ë,L/Ë-?L1Ì-L1Ì/L1)NN)NNNr+   )r7   r8   r9   r:   r   r   r   r	   r   r   r‹   r=   r   rc   r    r—   r   r¸   r   r»   rÆ   r&   r˜   r>   r#   r!   r…   r…   ›   s’  „ ÙQàNRØ>BñA˜}ð A¸¸XÀs¸]Ñ8Kð AØ'Ð(:Ñ;óAð bfØ[_ñ" Sð "°4¸Ñ3Gð "ÐQYÐZ]ÑQ^ð "Ø (¨¡ð"Ø@HÈÈcÐSVÈhÉÑ@Xð"ØdhÐilÐnqÐiqÑdró"ðHB cð B°8¸C±=ð BÈHÐUXÉMð BØ!)¨$¨s°C¨x©.Ñ!9ðBØ>BÀ3ÈÀ8¹nóBð¨ð °cð ¸dó ðL°4ó LðL¨Sð L¸3ð LÈð LÐPSó Lð6 MQñG°ð GÈ#ð GØ-5°d¸3À¸8±nÑ-EðGà.6Ð7HÑ.IðGð )-¨S°#¨X©ôGr#   r…   )+r:   ÚloggingÚreÚpathlibr   r   Údataclassesr   Útypingr   r   r   r	   Úhermes_cli.configr
   r(   r   r   r   Úsessionr   r†   r   r   Ú	getLoggerr7   r•   r¿   ÚcompileÚ
IGNORECASEr   rØ   r=   r   r"   r&   rM   rS   rV   ra   rc   rƒ   r…   r>   r#   r!   ú<module>rê      s}  ðñeó Û 	Ý Ý Ý !ß ,Ó ,å -ç ;Ñ ;Ý "ß Aà	ˆ×	Ñ	˜8Ó	$€ð
 Ð ð  �R—Z‘Zð2à‡M�MóÐ ð
 {Ð ð_ 8¨C¡=ð _°Tó _ñ �$Ô÷dð dó ðdð"¨ð ¸=ð Ø)1°$°xÀ°}Ñ2EÑ)FðØKSÐTeÑKfóð(°¸#±ð À4ó ð˜8 C™=ð ¨Tó ðR˜sð R x°¡}ó Rð ÷(/ð (/ó ð(/ðV¨#ð ¸ð À3ð ÐTXð Ð]`ó ÷gò gr#   