+
    kHàj­ð  ã                   ó  € R t ^ RIt^ RIt^ RIHtHt ^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHtHt ^ R	IHt ^ R
IHt ^ RIH t H!t!H"t"H#t#H$t$H%t% ^ RI&H't' ^ RI(H)t) ^ RI*H+t+H,t,H-t-H.t. ^ RI/H0t0 ^ RI1H2t2H3t3 ^ RI4H5t5H6t6 ^ RI7H8t8 ^ RI9H:t;H<t<H=t=H>t> ^ RI?H@t@HAtA ]P„                  ! ]C4      tDRRRRRRRRRRRR/tER˜tFRR RR RR  R!R" /tGR#tH^tI0 R™mtJ0 RšmtKR$R%R&R%R'R%R(R%R)R*R+R,R-R.R/R.R0R1/	tL]
Pš                  ! R2]
Pœ                  4      R33]
Pš                  ! R4]
Pœ                  4      R33]
Pš                  ! R5]
Pœ                  4      R33]
Pš                  ! R64      R73]
Pš                  ! R84      R93]
Pš                  ! R:4      R;3]
Pš                  ! R<4      R=3]
Pš                  ! R>4      R?3]
Pš                  ! R@4      RA33	tO]
Pš                  ! RB4      tP]
Pš                  ! RC4      tQRDtRR›tSRER9P©                  RF ]G 4       4       RG]S^,            RH2tU]
Pš                  ! RI]
Pœ                  4      tVRJtWRKtXRLtYRMtZ]WRN]Z,           ]XRO/t[RP]Z,           t\RQt]]
Pš                  ! RR]] RS]] RT2]
Pœ                  4      t^RU RV lt_RœRX RY llt`R�RZ R[ lltaR\ R] ltbR^ R_ ltcRžR` Ra lltd ! Rb Rc]PÊ                  4      tf ! Rd Re]PÎ                  4      thRf Rg ltiRh Ri ltjRj Rk ltkRl Rm ltlRn Ro ltmRp Rq ltnRr Rs ltoRt Ru ltpRv Rw ltqRx Ry ltrRz R{ ltsR| R} lttR~ R ltuR€ R� ltvR‚ Rƒ ltwR„ R… ltxR† R‡ ltyRœRˆ R‰ lltzRŠ R‹ lt{ ! RŒ R�]+4      t|RŽRR�RR�RW/R‘ lt}R’ R“ lt~R”t]
Pš                  ! R•4      t€R– R— lt�R# )ŸzÓEmail platform adapter for the Hermes gateway: users talk to Hermes by sending email; IMAP (polled)
receives, SMTP sends. Configured via EMAIL_* env vars or ``platforms.email`` in config.yaml (see website docs).N)ÚcontextmanagerÚsuppress)Údecode_header©ÚMIMEMultipart)ÚMIMEText)ÚMIMEBase)ÚBytesHeaderParser)Ú
formatdateÚ	parseaddr)Úencoders)ÚPath)ÚAnyÚCallableÚDictÚListÚOptionalÚTuple)Úsafe_schedule_threadsafe)Út)ÚBasePlatformAdapterÚ
SendResultÚcache_document_from_bytesÚcache_image_from_bytes)Úcancel_task)ÚMessageEventÚMessageType)ÚPlatformÚPlatformConfig)Úis_truthy_value)Úget_scoped_secretÚcoerce_portÚdecode_json_list_literalÚ
send_error)ÚStandaloneSendPolicyÚregex_stripped_parserÚtlsÚsslÚimplicitÚstarttlsÚplainÚnonezAuto-Submittedc                 ó(   € V P                  4       R 8g  # )Úno©Úlower©Úvs   &ÚD/home/ubuntu/.hermes/hermes-agent/plugins/platforms/email/adapter.pyÚ<lambda>r3   ,   s   € °!·'±'³)¸tÒ2Có    Ú
Precedencec                 ó(   € V P                  4       R9   # )Úbulk>   r7   ÚjunkÚlistr.   r0   s   &r2   r3   r3   -   s   € ¨a¯g©g«iÐ;SÒ.Sr4   zX-Auto-Response-Suppressc                 ó   € \        V 4      # ©N©Úboolr0   s   &r2   r3   r3   .   s   € ¼DÀ¼Gr4   zList-Unsubscribec                 ó   € \        V 4      # r;   r<   r0   s   &r2   r3   r3   .   s   € ÔcgÐhiÔcjr4   éPÃ  zunknown-8bitúutf-8Úunknownz	x-unknownÚdefaultzansi_x3.110-1983úlatin-1zcp-850Úcp850Úgb2312Úgb18030Úgbkzks_c_5601-1987Úcp949z	<br\s*/?>Ú
z<p[^>]*>z</p>z<[^>]+>Ú z&nbsp;Ú z&amp;Ú&z&lt;Ú<z&gt;Ú>z\n{3,}ú

z([^"<>]*)<([^<>\s]+)>\s*z
\([^()]*\)i   z6(BODY.PEEK[HEADER.FIELDS (FROM AUTHENTICATION-RESULTS c              #   ó@   "  € T F  qP                  4       x € K  	  R # 5ir;   )Úupper)Ú.0Úhs   & r2   Ú	<genexpr>rT   F   s   é € ÐElÑYkÐTUÇgÁgÇiÀiÓYkùs   ‚z)]<0.z>)z"\s*(dmarc|dkim|spf)\s*=\s*([a-z]+)z no Authentication-Results headerz2no Authentication-Results from trusted authserv-idzGauthserv-id is not configured; refusing to trust Authentication-Resultszmset platforms.email.require_authenticated_sender: false (or EMAIL_TRUST_FROM_HEADER=true) to accept the risk.z< If your mail server does not stamp Authentication-Results, zS Check that platforms.email.authserv_id (EMAIL_AUTHSERV_ID) names your mail server.ze Set EMAIL_AUTHSERV_ID (or platforms.email.authserv_id) to the receiving MTA's exact authserv-id, or z"(?:[^"\\]|\\.)*"zK(header\.from|header\.d|smtp\.mailfrom|smtp\.from|envelope-from)\s*=\s*((?:z|[^\s";])+)|(?:z	|[^\s"])+c                ó<   € V ^8„  d   QhR\         R\        R\        /# ©é   ÚnamerB   Úreturn)ÚstrÚint)Úformats   "r2   Ú__annotate__r]   ^   s&   € ÷ Oñ O”sð O¤Sð O¬Sñ Or4   c                óp   € \        \        \        V R4      4      P                  4       ;'       g    TV4      # )zScope-aware integer read.rJ   )r!   rZ   Ú_get_secretÚstrip)rX   rB   s   &&r2   Ú_esecret_intra   ^   s,   € ä”sœ; t¨RÓ0Ó1×7Ñ7Ó9×DÐD¸WÀgÓNÐNr4   Fc                ó<   € V ^8„  d   QhR\         R\        R\        /# rV   ©rZ   r=   )r\   s   "r2   r]   r]   c   s&   € ÷ mñ mœð m¤dð m´tñ mr4   c                ót   € \        \        V R4      4      P                  4       ;p'       d   \        W!R7      # T# )zScope-aware boolean read.rJ   ©rB   )rZ   r_   r`   r   )rX   rB   Úraws   && r2   Ú_esecret_boolrg   c   s3   € ä<?ÄÈDÐRTÓ@UÓ<V×<\Ñ<\Ó<^Ð5^°SÖ5^Œ?˜3Ô0ÐlÐelÐlr4   c                ó<   € V ^8„  d   QhR\         R\        R\        /# )rW   ÚvaluerB   rY   )r   rZ   )r\   s   "r2   r]   r]   h   s!   € ÷ /ñ /œsð /¬Sð /¼Sñ /r4   c                ó   € \        T ;'       g    R4      P                  4       P                  4       P                  RR4      P                  RR4      pV'       d"   V\        9  d   \
        P                  RW4       \        P                  W!4      # )z�Map to ``tls`` | ``starttls`` | ``plain``; unknown values warn and fall back to *default* (a typo never downgrades to plaintext).rJ   Ú-Ú_z(Unknown email security mode %r; using %r)rZ   r`   r/   ÚreplaceÚ_SECURITY_ALIASESÚloggerÚwarningÚget)ri   rB   rf   s   && r2   Ú_normalize_securityrr   h   si   € ä
ˆe�kˆk�rÓ
×
 Ñ
 Ó
"×
(Ñ
(Ó
*×
2Ñ
2°3¸Ó
;×
CÑ
CÀCÈÓ
L€Cß
ˆsÔ+Ô+Ü�‰ÐAÀ5ÔRÜ× Ñ  Ó.Ð.r4   c                óP   € V ^8„  d   QhR\         R\        R\        P                  /# )rW   ÚverifyÚhostrY   )r=   rZ   r'   Ú
SSLContext)r\   s   "r2   r]   r]   p   s%   € ÷ ,ñ ,œð ,¤Sð ,¬S¯^©^ñ ,r4   c                ó    € V '       d   \         P                  ! 4       # VR9  d   \        P                  RV4       \         P                  ! 4       # )zGVerified context by default; unverified only when explicitly opted out.z2TLS verification disabled for non-loopback host %s)z	127.0.0.1z::1Ú	localhost)r'   Úcreate_default_contextro   rp   Ú_create_unverified_context)rt   ru   s   &&r2   Ú_tls_contextr{   p   s;   € çÜ×)Ò)Ó+Ð+ØÐ4Ô4Ü�‰ÐKÈTÔRÜ×)Ò)Ó+Ð+r4   c                ó<   € V ^8„  d   QhR\         P                  RR/# ©rW   ÚimaprY   N©ÚimaplibÚIMAP4)r\   s   "r2   r]   r]   y   s   € ÷ ñ ”g—m‘mð ¨ñ r4   c                óÖ   €  V P                  4        R#   \         dJ    \        \        4      ;_uu_ 4        T P                  4        RRR4        R#   + '       g   i      R# ; ii ; i)a»  Teardown that guarantees the socket closes: ``logout()`` only guards ``OSError``, so ``IMAP4.abort`` on a
broken connection skipped ``shutdown()`` and leaked one fd per failed poll (fatal on macOS's 256 soft limit).

``IMAP4.logout()`` only guards against ``OSError`` internally: a broken connection makes
``_simple_command('LOGOUT')`` raise ``IMAP4.abort`` (which is *not* an ``OSError``), so ``logout()``
propagates before its own ``shutdown()`` call and the TCP socket stays open. On macOS, where the default
soft fd limit is 256 and pollers may run through a local proxy, these abandoned sockets accumulate one
per failed poll until the gateway hits ``[Errno 24] Too many open files`` (#79889).
N)ÚlogoutÚ	Exceptionr   Úshutdown)r~   s   &r2   Ú_close_imapr†   y   sB   € ðØ�‰ŽøÜô Ü”i× Õ Ø�M‰MŒO÷ !× × Ô úðús&   ‚ ”"A(¶AÁA(ÁA$ÁA(Á$A(c          
      óh   € V ^8„  d   QhR\         R\        R\        R\        R\        P                  /# )rW   ru   ÚportÚtimeoutÚsource_addressrY   )rZ   r[   Úfloatr   Úsocket)r\   s   "r2   r]   r]   Š   s>   € ÷ hñ h¤#ð h¬Sð h¼5ð hÔRUð hÔag×anÑanñ hr4   c                ó²  € Rp\         P                  ! W\         P                  \         P                  4       F\  w  rVrxp	\         P                   ! WVV4      p
V
P	                  V4        V'       d   V
P                  V4       V
P                  V	4       V
u # 	  Ve   Vh\        RV  RV 24      h  \         d   pTpT
P                  4         Rp?Kš  Rp?ii ; i)u~   ``socket.create_connection`` constrained to ``AF_INET`` (no process-global socket mutation â€” sends run in executor threads).NzNo IPv4 address found for Ú:)	rŒ   ÚgetaddrinfoÚAF_INETÚSOCK_STREAMÚ
settimeoutÚbindÚconnectÚOSErrorÚclose)ru   rˆ   r‰   rŠ   Ú
last_errorÚfamilyÚsocktypeÚprotoÚ
_canonnameÚsockaddrÚsockÚexcs   &&&&        r2   Ú_create_ipv4_connectionrŸ   Š   sÃ   € à!%€JÜ9?×9KÒ9KÈDÔX^×XfÑXfÔhn×hzÑhzÖ9{Ñ5ˆ˜%¨XÜ�}Š}˜V¨uÓ5ˆØ�‰˜Ô ð	ßØ—	‘	˜.Ô)Ø�L‰L˜Ô"ØŠKñ :|ð #Ò.ˆ*Ðg´GÐ>XÐY]ÐX^Ð^_Ð`dÐ_eÐ<fÓ4gÐgøô ô 	ØˆJØ�J‰J�LŠLûð	ús   Á'+B.Â.CÂ9CÃCc                   ó&   a € ] tR t^›t o R tRtV tR# )Ú	_IPv4SMTPc                ó0   € \        WW0P                  R 7      # )©rŠ   )rŸ   rŠ   ©Úselfru   rˆ   r‰   s   &&&&r2   Ú_get_socketÚ_IPv4SMTP._get_socketœ   s   € Ü& t°7×K^ÑK^Ô_Ð_r4   © N©Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r¦   Ú__static_attributes__Ú__classdictcell__©Ú__classdict__s   @r2   r¡   r¡   ›   s   ø‡ € ÷`ð `r4   r¡   c                   ó&   a € ] tR t^ t o R tRtV tR# )Ú_IPv4SMTP_SSLc           	     ó|   € V P                   P                  \        WW0P                  R 7      \	        V RV4      R7      # )r£   Ú_host)Úserver_hostname)ÚcontextÚwrap_socketrŸ   rŠ   Úgetattrr¤   s   &&&&r2   r¦   Ú_IPv4SMTP_SSL._get_socket¡   sQ   € Ø�|‰|×'Ñ'Ô(?ÀÈG×dwÑdwÔ(xô  KRð  SWð  Y`ð  bfó  KgÐ'ó  hð  	hr4   r¨   Nr©   r°   s   @r2   r³   r³       s   ø‡ € ÷hð hr4   r³   c                ó    € V ^8„  d   QhR\         R\        R\         R\        P                  R\        R\        R\
        R\        P                  /# )	rW   ru   rˆ   ÚsecurityÚctxÚsmtp_clsÚsmtp_ssl_clsÚkwargsrY   )rZ   r[   r'   rv   Útyper   ÚsmtplibÚSMTP)r\   s   "r2   r]   r]   ¥   s^   € ÷ ñ ”Sð ¤ð ¬sð ¼¿¹ð ÔSWð Ôgkð Ôwzð ô  @G÷  @Lñ  @Lñ r4   c                ó´   € VR8X  d   V! W3RV/VB # V! W3/ VB pVR8X  d    VP                  VR7       V# V#   \         d    TP                  4        h i ; i)z]Open one SMTP connection with TLS established per *security*; *kwargs* go to the constructor.r&   r·   r)   )r·   )r)   r„   r–   )ru   rˆ   r¼   r½   r¾   r¿   rÀ   Úsmtps   &&&&&&, r2   Ú
_open_smtprÆ   ¥   sq   € à�5ÔÙ˜DÑ>°Ð>°vÑ>Ð>Ù�DÑ) &Ñ)€DØ�:Ôð	Ø�M‰M #ˆMÔ&ð €Kˆ4€Køô ô 	Ø�J‰JŒLØð	ús	   ¤: ºAc                ó<   € V ^8„  d   QhR\         P                  RR/# r}   r   )r\   s   "r2   r]   r]   ³   s"   € ÷ Dñ DœŸ™ð D¨$ñ Dr4   c                ó8  € RV P                   9  d   \        P                  R4       R#   ^ RIHp V! 4       P
                  pV P                  RRV R24       R#   \         d    Rp L'i ; i  \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)	uS  Send RFC 2971 IMAP ID: 163/NetEase require it after LOGIN (else every UID command
returns ``BYE Unsafe Login``); other servers may reject it, so failures are swallowed.

Sent only when the server advertises ``ID`` (RFC 2971 requires advertising it): a server
without the extension can answer an untagged ``* BYE Unknown command.`` and close the
connection, which imaplib cannot surface here â€” the failure appears one command later
as a misleading SELECT error and the adapter retries forever (Purelymail, #39856).
``imap.capabilities`` is populated by imaplib at connect, so the check is free.ÚIDzA[Email] Server does not advertise IMAP ID capability; skipping IDN)Úget_version_infoÚ0z"("name" "hermes-agent" "version" "zE" "vendor" "NousResearch" "support-email" "noreply@nousresearch.com")z([Email] IMAP ID command not accepted: %s)Úcapabilitiesro   ÚdebugÚhermes_cli.version_inforÊ   Úbase_versionr„   Úxatom)r~   rÊ   ÚversionÚes   &   r2   Ú_send_imap_idrÓ   ³   s¢   € ð �4×$Ñ$Ô$Ü�‰ØOô	
ñ 	ð	Dð	Ý@Ù&Ó(×5Ñ5ˆGð 	�
‰
�4Ð=¸g¸Yð G_ð _ö 	`øô ô 	ØŠGð	ûô ô DÜ�‰Ð?À×CÒCûðDús5   «A ÁA- ÁA*Á'A- Á)A*Á*A- Á-BÁ8BÂBc                ó<   € V ^8„  d   QhR\         R\        R\        /# )rW   ÚaddressÚheadersrY   )rZ   Údictr=   )r\   s   "r2   r]   r]   Í   s&   € ÷ mñ m¤#ð m´ð m¼ñ mr4   c                ó|  aaa€ V P                  4       o\        ;QJ d#    V3R l\         4       F  '       g   K   RM	  RM! V3R l\         4       4      ;'       ga    \        ;QJ d2    VV3R l\        P	                  4        4       F  '       g   K   R# 	  R# ! VV3R l\        P	                  4        4       4      # )z7True if this email is from an automated/noreply source.c              3   ó,   <"  € T F	  qS9   x € K  	  R # 5ir;   r¨   )rR   ÚpatternÚaddrs   & €r2   rT   Ú'_is_automated_sender.<locals>.<genexpr>Ð   s   øé € Ð@Ñ.? 7˜$ŽÓ.?ùó   ƒTFc              3   óp   <"  € T F+  w  rSP                  VR 4      ;o;'       d	    V! S4      x € K-  	  R# 5i©rJ   N)rq   )rR   ÚheaderÚcheckrÖ   ri   s   &  €€r2   rT   rÜ   Ð   s8   øé € ð HmÙQkÁÀ�'—+‘+˜f bÓ)Ð	)ˆ×;Ð;©u°U«|Ô;ÓQkùs   ƒ!6¥6)r/   ÚanyÚ_NOREPLY_PATTERNSÚ_AUTOMATED_HEADERSÚitems)rÕ   rÖ   rÛ   ri   s   &f@@r2   Ú_is_automated_senderræ   Í   s“   ú€ à�=‰=‹?€Dß‹3Ô@Õ.?Ó@�3�3Š3Ô@Õ.?Ó@Ó@÷ mð mÇCÃCõ HmÜQc×QiÑQiÔQkóHmÇCÄCð mÂCð mÀCõ HmÜQc×QiÑQiÔQkóHmó Emð mr4   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )rW   ÚdatarY   )r   r   Úbytes)r\   s   "r2   r]   r]   Ô   s"   € ÷ Oñ Oœð O¤¬¥ñ Or4   c                ó¦   €  V ^ ,          ^,          p\        T\        \        34      '       d   \        T4      # R#   \         \        3 d     R# i ; i)zaThe bytes of a one-message IMAP FETCH response, or ``None`` for an unexpected shape (see #80032).N)Ú
IndexErrorÚ	TypeErrorÚ
isinstanceré   Ú	bytearray)rè   Úpayloads   & r2   Ú_imap_payloadrð   Ô   sO   € ðØ�q•'˜!•*ˆô (¨´%¼Ð1C×DÒDŒ5�‹>ÐNÈ$ÐNøô œ	Ð"ô Úðús   ‚; »AÁAc                ó$   € V ^8„  d   QhR\         /# ©rW   rY   r<   )r\   s   "r2   r]   r]   Ý   s   € ÷ Dñ D¤$ñ Dr4   c                 ój   € \         ;QJ d    R R 4       F  '       d   K   R# 	  R# ! R R 4       4      # )a  True when all email settings are present and non-blank (blank keys left by an abandoned setup must not enable the platform).

Treats blank/whitespace-only values as missing so an abandoned setup that left empty ``EMAIL_*`` keys in
``.env`` does not enable the platform (#40715).
c              3   óV   "  € T F  p\        VR 4      P                  4       x € K!  	  R# 5irß   )r_   r`   ©rR   rX   s   & r2   rT   Ú+check_email_requirements.<locals>.<genexpr>ã   s.   é € ð  Dñ  :C°Œ{˜4 Ó$×*Ñ*×,Ð,ó  :Cùs   ‚')FT©ÚEMAIL_ADDRESSÚEMAIL_PASSWORDÚEMAIL_IMAP_HOSTÚEMAIL_SMTP_HOST)Úallr¨   r4   r2   Úcheck_email_requirementsrý   Ý   sM   € ÷ ‹3ñ  Dñ  :Có  D�3Œ3ð  DŠ3ð  Dˆ3ñ  Dñ  :Có  Dó  Dð  Dr4   c                óR   € V ^8„  d   QhR\         R\        \        ,          R\        /# )rW   rï   ÚcharsetrY   )ré   r   rZ   )r\   s   "r2   r]   r]   æ   s%   € ÷ 7ñ 7œ%ð 7¬(´3­-ð 7¼Cñ 7r4   c                ó>  € T;'       g    RP                  4       P                  R4      P                  4       ;'       g    Rp\        P                  W"4      R3 F  p V P	                  VRR7      u # 	  V P	                  RRR7      #   \
        \        3 d     KB  i ; i)u2  Decode without ever raising: ``errors="replace"`` does not guard a missing codec (``LookupError``), so fall back alias â†’ UTF-8 â†’ latin-1.

Unknown or malformed charset labels (``unknown-8bit``, misspelled names, attacker-controlled garbage)
previously raised ``LookupError`` from ``bytes.decode`` â€” ``errors="replace"`` only guards decode
errors, not a missing codec â€” which aborted the whole IMAP fetch and dropped every message in the batch
(#35901, #55381, #55383). Fall back through a small alias table, then UTF-8, then latin-1 (which never
fails).
r@   z"'rm   )ÚerrorsrC   )r`   r/   Ú_CHARSET_ALIASESrq   ÚdecodeÚLookupErrorÚ
ValueError)rï   rÿ   ÚlabelÚ	candidates   &&  r2   Ú_safe_decoder  æ   s—   € ð ×Ð˜×&Ñ&Ó(×.Ñ.¨uÓ5×;Ñ;Ó=×HÐHÀ€EÜ&×*Ñ*¨5Ó8¸'ÓBˆ	ð	Ø—>‘> )°I�>Ó>Ò>ñ Cð
 �>‰>˜)¨Iˆ>Ó6Ð6øô œZÐ(ô 	Úð	ús   ÁBÂBÂBc                ó0   € V ^8„  d   QhR\         R\         /# ©rW   rf   rY   ©rZ   )r\   s   "r2   r]   r]   ø   s   € ÷ 
qñ 
qœcð 
q¤cñ 
qr4   c                óp   €  \        V 4      pRP                  R T 4       4      #   \         d    T u # i ; i)zÇDecode an RFC 2047 header into a plain string; never raises.

Never raises: malformed encoded-words or unknown charsets degrade to replacement characters instead of
crashing the fetch loop (#55381).
rK   c              3   ól   "  € T F*  w  r\        V\        4      '       d   \        W4      MTx € K,  	  R # 5ir;   )rí   ré   r  )rR   Úpartrÿ   s   &  r2   rT   Ú'_decode_header_value.<locals>.<genexpr>  s-   é € ÐpÑjoÑYfÐY]´:¸dÄE×3JÒ3J”L Ô/ÐPTÔTÓjoùs   ‚24)r   r„   Újoin)rf   Úpartss   & r2   Ú_decode_header_valuer  ø   s?   € ðÜ˜cÓ"ˆð �8‰8ÑpÑjoÓpÓpÐpøô ô ØŠ
ðús   ‚% ¥5´5c                ód   € V ^8„  d   QhR\         P                  P                  R\        R\        /# )rW   ÚmsgÚcontent_typerY   ©Ú	email_libÚmessageÚMessagerZ   )r\   s   "r2   r]   r]     s-   € ÷ ñ œ)×+Ñ+×3Ñ3ð Ä3ð Ì3ñ r4   c                ó  € V P                  4        Fo  pR\        VP                  RR4      4      9   g   VP                  4       V8w  d   K:  VP	                  RR7      ;p'       g   KV  \        W2P                  4       4      u # 	  R# )zGDecoded text of the first non-attachment part of *content_type*, or ''.Ú
attachmentúContent-DispositionrJ   T©r  )ÚwalkrZ   rq   Úget_content_typeÚget_payloadr  Úget_content_charset)r  r  r  rï   s   &&  r2   Ú_first_body_partr"    st   € à—‘–
ˆØœ3˜tŸx™xÐ(=¸rÓBÓCÔCÀt×G\ÑG\ÓG^ÐbnÔGnÙØ×&Ñ&¨dÐ&Ó3Ð3ˆ7×3Ð3Ü ×)AÑ)AÓ)CÓDÒDñ	 ñ
 r4   c                óX   € V ^8„  d   QhR\         P                  P                  R\        /# )rW   r  rY   r  )r\   s   "r2   r]   r]     s*   € ÷ Pñ PœI×-Ñ-×5Ñ5ð P¼#ñ Pr4   c                óF  € V P                  4       '       d6   \        V R4      p\        V R4      ;'       g    V'       d   \        V4      # R# V P                  RR7      ;p'       d   \	        W P                  4       4      MRpV P                  4       R8X  d   \        V4      # T# )z?Extract the plain-text body from a potentially multipart email.ú	text/htmlú
text/plainrJ   Tr  )Úis_multipartr"  Ú_strip_htmlr   r  r!  r  )r  Úhtmlrï   Útexts   &   r2   Ú_extract_text_bodyr+    s‹   € à
×Ñ×ÒÜ  [Ó1ˆÜ  \Ó2×YÐYÏD´{À4Ó7HÐYÐVXÐYØKNÏ?É?ÐbfÈ?ÓKgÐ@gÀÖ@gŒ<˜×!8Ñ!8Ó!:Ô;Ðnp€DØ #× 4Ñ 4Ó 6¸+Ô EŒ;�tÓÐOÈ4ÐOr4   c                ó0   € V ^8„  d   QhR\         R\         /# )rW   r)  rY   r  )r\   s   "r2   r]   r]     s   € ÷ ñ ”cð œcñ r4   c                ób   € \          F  w  rVP                  W 4      p K  	  V P                  4       # )z5Naive HTML tag stripper for fallback text extraction.)Ú
_HTML_SUBSÚsubr`   )r)  rÚ   Úrepls   &  r2   r(  r(    s(   € ç#‰ˆØ�{‰{˜4Ó&Šñ $à�:‰:‹<Ðr4   c                ó0   € V ^8„  d   QhR\         R\         /# r
  r  )r\   s   "r2   r]   r]     s   € ÷ 'ñ '¤ð '¬ñ 'r4   c                óÈ  a€ \         P                  ! RR\        T ;'       g    R4      4      p\        V4      \        8”  g   VP                  R4      ^@8”  d   R# \        V4      w  r#V'       gÎ   \        P                  V4      ;p'       d±   \        VP                  ^4      4      P                  4       VP                  ^4      uopRV^R
 9   dm   \        ;QJ d    V3R lR 4       F  '       g   K   RM	  R	M! V3R lR 4       4      '       g-   RS9  g$   SP                  4       VP                  4       8X  d   TpVP                  4       P                  4       pRV9   d   V# R# )a‘  Bare lowercased addr-spec from a From: value. Uses parseaddr, not a first-<...> regex (GHSA-rxqh-5572-8m77);
RFC 5322 folding is unfolded first because parseaddr misreads a folded quoted display name. Unquoted
``Name <addr>`` values parseaddr rejects (``Doe, John <j@x>``) fall back to their single bracketed address,
but only when the display part (``(comments)`` removed) cannot hold another mailbox or group: no quotes, ``;``,
``:`` or stray parens, and no ``@`` unless it is exactly the bracketed address (``a@x <a@x>``). Values over
``_MAX_FROM_LEN`` (or with more than 64 ``(``) and results without ``@`` return ``""`` so the caller drops the message.z\r?\n[ \t]+rK   rJ   Ú(Ú@c              3   ó,   <"  € T F	  qS9   x € K  	  R # 5ir;   r¨   )rR   ÚcÚdisplays   & €r2   rT   Ú)_extract_email_address.<locals>.<genexpr>,  s   øé € Ð.LÁVÀ°G®|ÃVùrÝ   z;:()TFéÿÿÿÿ)Úrer/  rZ   ÚlenÚ_MAX_FROM_LENÚcountr   Ú_SINGLE_BRACKET_FROM_REÚ	fullmatchÚ_strip_commentsÚgroupr`   râ   r/   )rf   ri   rl   rÛ   ÚmÚ	bracketedr7  s   &     @r2   Ú_extract_email_addressrD    s  ø€ ô �FŠF�> 3¬¨C¯I¨I°2«Ó7€EÜ
ˆ5ƒz”MÔ! U§[¡[°Ó%5¸Ô%:ÙÜ˜Ó�G€AßÔ1×;Ñ;¸EÓBÐB�QÖBÜ,¨Q¯W©W°Q«ZÓ8×>Ñ>Ó@À!Ç'Á'È!Ã*Ðˆ�Ø�9˜Q˜r�?Ô"¯3«3Ô.LÁVÓ.L¯3¯3ª3Ô.LÁVÓ.L×+LÒ+LØ Ô'¨7¯=©=«?¸i¿o¹oÓ>OÔ+OØˆDØ�:‰:‹<×ÑÓ€DØ˜$”;ˆ4Ð& BÐ&r4   c                ó0   € V ^8„  d   QhR\         R\         /# ©rW   r*  rY   r  )r\   s   "r2   r]   r]   3  s   € ÷ ñ œ#ð ¤#ñ r4   c                óF   € \         P                  RV 4      ;q8w  d   Tp K   V # )zPRemove (possibly nested) ``(comments)``, innermost first, until nothing changes.rK   )Ú_COMMENT_REr/  )r*  Ústrippeds   & r2   r@  r@  3  s"   € ä"—‘ s¨DÓ1Ð1ˆ8Ô
:ØŠØ€Kr4   c                ó\   € V ^8„  d   QhR\         R\        \        \         ,          ,          /# rF  )rZ   r   r9   )r\   s   "r2   r]   r]   :  s'   € ÷ Añ A”cð Aœh¤t¬C¥yÕ1ñ Ar4   c                óÎ  € . . ^ R^ 3w  rr4pV\        V 4      8  Ed    W,          pVR8X  d>   V'       g	   V'       d.   V'       d   VP                  WV^,            4       V^,          pK]  V'       d   VR8g  pVP                  V4       M¨V'       d8   VR^RR/P                  V^ 4      ,          pV'       g   VP                  R4       MiVR8X  d   ^pM_VR8X  d   RpVP                  V4       MDVR8X  d   R# VR	8X  d$   VP                  R
P                  V4      4       . pMVP                  V4       V^,          pEK0  V'       g	   V'       d   R# VR
P                  V4      .,           # )zÜSplit an Authentication-Results value on ``;`` outside quoted-strings and (nested) comments; comments are
dropped, quoted-strings kept (``header.from="x"`` stays readable). ``None`` when a quote or comment is unbalanced.FÚ\Ú"r3  Ú)rK   TNÚ;rJ   r9  )r;  Úappendrq   r  )r*  ÚclausesÚcurÚdepthÚquotedÚir6  s   &      r2   Ú_ar_clausesrV  :  s#  € ð &(¨¨Q°°qÐ%8Ñ"€G�% Ø
Œc�$‹i�-Ø�GˆØ�Œ9Ÿ&§EßØ—
‘
˜4 ! a¥%˜=Ô)Ø��FˆAÙßØ˜#‘XˆFØ�J‰J�q�MßØ�c˜1˜c 2Ð&×*Ñ*¨1¨aÓ0Õ0ˆEßØ—
‘
˜3”øØ�#ŒXØ‰EØ�#ŒXØˆFØ�J‰J�q�MØ�#ŒXÙØ�#ŒXØ�N‰N˜2Ÿ7™7 3›<Ô(Ø‰Cà�J‰J�qŒMØ	ˆQ�‹ßŸUˆ4Ð@¨°2·7±7¸3³<°.Õ(@Ð@r4   c                óh   € V ^8„  d   QhR\         R\        \        \         \         3,          ,          /# rF  )rZ   r9   Útuple)r\   s   "r2   r]   r]   \  s+   € ÷ Tñ T”cð Tœd¤5¬¬c¨¥?Õ3ñ Tr4   c                ó²   € \         P                  V 4       UUu. uF0  w  rV'       g   K  VP                  4       VP                  R4      3NK2  	  upp# u uppi )zÍ``(property, value)`` pairs (``header.from=x``) of one comment-free Authentication-Results clause, property
lowercased, surrounding quotes stripped. Quoted-string contents are never scanned for properties.rM  )Ú_AUTH_PROP_REÚfindallr/   r`   )r*  Úpr1   s   &  r2   Ú_auth_propsr]  \  sE   € ô 3@×2GÑ2GÈÔ2MÔSÑ2M©$¨!ÔQRÔ%ˆQ�W‰W‹Y˜Ÿ™ ›Ó%Ñ2MÒSÐSùÓSs
   ™Aª%Ac                ó0   € V ^8„  d   QhR\         R\         /# )rW   rÕ   rY   r  )r\   s   "r2   r]   r]   b  s   € ÷ 6ñ 6œð 6¤ñ 6r4   c                ój   € V P                  R4      ^,          P                  4       P                  4       # )z2Lowercased domain part of an email address, or ''.r4  )Ú
rpartitionr`   r/   )rÕ   s   &r2   Ú
_domain_ofra  b  s*   € à×Ñ˜cÓ" 1Õ%×+Ñ+Ó-×3Ñ3Ó5Ð5r4   c                ó<   € V ^8„  d   QhR\         R\         R\        /# )rW   ÚaÚbrY   rc   )r\   s   "r2   r]   r]   g  s&   € ÷ Tñ Tœð T¤ð T¬ñ Tr4   c                ó   € T ;'       g    RP                  4       P                  4       P                  R4      p T;'       g    RP                  4       P                  4       P                  R4      p\        T ;'       d    T4      ;'       dE    W8H  ;'       g9    V P	                  RV,           4      ;'       g    VP	                  RV ,           4      # )zDRelaxed DMARC alignment: equal, or one is a dot-suffix of the other.rJ   Ú.)r`   r/   Úrstripr=   Úendswith)rc  rd  s   &&r2   Ú_domains_alignedri  g  s“   € à	
�ˆˆb�‰Ó×ÑÓ!×(Ñ(¨Ó-€AØ	
�ˆˆb�‰Ó×ÑÓ!×(Ñ(¨Ó-€AÜ�—��a‹=×SÐS˜a™f×RÐR¨¯
©
°3¸µ7Ó(;×RÐR¸q¿z¹zÈ#ÐPQÍ'Ó?RÐSr4   c          
      ó’   € V ^8„  d   QhR\         P                  P                  R\        R\        R\        \
        \        3,          /# )rW   r  Ú	from_addrÚauthserv_idrY   )r  r  r  rZ   rX  r=   )r\   s   "r2   r]   r]   n  sB   € ÷ .=ñ .=¤y×'8Ñ'8×'@Ñ'@ð .=ÌSð .=Ôbeð .=ÔjoÔptÔvyÐpyÕjzñ .=r4   c               óÒ  a
a€ \        V4      oS'       g   R# V P                  R4      ;p'       g	   R\        3# RP                  \	        V^ ,          4      P                  4       4      p\        V4      ;pf   R# V'       g	   R\        3# V^ ,          P                  4       P                  4       V8w  d	   R\        3# R. R. R. /pV F~  p\        P                  V4      ;p'       g   K"  WhP                  ^4      P                  4       ,          P                  VP                  ^4      P                  4       \        V4      34       K€  	  RR/R	 V3R
 lllo
\!        VR,          4      ^8”  d   R# \"        ;QJ d&    V
3R lVR,           4       F  '       g   K   RM	  RM! V
3R lVR,           4       4      '       d   R# \!        VR,          4      ^8X  d7   VR,          ^ ,          ;p	^ ,          R8X  d   S
! V	^,          R4      '       d   R# \"        ;QJ d&    V
3R lVR,           4       F  '       g   K   RM	  RM! V
3R lVR,           4       4      '       d   R# RRVR,           R23# )u�  Verify the ``From:`` domain is authenticated; returns ``(authenticated, reason)``.
``From:`` is attacker-controlled (GHSA-rxqh-5572-8m77); the only trustworthy signal is the
``Authentication-Results`` header stamped by the *receiving* server. It prepends, so only the
FIRST instance is authoritative, and it must match the required, already-normalised *authserv_id* exactly. A matching id is a
pin, not proof of provenance: the receiving MTA must strip inbound results claiming its id (RFC 8601).
True on DMARC pass, aligned SPF pass, or aligned DKIM (``header.d``) pass. No header or no pin â†’ fail-closed
(opt out via ``EmailAdapter._require_authenticated_sender``).FzAuthentication-ResultsrK   ÚdmarcÚspfÚdkimÚrequiredTc                óš   € V ^8„  d   QhR\         \        \        \        3,          ,          R\        \        R3,          R\        R\        /# )rW   ÚpropsÚnames.rq  rY   )r9   rX  rZ   r=   )r\   s   "r2   r]   Ú3_verify_sender_authentication.<locals>.__annotate__‹  sE   € ÷ jñ j”tœE¤#¤s (�OÕ,ð j´U¼3À¸8µ_ð jÔSWð jÔcgñ jr4   c                ó  <€ V  UUu. uF  w  r4W19   g   K  \        V4      NK  	  ppp\        V4      ;'       g    V'       * ;'       d;    \        ;QJ d    V3R  lV 4       F  '       d   K   R# 	  R# ! V3R  lV 4       4      # u uppi )c              3   ó<   <"  € T F  p\        VS4      x € K  	  R # 5ir;   )ri  )rR   ÚdÚfrom_domains   & €r2   rT   ÚA_verify_sender_authentication.<locals>.aligned.<locals>.<genexpr>�  s   øé € Ð6iÑahÐ\]Ô7GÈÈ;×7WÐ7WÓahùs   ƒFT)ra  r=   rü   )rs  rt  rq  r\  r1   Údomainsry  s   &&$   €r2   ÚalignedÚ._verify_sender_authentication.<locals>.aligned‹  sj   ø€ Ù-2ÔA©U¡T Q°a±j”=”:˜a–=©UˆÑAÜ�W“×-Ð- X¤×iÐi·3³3Ô6iÑahÓ6i·3´3Ði²3Ði°3Ô6iÑahÓ6iÓ3iÐiùó Bs
   ‡
B–Bc              3   óX   <"  € T F  w  rVR 8H  ;'       d    S! VRRR7      x € K!  	  R# 5i)ÚpassF)rq  N©zheader.fromr¨   ©rR   Úrrs  r|  s   &  €r2   rT   Ú0_verify_sender_authentication.<locals>.<genexpr>’  s0   øé € Ð
mÑ\lÑPXÐPQˆ1�‰;×KÐK™7 5Ð*:ÀUÔKÔKÓ\lùs   ƒ*–*r  c              3   óÌ   <"  € T FY  w  rVR 8H  ;'       dF    S! T\         ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   RMR4      x € K[  	  R# 5i)r  c              3   ó0   "  € T F  w  rVR 8H  x € K  	  R# 5i)úheader.dNr¨   )rR   r\  rl   s   &  r2   rT   Ú:_verify_sender_authentication.<locals>.<genexpr>.<genexpr>™  s   é € Ð>aÑ[`ÑSWÐST¸qÀJ¾Ó[`ùs   ‚TFN)r†  r€  ©râ   r�  s   &  €r2   rT   rƒ  ™  sU   øé € ð ,Ù*‰xˆqð �‰;×xÐx™7 5¿3»3Ñ>aÑ[`Ó>a¿3¿3º3Ñ>aÑ[`Ó>a×;aÒ;a©-ÐgwÓxÔxÛ*ùs   ƒA$–A$¥A$¹A$ÁA$zauthentication failed (:Néx   NrN  )Fzmissing From domain)Fz5unbalanced quote or comment in Authentication-Results)Fzambiguous dmarc result)Tz
dmarc=pass)zsmtp.mailfromz	smtp.fromzenvelope-from)Tzspf=pass aligned)Tzdkim=pass aligned)ra  Úget_allÚ_NO_AUTH_RESULTS_REASONr  rZ   ÚsplitrV  Ú_MISSING_AUTHSERV_REASONr`   r/   Ú_UNTRUSTED_AUTHSERV_REASONÚ_AUTH_METHOD_REÚmatchrA  rP  r]  r;  râ   )r  rk  rl  rÖ   ÚtrustedrQ  ÚresultsÚclauserB  ro  r|  ry  s   &&$       @@r2   Ú_verify_sender_authenticationr”  n  s*  ù€ ô ˜YÓ'€KßØ+Ð+Ø—{‘{Ð#;Ó<Ð<ˆGÖ<ØÔ-Ð-Ð-Ø�h‰h”s˜7 1�:“×,Ñ,Ó.Ó/€Gô ˜wÓ'Ð'ˆÒ0ØMÐMßØÔ.Ð.Ð.Øˆq…z×ÑÓ×ÑÓ! [Ô0ØÔ0Ð0Ð0ð DKÈBÐPUÐWYÐ[aÐceÐBf€GÛˆÜ×%Ñ% fÓ-Ð-ˆ1×-Ð-Ø—G‘G˜A“J×$Ñ$Ó&Õ'×.Ñ.°·±¸³
×0@Ñ0@Ó0BÄKÐPVÓDWÐ/XÖYñ ðjÐZ^÷ jò jô ˆ7�7ÕÓ˜qÔ Ø.Ð.ç
ƒsÔ
mÐ\cÐdkÖ\lÓ
m‡s‡s‚sÔ
mÐ\cÐdkÖ\lÓ
m×mÒmØ!Ð!ä
ˆ7�5�>Ó˜aÔ¨G°E­N¸1Õ,=Ð%= S¸qÕ$AÀVÔ$KÑPWØ��FÐC÷QEò QEà'Ð'ç
ƒsô ,Ø" 6ž?ó,‡s‡s‚sô ,Ø" 6ž?ó,÷ ,ò ,à(Ð(ØÐ+¨G°D­M¨?¸!Ð<Ð<Ð<r4   c          	      óœ   € V ^8„  d   QhR\         P                  P                  R\        R\        \
        \        \        3,          ,          /# )rW   r  Úskip_attachmentsrY   )r  r  r  r=   r9   r×   rZ   r   )r\   s   "r2   r]   r]   Ÿ  s@   € ÷ ñ œi×/Ñ/×7Ñ7ð Ì4ð Ô\`ÔaeÔfiÔknÐfnÕaoÕ\pñ r4   c                óÊ  € . pV P                  4       '       g   V# V P                  4        EF
  p\        VP                  RR4      4      VP	                  4       rTV'       g   RV9  d   RV9  g   VR9   d   KM  VP                  4       ;p'       d   \        V4      MRVP                  4       ;'       g    R 2pVP                  RR7      ;p'       g   K©  \        V4      P                  P                  4       ;p	\        9   d    \        W‰4      R	rºM\#        W‡4      RrºVP%                  RV
RVRVRV/4       EK  	  V#   \         d    \        P!                  R
T4        EK6  i ; i)zVExtract attachment metadata and cache files locally (nothing when *skip_attachments*).r  rJ   r  Úinlinezattachment.ÚbinTr  Úimagez6Skipping non-image attachment %s (invalid magic bytes)ÚdocumentÚpathÚfilenamerÁ   Ú
media_type>   r%  r&  )r'  r  rZ   rq   r  Úget_filenamer  Úget_content_subtyper   r   Úsuffixr/   Ú_IMAGE_EXTSr   r  ro   rÍ   r   rP  )r  r–  Úattachmentsr  Údispositionr  Úfnr�  rï   ÚextÚcached_pathÚkinds   &&          r2   Ú_extract_attachmentsr©  Ÿ  sb  € à€KØ×Ñ×ÒØÐØ—‘—
ˆÜ$'¨¯©Ð1FÈÓ(KÓ$LÈd×NcÑNcÓNe�\ß °KÔ ?Ø Ô+¨|Ð?ZÔ/ZÙØ6:×6GÑ6GÓ6IÐ0I°Ö0IÔ'¨Ô+ÐR]Ð^b×^vÑ^vÓ^x÷  _Bð  _Bð  }Bð  ^Cð  QDˆØ×+Ñ+°4Ð+Ó8Ð8�Ö8ÙÜ˜“>×(Ñ(×.Ñ.Ó0Ð0ˆC´[Ô@ðÜ$:¸7Ó$HÈ'™Tô
 !:¸'Ó LÈj˜Ø×Ñ˜F K°¸XÀvÈtÐUaÐcoÐp×qñ! ð" Ðøô ô Ü—‘ÐUÐW_Ô`Ûðús   ÄD<Ä<!E"Å!E"c                ó@   € V ^8„  d   QhR\         R\        R\        RR/# )rW   r  rœ  r�  rY   N)r   r   rZ   )r\   s   "r2   r]   r]   ¸  s(   € ÷ ñ ”mð ¬4ð ¼3ð À4ñ r4   c                ó6  € \        VR4      ;_uu_ 4       p\        RR4      pVP                  VP                  4       4       \        P
                  ! V4       VP                  RRV 24       V P                  V4       RRR4       R#   + '       g   i     R# ; i)z:Attach *path* to *msg* as base64 application/octet-stream.ÚrbÚapplicationzoctet-streamr  zattachment; filename=N)Úopenr   Úset_payloadÚreadr   Úencode_base64Ú
add_headerÚattach)r  rœ  r�  Úfr  s   &&&  r2   Ú_attach_filerµ  ¸  sq   € ä	ˆd�D×	Ô	˜QÜ˜ ~Ó6ˆØ×Ñ˜Ÿ™›Ô"Ü×Ò˜tÔ$Ø�‰Ð-Ð1FÀxÀjÐ/QÔRØ�
‰
�4Ô÷ 
×	×	Ò	ús   •A(BÂB	c                   óü  a a€ ] tR tRt oRtRtRt/ t]! 4       t	V3R lV 3R llt
V3R lR ltV3R lR	 lt]R
 4       tV3R lR ltV3R lR ltV3R lR ltV3R lR ltRR/V3R lR lltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR  ltV3R! lR" ltV3R# lR$ ltV3R% lR& lt]V3R' lR( l4       tV3R) lR* ltV3R+ lR, ltV3R- lR. lt V3R/ lR0 lt!RNV3R2 lR3 llt"V3R4 lR5 lt#ROR6R/V3R7 lR8 lllt$V3R9 lR: lt%ROV3R; lR< llt&R=R1/V3R> lR? llt'RPV3R@ lRA llt(RQV3RB lV 3RC lllt)V3RD lRE lt*RPV3RF lRG llt+RNV3RH lRI llt,V3RJ lRK lt-V3RL lt.RMt/Vt0V ;t1# )RÚEmailAdapteriÂ  z;Email gateway adapter using IMAP (receive) and SMTP (send).Tc                ó    <€ V ^8„  d   QhRS[ /# )rW   Úconfig)r   )r\   r±   s   "€r2   r]   ÚEmailAdapter.__annotate__Ð  s   ø€ ÷ $Iñ $I™~ñ $Ir4   c                óD  <a€ \         SV `  V\        P                  4       VP                  ;'       g    / oV3R  lpV3R lpV! RR4      P                  4       V n        \        RR4      V n        V! RR4      P                  4       V n	        \        RR	4      V n        \        V! R
R4      4      V n        V! RR4      V n        V! RR4      P                  4       V n        \        RR4      V n        \        V! RR4      V P                   R8X  d   RMRR7      V n        V! RR4      V n        \        R^4      V n        SP)                  RR4      V n        RS9   d   \-        SR,          4      V n        M\1        RR4      '       * V n        SP)                  RR4      ;'       g    \        R R4      P                  4       P3                  4       V n        \7        4       V n        R!V n        R"V n        RRuV n        V n         / V n!        \D        PG                  R#V P                  4       R"# )$c                 óP   <€ \        V R 4      ;'       g    SP                  VR 4      # )rJ   )r_   rq   ©ÚenvÚkeyÚextras   &&€r2   r3   Ú'EmailAdapter.__init__.<locals>.<lambda>Õ  s"   ø€ ¤;¨s°BÓ#7×#MÐ#M¸5¿9¹9ÀSÈ"Ó;MÐ#Mr4   c                 óP   <€ \        V \        SP                  V4      R R7      4      # )Tre   )rg   r   rq   r½  s   &&€r2   r3   rÁ  Ö  s   ø€ ¤m°C¼ÈÏÉÐSVËÐaeÔ9fÔ&gr4   rø   rÕ   rù   rJ   rú   Ú	imap_hostÚEMAIL_IMAP_PORTiá  ÚEMAIL_IMAP_SECURITYÚimap_securityÚEMAIL_IMAP_TLS_VERIFYÚimap_tls_verifyrû   Ú	smtp_hostÚEMAIL_SMTP_PORTéK  ÚEMAIL_SMTP_SECURITYÚsmtp_securityéÑ  r&   r)   re   ÚEMAIL_SMTP_TLS_VERIFYÚsmtp_tls_verifyÚEMAIL_POLL_INTERVALr–  FÚrequire_authenticated_senderÚEMAIL_TRUST_FROM_HEADERrl  ÚEMAIL_AUTHSERV_IDiÐ  Nz"[Email] Adapter initialized for %s)$ÚsuperÚ__init__r   ÚEMAILrÀ  r`   Ú_addressr_   Ú	_passwordÚ
_imap_hostra   Ú
_imap_portrr   Ú_imap_securityÚ_imap_tls_verifyÚ
_smtp_hostÚ
_smtp_portÚ_smtp_securityÚ_smtp_tls_verifyÚ_poll_intervalrq   Ú_skip_attachmentsr=   Ú_require_authenticated_senderrg   r/   Ú_authserv_idÚsetÚ
_seen_uidsÚ_seen_uids_maxÚ
_poll_taskÚ_last_fetch_failedÚ_last_fetch_errorÚ_thread_contextro   Úinfo)r¥   r¹  ÚsettingÚ
tls_verifyrÀ  Ú	__class__s   &&  @€r2   rÖ  ÚEmailAdapter.__init__Ð  sõ  ù€ Ü‰Ñ˜¤§¡Ô0ð —‘×"Ð" ˆÜMˆÜgˆ
Ù °Ó;×AÑAÓCˆŒÜ$Ð%5°rÓ:ˆŒÙ!Ð"3°[ÓA×GÑGÓIˆŒÜ&Ð'8¸#Ó>ˆŒÜ1±'Ð:OÐQ`Ó2aÓbˆÔÙ *Ð+BÐDUÓ VˆÔÙ!Ð"3°[ÓA×GÑGÓIˆŒÜ&Ð'8¸#Ó>ˆŒÜ1±'Ð:OÐQ`Ó2aÐtx÷  uDñ  uDð  HKô  uKÑkpð  Q[ô  \ˆÔÙ *Ð+BÐDUÓ VˆÔÜ*Ð+@À"ÓEˆÔØ!&§¡Ð+=¸uÓ!EˆÔð *¨UÔ2Ü15°eÐ<ZÕ6[Ó1\ˆDÕ.ä5BÐC\Ð^cÓ5dÔ1dˆDÔ.ð #ŸY™Y }°bÓ9×aÐa¼[ÐI\Ð^`Ó=a×hÑhÓj×pÑpÓrˆÔÜ"›uˆŒØ#'ˆÔØ26ˆŒØ:?ÀÐ7ˆÔ Ô!7ð ;=ˆÔÜ�‰Ð8¸$¿-¹-ÖHr4   c                ó   <€ V ^8„  d   QhRR/# ©rW   rY   Nr¨   )r\   r±   s   "€r2   r]   rº  ö  s   ø€ ÷ 	Uñ 	U ñ 	Ur4   c                ó¾  € \        V P                  4      V P                  8:  d   R#  \        V P                  R R7      p\	        WP                  ^,          ) R 4      V n        \
        P                  R\        V P                  4      4       R#   \        \        3 d=    \	        \        T P                  4      T P                  ) ^,          R 4      T n         R# i ; i)zgKeep only the highest half of UIDs once over the cap (UIDs are monotonic; UNSEEN prevents re-delivery).Nc                 ó   € \        V 4      # r;   )r[   )Úus   &r2   r3   Ú.EmailAdapter._trim_seen_uids.<locals>.<lambda>û  s   € ÄÀAÄr4   )r¿  z'[Email] Trimmed seen UIDs to %d entries)
r;  rç  rè  Úsortedræ  ro   rÍ   r  rì   r9   )r¥   Úsorted_uidss   & r2   Ú_trim_seen_uidsÚEmailAdapter._trim_seen_uidsö  s­   € äˆt�‰Ó 4×#6Ñ#6Ô6Ùð	UÜ  §¡Ñ6FÔGˆKÜ! +×0CÑ0CÀqÕ0HÐ.IÐ.JÐ"KÓLˆDŒOÜ�L‰LÐBÄCÈÏÉÓDXÖYøÜœIÐ&ô 	UÜ!¤$ t§¡Ó"7¸×9LÑ9LÐ8LÐPQÕ8QÐ8RÐ"SÓTˆD�Oð	Uús   ¨A%B ÂA	CÃCc                ó4   <€ V ^8„  d   QhRS[ P                  /# rò   r   )r\   r±   s   "€r2   r]   rº    s   ø€ ÷ ñ ™wŸ}™}ñ r4   c           	     óØ  € V P                   R8X  dM   \        P                  ! V P                  V P                  ^\        V P                  V P                  4      R7      # \        P                  ! V P                  V P                  ^R7      pV P                   R8X  d4    VP                  \        V P                  V P                  4      R7       V# V#   \         d    \        T4       h i ; i)zECreate an IMAP connection using implicit TLS, STARTTLS, or plaintext.r&   )r‰   Ússl_context©r‰   r)   )rþ  )rÜ  r€   Ú	IMAP4_SSLrÚ  rÛ  r{   rÝ  r�   r)   r„   r†   ©r¥   r~   s   & r2   Ú_connect_imapÚEmailAdapter._connect_imap  sÖ   € à×Ñ %Ô'Ü×$Ò$ T§_¡_°d·o±oÈrÔ_kÐlp÷  mBñ  mBð  DH÷  DSñ  DSó  `Tô  Uð  UÜ�}Š}˜TŸ_™_¨d¯o©oÀrÔJˆØ×Ñ *Ô,ðØ—‘¬,°t×7LÑ7LÈdÏoÉoÓ*^�Ô_ð ˆˆtˆøô ô Ü˜DÔ!Øðús   Â0C ÃC)c              #  óò   "  € V P                  4       p VP                  V P                  V P                  4       \	        V4       VP                  R4       Vx € \        V4       R#   \        T4       i ; i5i)z}Logged-in IMAP handle on INBOX; always ``_close_imap``-ed on exit (a login/select failure used to leak one fd per reconnect).ÚINBOXN)r  ÚloginrØ  rÙ  rÓ   Úselectr†   r  s   & r2   Ú_inboxÚEmailAdapter._inbox  sY   é € ð ×!Ñ!Ó#ˆð	Ø�J‰J�t—}‘} d§n¡nÔ5Ü˜$ÔØ�K‰K˜Ô ØŠJä˜ÖøŒK˜Õüs   ‚A7”AA' ÁA7Á'A4Á4A7c                ó4   <€ V ^8„  d   QhRS[ P                  /# rò   )rÂ   rÃ   )r\   r±   s   "€r2   r]   rº    s   ø€ ÷ 
qñ 
q™wŸ|™|ñ 
qr4   c                ó®  € V P                   V P                  V P                  \        V P                  V P                   4      3w  rr4 \        WW4\        P                  \        P                  \        R7      #   \        \        \        3 dH   p\        T\        P                  4      '       d   h \        YY4\         \"        \        R7      u Rp?# Rp?ii ; i)a  SMTP connection with TLS established (callers go straight to ``login()``). An unreachable IPv6 address can
hang until the socket timeout, so connection-level failures retry through an IPv4-only socket path (no global
resolver mutation); TLS verification errors are not retried.rÿ  N)rÞ  rß  rà  r{   rá  rÆ   rÂ   rÃ   ÚSMTP_SSLÚSMTP_CONNECT_TIMEOUTÚTimeoutErrorÚConnectionErrorr•   rí   r'   ÚSSLErrorr¡   r³   )r¥   ru   rˆ   r¼   r½   rž   s   &     r2   Ú_connect_smtpÚEmailAdapter._connect_smtp  s³   € ð %)§O¡O°T·_±_Àd×FYÑFYÔ[gÐhl×h}Ñh}ð  @D÷  @Oñ  @Oó  \Pð  %PÑ!ˆ�Hð	qÜ˜d¨(¼¿¹Äw×GWÑGWÔauÔvÐvøÜœo¬wÐ7ô 	qÜ˜#œsŸ|™|×,Ò,ØÜ˜d¨(¼ÄMÔ[oÔpÕpûð	qús   Á/A7 Á7CÂ<CÃ	CÃCc                ó>   <€ V ^8„  d   QhRS[ RS[RS[ RS[ RS[RS[/# )rW   Úlog_fmtÚerrÚcodeÚdetailÚ	retryablerY   )rZ   Úobjectr=   )r\   r±   s   "€r2   r]   rº  +  s9   ø€ ÷ ñ ™Sð ¡vð ±Sð Á#ð ÑUYð Ñ^bñ r4   c               óV   € \         P                  W4       V P                  W4VR7       R# )zTLog *err*, record a fatal error for the gateway's reconnect machinery, return False.©r  F)ro   ÚerrorÚ_set_fatal_error)r¥   r  r  r  r  r  s   &&&&&$r2   Ú_failÚEmailAdapter._fail+  s$   € ä�‰�WÔ"Ø×Ñ˜d°iÐÔ@Ùr4   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# ©rW   Úis_reconnectrY   r<   )r\   r±   s   "€r2   r]   rº  1  s   ø€ ÷ uñ u©ð u±ñ ur4   c                ó&  €  V P                  4       ;_uu_ 4       pV P                  P                  V P                  4      pV'       d   Ve   \	        V4      V n        RpMgVP                  RRR4      w  rVV P
                  P                  VR8X  d/   V'       d'   V^ ,          '       d   V^ ,          P                  4       MR4       RpV P                  4        \        P                  V\        V P
                  4      4       RRR4       \	        V P
                  4      V P                  V P                  &   R#   + '       g   i     L>; i  \         d>   pT P                  RTR	R
T P                   RT P                    RT 2RR7      u Rp?# Rp?ii ; i)zUConnection test + seen-UID baseline. Sets a fatal error and returns False on failure.Nzq[Email] IMAP reconnect test passed. Restored %d seen UIDs; messages received during the outage will be processed.ÚsearchÚALLÚOKzB[Email] IMAP connection test passed. %d existing messages skipped.Tz"[Email] IMAP connection failed: %sÚemail_imap_connect_errorzIMAP connection to rŽ   ú	 failed: r  r¨   )r  Ú_seen_uids_snapshotrq   rØ  ræ  rç  ÚuidÚupdaterŒ  rú  ro   rí  r;  r„   r  rÚ  rÛ  )r¥   r"  r~   ÚsnapshotÚpassedÚstatusrè   rÒ   s   &&      r2   Ú_probe_imapÚEmailAdapter._probe_imap1  sF  € ð	uØ—‘—” $Ø×3Ñ3×7Ñ7¸¿¹ÓF�ß HÒ$8ô '*¨(£m�D”Oð Q‘Fà#'§8¡8¨H°d¸EÓ#B‘L�FØ—O‘O×*Ñ*¸fÈ¼n×QUÐZ^Ð_`×ZaÔZa¨4°­7¯=©=¬?ÐgiÔjØa�FØ×$Ñ$Ô&Ü—‘˜F¤C¨¯©Ó$8Ô9÷ ô 7:¸$¿/¹/Ó6JˆD×$Ñ$ T§]¡]Ñ3Ù÷ —ûô ô 	uð —:‘:ÐBÀAÐGaØ 3°D·O±OÐ3DÀAÀdÇoÁoÐEVÐV_Ð`aÐ_bÐcÐosð ó uõ uûð		uúsB   ‚E šA=D5ÂD5Â'AD5Ã?4E Ä5E	Å E ÅFÅ2FÆFÆFc                ó    <€ V ^8„  d   QhRS[ /# rò   r<   )r\   r±   s   "€r2   r]   rº  J  s   ø€ ÷ cñ c™Tñ cr4   c                óî  €  V P                  4       p VP                  V P                  V P                  4       VP	                  4        \
        P                  R4       R#   TP	                  4        i ; i  \        P                   d2   pT P                  RTRRT P                   RT R2RR	7      u R
p?# R
p?i\         d1   pT P                  RTRRT P                   RT 2RR	7      u R
p?# R
p?ii ; i)zKSMTP connect + login test. Sets a fatal error and returns False on failure.z$[Email] SMTP connection test passed.Tz&[Email] SMTP authentication failed: %sÚemail_auth_errorzSMTP authentication failed for z: zb. Check EMAIL_PASSWORD (for Gmail/Outlook this must be an app password, not the account password).Fr  Nz"[Email] SMTP connection failed: %sÚemail_smtp_connect_errorzSMTP connection to r(  )r  r  rØ  rÙ  Úquitro   rí  rÂ   ÚSMTPAuthenticationErrorr  r„   rÞ  )r¥   rÅ   rÒ   s   &  r2   Ú_probe_smtpÚEmailAdapter._probe_smtpJ  s÷   € ð	cØ×%Ñ%Ó'ˆDðØ—
‘
˜4Ÿ=™=¨$¯.©.Ô9à—	‘	”Ü�K‰KÐ>Ô?Ùøð —	‘	•ûô ×.Ñ.ô 	kà—:‘:ÐFÈÐK]Ø ?ÀÇÁ¸ÈbÐQRÐPSð TYð YØdið ó kõ kûô ô 	cØ—:‘:ÐBÀAÐGaØ 3°D·O±OÐ3DÀIÈaÈSÐQÐ]að ó cõ cûð	cúsK   ‚A5 “&A  ¹%A5 Á A2Á2A5 Á5C4Â
&B6Â0C4Â6C4ÃC4Ã%C/Ã)C4Ã/C4r"  Fc                ó&   <€ V ^8„  d   QhRS[ RS[ /# r!  r<   )r\   r±   s   "€r2   r]   rº  ]  s   ø€ ÷ ñ ©Tð ¹dñ r4   c             ƒ  óh  "  € RV P                   3RV P                  3RV P                  3RV P                  33pV UUu. uF  w  r4V'       d   K  VNK  	  upp;p'       d,   RRP	                  V4       R2pV P                  RVR	VR
R7      # V P                  V4      '       d   V P                  4       '       g   R
# V P                  '       d…   V P                  '       gs   V P                   \        P                  9  dT   \        P                  P                  V P                   4       \        P                  RV P                   \        \         4       RV n        \$        P&                  ! V P)                  4       4      V n        \-        RV P                    24       V P/                  R4       R# u uppi 5i)z>Connect to the IMAP server and start polling for new messages.rø   rù   rú   rû   u   Not configured â€” missing z, zL. Set it via `hermes gateway setup` (env) or platforms.email in config.yaml.z
[Email] %sÚemail_missing_configurationFr  z[Email] %s: %s.%sTz[Email] Connected as N)rØ  rÙ  rÚ  rÞ  r  r  r/  r7  rä  rå  r·  Ú_missing_pin_warnedÚaddro   rp   r�  Ú_MISSING_AUTHSERV_HINTÚ_runningÚasyncioÚcreate_taskÚ
_poll_loopré  ÚprintÚ_wire_plugin_handlers)r¥   r"  rq  rX   ri   Úmissingr  s   &$     r2   r”   ÚEmailAdapter.connect]  sˆ  é € ð % d§m¡mÐ4Ð7GÈÏÉÐ6XÐ[lÐnr×n}Ñn}ÐZ~ð  BSð  UY÷  Udñ  Udð  Aeð  fˆÙ/7ÔE©x¡ ¼u—t�t©xÒEÐEˆ7ÖEØ3°D·I±I¸gÓ4FÐ3Gð  HTð  UˆGà—:‘:˜l¨GÐ5RÐT[Ðgl�:ÓmÐmØ×Ñ ×-Ò-°T×5EÑ5E×5GÒ5GÙØ×-×-Ð-°d×6G×6GÐ6GÈDÏMÉMÔam÷  bBñ  bBô  MBÜ×,Ñ,×0Ñ0°·±Ô?Ü�N‰NÐ.°·±Ô?WÔYoÔpØˆŒÜ!×-Ò-¨d¯o©oÓ.?Ó@ˆŒÜÐ% d§m¡m _Ð5Ô6Ø×"Ñ" 4Ô(Ùùó Fùs6   ‚<F2¾F,ÁF,ÁF2Á!AF2Â#F2Â9F2ÃF2ÃCF2c                ó   <€ V ^8„  d   QhRR/# ró  r¨   )r\   r±   s   "€r2   r]   rº  p  s   ø€ ÷ -ñ - $ñ -r4   c              ƒ  ó’   "  € RV n         \        V P                  4      G Rj  x€L
  RV n        \        P	                  R4       R#  L"5i)zStop polling and disconnect.FNz[Email] Disconnected.)r?  r   ré  ro   rí  ©r¥   s   &r2   Ú
disconnectÚEmailAdapter.disconnectp  s7   é € àˆŒÜ˜$Ÿ/™/Ó*×*Ð*ØˆŒÜ�‰Ð+Ö,ñ 	+ùs   ‚ A¢A£#Ac                ó   <€ V ^8„  d   QhRR/# ró  r¨   )r\   r±   s   "€r2   r]   rº  w  s   ø€ ÷ 	5ñ 	5 $ñ 	5r4   c              ƒ  óJ  "  € V P                   '       dD    V P                  4       G Rj  x€L
  \        P                  ! T P                  4      G Rj  x€L
  KU  R#  L0  \        P                   d     R# \         d!   p\
        P                  RT4        Rp?LkRp?ii ; i LO5i)z0Poll IMAP for new messages at regular intervals.Nz[Email] Poll error: %s)	r?  Ú_check_inboxr@  ÚCancelledErrorr„   ro   r  Úsleeprâ  )r¥   rÒ   s   & r2   rB  ÚEmailAdapter._poll_loopw  s}   é € à�m�mˆmð:Ø×'Ñ'Ó)×)Ð)ô
 —-’- × 3Ñ 3Ó4×4Ò4ñ á)øÜ×)Ñ)ô ÚÜô :Ü—‘Ð5°q×9Ñ9ûð:úá4ùs[   ‚B#–A ©AªA ®#B#ÁB!ÁB#ÁA ÁBÁ1B#Á4BÁ=BÁ>BÂB#ÂBÂB#c                ó   <€ V ^8„  d   QhRR/# ró  r¨   )r\   r±   s   "€r2   r]   rº  ‚  s   ø€ ÷ -ñ - Dñ -r4   c              ƒ  ó¼  a aa"  € \         P                  ! 4       oR V 3R lloR VV3R llp\         P                  ! S P                  V4      G Rj  x€L
 pV F  pS P	                  V4      G Rj  x€L
  K  	  S P
                  '       dJ   RS n        S P                  RS P                  ;'       g    RR	R
7       S P                  4       G Rj  x€L
  R# R#  Lƒ Lg L5i)z2Check INBOX for unseen messages and dispatch them.c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# )rW   Úmsg_datarY   ©r×   rZ   r   r=   )r\   s   "r2   r]   Ú/EmailAdapter._check_inbox.<locals>.__annotate__†  s&   € ÷ 	Lñ 	L¬d´3¼°8­nð 	LÄñ 	Lr4   c              “   ó>   <"  € SP                  V R ,          V 4      # 5i)Úsender_addr)Ú_sender_accepted)rU  r¥   s   &€r2   Úauthorize_on_loopÚ4EmailAdapter._check_inbox.<locals>.authorize_on_loop†  s   øé € Ø×(Ñ(¨°-Õ)@À(ÓKÐKùs   ƒc                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# )rW   r  rY   rV  )r\   s   "r2   r]   rW  ‰  s"   € ÷ 	4ñ 	4œD¤¤c �Nð 	4¬tñ 	4r4   c                 ón   <€ \        S! V 4      S\        R R7      pVRJ;'       d    VP                  4       # )z/[Email] Could not schedule sender authorization)ro   Úlog_messageN)r   ro   Úresult)r  Úfutr[  Úloops   & €€r2   ÚgateÚ'EmailAdapter._check_inbox.<locals>.gate‰  s8   ø€ ô +Ñ+<¸YÓ+GÈÔV\Ø7hôjˆCà˜d�?×3Ð3 s§z¡z£|Ð3r4   NFÚemail_imap_fetch_failedzIMAP fetch failedTr  )	r@  Úget_running_loopÚ	to_threadÚ_fetch_new_messagesÚ_dispatch_messagerê  r  rë  Ú_notify_fatal_error)r¥   rc  ÚmessagesrU  r[  rb  s   f   @@r2   rN  ÚEmailAdapter._check_inbox‚  sÈ   úé € ä×'Ò'Ó)ˆ÷	Lð 	L÷	4ñ 	4ô !×*Ò*¨4×+CÑ+CÀTÓJ×Jˆã ˆHØ×(Ñ(¨Ó2×2Ò2ñ !à×"×"Ð"ð
 ',ˆDÔ#Ø×!Ñ!Ð";¸T×=SÑ=S×=jÐ=jÐWjÐvzÐ!Ô{Ø×*Ñ*Ó,×,Ò,ñ #ñ	 Kñ 3ñ -ùsB   …ACÁCÁCÁ0CÁ1CÂ%CÂ1CÃCÃ	CÃCÃCc                ó>   <€ V ^8„  d   QhRS[ P                  RS[RR/# )rW   r~   r*  rY   N)r€   r�   r   )r\   r±   s   "€r2   r]   rº  ž  s+   ø€ ÷ Oñ O¡w§}¡}ð O¹3ð OÀ4ñ Or4   c                óÆ   € V P                   P                  V4       V P                  4        VP                  RVRR4      w  r4VR8w  d   \        P                  RV4       R# R# )zHRemember a rejected UID and mark it seen without fetching its MIME body.Ústorez+FLAGS.SILENTz(\Seen)r&  z+[Email] Could not mark rejected UID %s seenN)rç  r=  rú  r*  ro   rp   )r¥   r~   r*  r.  rl   s   &&&  r2   Ú_mark_uid_consumedÚEmailAdapter._mark_uid_consumedž  sQ   € à�‰×Ñ˜CÔ Ø×ÑÔØ—H‘H˜W c¨?¸JÓG‰	ˆØ�TŒ>Ü�N‰NÐHÈ#ÖNñ r4   c                óz   <€ V ^8„  d   QhRS[ S[S[S[3,          .S[3,          RS[S[S[S[3,          ,          /# )rW   ÚpreauthorizerY   )r   r×   rZ   r   r=   r9   )r\   r±   s   "€r2   r]   rº  ¦  sC   ø€ ÷ 4ñ 4±¹$¹sÁC¸x½.Ð9IÉ4Ð9OÕ0Pð 4ÑUYÑZ^Ñ_bÑdgÐ_gÕZhÕUiñ 4r4   c           	     ó~  € . p V P                  4       ;_uu_ 4       pVP                  RRR4      w  rEVR8X  d/   V'       d'   V^ ,          '       d   V^ ,          P                  4       M.  EF`  pW`P                  9   d   K  VP                  RV\        4      w  rxVR8w  d   K8  \        V4      p	V	e   \        V	4      \        8”  d*   \        P                  RV4       V P                  W64       K„   V P                  Wi4      p
V
RJ;'       d	    V! V
4      pV'       g   V P                  W64       KÅ  VP                  RVR	4      w  rMVR8w  d   Kã  V P                  P                  V4       V P                  4        \        V4      ;pf   \        P                  R
V4       EK6   V P!                  Wn4      pTf   EKO  TP#                  T4       EKc  	  RRR4       \+        T P                  4      T P,                  T P.                  &   T#   \         d$   p\        P                  RYl4       Rp Rp?ELRp?ii ; i  \         d$   p\        P                  RTT4        Rp?EKõ  Rp?ii ; i  + '       g   i     L ; i  \         d9   p\        P                  RT4       R\%        T4      uT n        T n         Rp?LáRp?ii ; i)zVFetch unseen messages; bounded headers pass *preauthorize* before RFC822 is requested.r$  NÚUNSEENr&  Úfetchz?[Email] Unusable pre-authorization headers for UID %s, skippingz8[Email] Failed to authorize message UID %s, skipping: %sFz(RFC822)z?[Email] Unexpected IMAP response structure for UID %s, skippingz6[Email] Failed to process message UID %s, skipping: %sz[Email] IMAP fetch error: %sT)r  r*  rŒ  rç  Ú_PREAUTH_FETCHrð   r;  Ú_MAX_PREAUTH_HEADER_BYTESro   rp   rp  Ú_parse_fetched_headersr„   r  r=  rú  Ú_parse_fetched_messagerP  rZ   rê  rë  ræ  r)  rØ  )r¥   rs  r’  r~   r.  rè   r*  Úheader_statusÚheader_dataÚraw_headersr  ÚacceptedÚauth_excrU  Ú	raw_emailÚparsedÚ	parse_excrÒ   s   &&                r2   rh  Ú EmailAdapter._fetch_new_messages¦  sS  € àˆð.	KØ—‘—” $Ø#Ÿx™x¨°$¸ÓA‘�Ø/5¸¬~Ç$È4ÐPQÏ7Ì7˜D �GŸM™MœOÐXZÓZ�CØŸo™oÔ-Ù Ø15·±¸'À3ÌÓ1WÑ.�MØ$¨Ô,Ù Ü"/°Ó"<�KØ"Ò*¬c°+Ó.>ÔAZÔ.ZÜŸ™Ð'hÐjmÔnØ×/Ñ/°Ô:Ù ð)Ø$(×$?Ñ$?ÀÓ$Q˜	Ø#,°DÐ#8×#TÐ#T¹\È)Ó=T˜÷ $Ø×/Ñ/°Ô:Ù Ø'+§x¡x°¸¸jÓ'IÑ$�FØ ”~Ù ð —O‘O×'Ñ'¨Ô,Ø×(Ñ(Ô*Ü%2°8Ó%<Ð<˜	ÒEÜŸ™Ð'hÐjmÔnÚ ð!à!%×!<Ñ!<¸SÓ!L˜ð Õ)ØŸ™ v×.ñM [÷ ô^ 36°d·o±oÓ2Fˆ× Ñ  §¡Ñ/ØˆøôA %ô )ÜŸ™Ð%_ÐadÔoØ#(žûð)ûô( %ô !ÜŸ™Ð%]Ð_bÐdmÔnÞ ûð!ú÷I —ûôR ô 	Kô �L‰LÐ7¸Ô;Ø>BÄCÈÃFÐ;ˆDÔ# T×%;Ñ%;ûð		Kús¨   „I9 œ$I&ÁI&ÁBI&Ã.HÄ
	HÄI&ÄBI&Æ H5Æ1I&Æ8I&ÇI9 ÈH2	ÈH-	È'I&È-H2	È2I&È5I#	É I	ÉI&ÉI#	É#I&É&I6	É1I9 É6I9 É9J<Ê.J7Ê7J<c          	      óz   <€ V ^8„  d   QhRS[ RS[P                  P                  RS[S[S[S[3,          ,          /# )rW   r*  r  rY   )ré   r  r  r  r   r×   rZ   r   )r\   r±   s   "€r2   r]   rº  Ü  sE   ø€ ÷ wñ w¡Uð w±×1BÑ1B×1JÑ1Jð wÉxÑX\Ñ]`ÑbeÐ]eÕXfÕOgñ wr4   c                ó¸  € \        VP                  RR4      4      ;p'       g)   \        P                  RVP                  RR4      4       R# \	        VP                  RR4      4      pRV9   d6   VP                  R4      ^ ,          P                  4       P                  R4      p\	        VP                  RR4      4      p\        V\        VP                  4       4      4      '       d   \        P                  R	V4       R# \        W#V P                  R
7      w  rgRVRVRVRVRVP                  RR4      RVP                  RR4      RVP                  RR4      RVRV/	# )zNParse sender-facing headers and authentication without touching the MIME body.ÚFromrJ   z;[Email] Dropping message with no parseable From address: %rNrM   rM  ÚSubjectz(no subject)z%[Email] Skipping automated sender: %s)rl  r*  rY  Úsender_nameÚsubjectÚ
message_idú
Message-IDÚin_reply_toúIn-Reply-ToÚdateÚDateÚsender_authenticatedÚauth_reason)rD  rq   ro   rÍ   r  rŒ  r`   ræ   r×   rå   r”  rå  )r¥   r*  r  rY  rˆ  r‰  r�  r‘  s   &&&     r2   Ú_message_metadataÚEmailAdapter._message_metadataÜ  s7  € ä5°c·g±g¸fÀbÓ6IÓJÐJ�ÖJÜ�L‰LÐVÐX[×X_ÑX_Ð`fÐhjÓXkÔlÙÜ*¨3¯7©7°6¸2Ó+>Ó?ˆØ�+ÔØ%×+Ñ+¨CÓ0°Õ3×9Ñ9Ó;×AÑAÀ#ÓFˆKÜ& s§w¡w¨y¸.Ó'IÓJˆÜ ¬T°#·)±)³+Ó->×?Ò?Ü�L‰LÐ@À+ÔNÙÜ,IÈ#Ðhl×hyÑhyÔ,zÑ)ÐØ�s˜M¨;¸À{ÐT]Ð_fØ˜cŸg™g l°BÓ7¸ÈÏÉÐP]Ð_aÓHbØ˜Ÿ™ ¨Ó+Ð-CÐEYÐ[hÐjuðwð 	wr4   c          	      ób   <€ V ^8„  d   QhRS[ RS[ S[,          RS[S[S[S[3,          ,          /# )rW   r*  r}  rY   ©ré   rî   r   r×   rZ   r   )r\   r±   s   "€r2   r]   rº  í  s?   ø€ ÷ _ñ _©%ð _¹eÁiÕ>Oð _ÑT\Ñ]aÑbeÑgjÐbjÕ]kÕTlñ _r4   c                óf   € V P                  V\        4       P                  \        V4      4      4      # )zIParse the bounded IMAP header preflight without constructing a MIME tree.)r’  r	   Ú
parsebytesré   )r¥   r*  r}  s   &&&r2   ry  Ú#EmailAdapter._parse_fetched_headersí  s*   € à×%Ñ% cÔ+<Ó+>×+IÑ+IÌ%ÐP[ÓJ\Ó+]Ó^Ð^r4   c          	      ób   <€ V ^8„  d   QhRS[ RS[ S[,          RS[S[S[S[3,          ,          /# )rW   r*  r€  rY   r•  )r\   r±   s   "€r2   r]   rº  ñ  s:   ø€ ÷ ñ ©%ð ¹EÁIÕ<Mð ÑRZÑ[_Ñ`cÑehÐ`hÕ[iÕRjñ r4   c                óÀ   € \         P                  ! V4      pV P                  W4      ;pf   R# VP                  \	        V4      \        W0P                  R7      R7       V# )z<Parse an authorized RFC822 payload into a dispatchable dict.N)r–  )Úbodyr£  )r  Úmessage_from_bytesr’  r+  r+  r©  rã  )r¥   r*  r€  r  Úmetadatas   &&&  r2   rz  Ú#EmailAdapter._parse_fetched_messageñ  sX   € ä×*Ò*¨9Ó5ˆØ×.Ñ.¨sÓ8Ð8ˆHÒAÙØ�‰Ô/°Ó4Ü$8¸×OeÑOeÔ$fð 	ô 	hàˆr4   c                ó    <€ V ^8„  d   QhRS[ /# rò   r<   )r\   r±   s   "€r2   r]   rº  û  s   ø€ ÷ Uñ U¡ñ Ur4   c                 ój   € \         ;QJ d    R R 4       F  '       g   K   R# 	  R# ! R R 4       4      # )zúTrue when the operator opted into any sender (EMAIL_ or GATEWAY_ALLOW_ALL_USERS).

Both names go through the scoped reader: under multiplex ``os.environ`` is the DEFAULT
profile's opt-in, and borrowing it opened every secondary mailbox to any sender.c              3   ó€   "  € T F4  p\        VR 4      P                  4       P                  4       \        9   x € K6  	  R# 5irß   )r_   r`   r/   Ú_TRUTHYrõ   s   & r2   rT   Ú2EmailAdapter._allow_all_senders.<locals>.<genexpr>   s6   é € ð UÙS�tô ˜t RÓ(×.Ñ.Ó0×6Ñ6Ó8¼GÖCÛSùs   ‚<>TF)ÚEMAIL_ALLOW_ALL_USERSÚGATEWAY_ALLOW_ALL_USERSrˆ  r¨   r4   r2   Ú_allow_all_sendersÚEmailAdapter._allow_all_sendersú  sG   € ÷ ‹sñ UÙSóU�sŒsð 	UŠsð 	Uˆsñ UÙSóUó Uð 	Ur4   c                ó    <€ V ^8„  d   QhRS[ /# rò   r<   )r\   r±   s   "€r2   r]   rº    s   ø€ ÷ ]ñ ]©$ñ ]r4   c                óÒ   € V P                   P                  ;'       g    / P                  R4      p\        V\        4      ;'       d"    VP                  4       P                  4       R9   # )zYTrue when ``platforms.email.unauthorized_dm_behavior`` opts into ``pair`` or ``decline``.Úunauthorized_dm_behavior>   ÚpairÚdecline)r¹  rÀ  rq   rí   rZ   r`   r/   )r¥   Úbehaviors   & r2   Ú_answers_unknown_sendersÚ%EmailAdapter._answers_unknown_senders  sP   € à—K‘K×%Ñ%×+Ð+¨×0Ñ0Ð1KÓLˆÜ˜(¤CÓ(×\Ð\¨X¯^©^Ó-=×-CÑ-CÓ-EÐI\Ñ-\Ð\r4   c                óB   <€ V ^8„  d   QhRS[ RS[S[ S[3,          RS[/# )rW   rY  rU  rY   )rZ   r×   r   r=   )r\   r±   s   "€r2   r]   rº    s*   ø€ ÷ .ñ .©Cð .¹4ÁÁSÀ½>ð .Édñ .r4   c                óž  € WP                   P                  4       8X  d   R# \        V/ 4      '       d   \        P	                  RV4       R# \        RR4      P                  4       p\        4       pV\        RR4      3 FV  p\        V4      pTP                  R \        V\        4      '       d   TM\        V4      P                  R4       4       4       KX  	  VP                  4       V9   pV'       d   RpM|VP                  R	^4      ^ ,          P                  4       V9   d   \        P	                  R
V4       R# V P                  VRV4      pVe   TMV'       * ;'       d    V P                  4       pV'       g/   V P!                  4       '       g   \        P	                  RV4       R# V P"                  '       d•   VP%                  RR4      '       g}   VP%                  RR4      p	\&        P%                  V	R4      p
V'       g   V'       d"   V
'       d   \        P)                  RWV
4       R# \        P	                  RV'       d   RMRW4       R# R# )zOPre-dispatch sender gate: self, automated, authorization, From: authentication.Fz1[Email] Dropping automated sender at dispatch: %sÚEMAIL_ALLOWED_USERSrJ   ÚGATEWAY_ALLOWED_USERSc              3   ó²   "  € T FM  p\        V4      P                  4       '       g   K$  \        V4      P                  4       P                  4       x € KO  	  R # 5ir;   )rZ   r`   r/   )rR   rc  s   & r2   rT   Ú0EmailAdapter._sender_accepted.<locals>.<genexpr>  s<   é € ð -Ñ;p°QÜ  ›VŸ\™\Ÿ^ô 1œ#˜a›&Ÿ,™,›.×.Ñ.×0Ð0Ó;pùs
   ‚!A¨/AÚ,Tr4  zM[Email] Dropping sender whose local part alone matches an allowlist entry: %sÚdmzR[Email] Dropping unauthorized sender at dispatch (unknown senders are ignored): %sr�  r‘  z
no verdictz=[Email] Dropping sender with unauthenticated From: %s (%s).%sz=[Email] Dropping %s sender with unauthenticated From: %s (%s)Ú
authorizedrA   )rØ  r/   ræ   ro   rÍ   r_   r`   ræ  r"   r+  rí   r9   rZ   rŒ  Ú_is_sender_authorizedr¦  r®  rä  rq   Ú_DROP_HINTSrp   )r¥   rY  rU  Úallowed_rawÚlistedrf   Ú	is_listedÚgrantedÚverdictr‘  Úhints   &&&        r2   rZ  ÚEmailAdapter._sender_accepted  sã  € àŸ-™-×-Ñ-Ó/Ô/ÙÜ ¨R×0Ò0Ü�L‰LÐLÈkÔZÙÜ!Ð"7¸Ó<×BÑBÓDˆä“ˆØ¤Ð-DÀbÓ!IÓJˆCÜ*¨3Ó/ˆCØ�M‰Mñ -Ä*ÈSÔRV×BWÒBW¹3Ô]`ÐadÓ]e×]kÑ]kÐloÓ]pÐ;pó -ö -ñ Kð  ×%Ñ%Ó'¨6Ñ1ˆ	ßØ‰GØ×Ñ˜s AÓ& qÕ)×/Ñ/Ó1°VÔ;ô �L‰LÐhÐjuÔvÙð ×0Ñ0°¸dÀKÓPˆGØ!(Ò!4‘g¸{¼?×;hÐ;hÈt×OfÑOfÓOhˆG÷ ˜t×<Ñ<×>Ò>Ü�L‰LÐmÐozÔ{Ùð ×-×-Ð-°h·l±lÐCYÐ[`×6aÒ6aØ"Ÿ,™, }°lÓCˆKÜ—?‘? ;°Ó3ˆDßŸW¯Ü—‘Ð^Ð`kÐz~Ôñ ô —‘Ð\ß-4™\¸)À[ô_áÙr4   c                ó:   <€ V ^8„  d   QhRS[ S[S[3,          RR/# )rW   rU  rY   N)r×   rZ   r   )r\   r±   s   "€r2   r]   rº  8  s#   ø€ ÷ )ñ )±±S¹#°Xµð )À4ñ )r4   c              ƒ  óh  "  € VR,          pV P                  W!4      '       g   R# VR,          VR,          P                  4       VR,          rTpV'       d    VP                  R4      '       g	   RV RV 2MTpV Uu0 uF  qwR	,          kK  	  ppRVR
VR
,          /V P                  V&   VR,          ;'       g    Tp	\	        T;'       g    RVR
,          RV9   d   \
        P                  M&RV9   d   \
        P                  M\
        P                  V P                  W)RW)VR
,          R7      V Uu. uF  qwR,          NK  	  upV Uu. uF  qwR,          NK  	  upVR,          ;'       g    RR7      p
\        P                  RW#4       V P                  V
4      G Rj  x€L
  R# u upi u upi u upi  L5i)z<Convert a fetched email into a MessageEvent and dispatch it.rY  Nr‰  r›  r£  úRe:z
[Subject: z]

rÁ   rŠ  rˆ  z(empty email)r›  rš  r·  )Úchat_idÚ	chat_nameÚ	chat_typeÚuser_idÚ	user_namerŠ  rœ  rž  rŒ  )r*  rŠ  Úmessage_typeÚsourceÚ
media_urlsÚmedia_typesÚreply_to_message_idz[Email] New message from %s: %s)rZ  r`   Ú
startswithrì  r   r   ÚDOCUMENTÚPHOTOÚTEXTÚbuild_sourcero   rí  Úhandle_message)r¥   rU  rY  r‰  r›  r£  r*  ÚattÚkindsrX   Úevents   &&         r2   ri  ÚEmailAdapter._dispatch_message8  sª  é € à˜}Õ-ˆØ×$Ñ$ [×;Ò;ÙØ%-¨iÕ%8¸(À6Õ:J×:PÑ:PÓ:RÐT\Ð]jÕTk�{ˆß4;ÀG×DVÑDVÐW\×D]ÒD]�˜G˜9 E¨$¨Ñ0Ðcgˆñ )4Ó4© �V—�©ˆÐ4Ø-6¸ÀÈxÐXdÕOeÐ,fˆ×Ñ˜[Ñ)Ø˜Õ&×5Ð5¨+ˆÜØ×(Ð(˜°X¸lÕ5KØ1;¸uÔ1Dœ×-Ò-Ð_fÐjoÔ_oÌ+×J[ÒJ[ô  vA÷  vFñ  vFØ×$Ñ$¨[ÐTXÐbmØ08¸Õ0Fð %ó Há/:Ó;©{¨˜FŸ˜©{Ñ;ÑgrÓIsÑgrÐ`cÈl×J[ÐJ[ÑgrÑIsØ (¨Õ 7× ?Ð ?¸4ôAˆô 	�‰Ð5°{ÔLØ×!Ñ! %Ó(×(Ò(ùò 5ùò <ùÒIsñ 	)ùsO   ‚A)F2Á,F2Á:F!Â+F2Â7F2ÃA&F2Ä.F&Ä?F2ÅF+ÅF2Å(2F2ÆF0ÆF2c                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )rW   Úargsr  rY   )rX  rZ   r   )r\   r±   s   "€r2   r]   rº  N  s"   ø€ ÷ ;ñ ;©ð ;¹ð ;É:ñ ;r4   c              ‡  ó  "  €  \        R\        P                  ! 4       P                  ! RV.VO5!  G Rj  x€L
 R7      #  L	  \         d;   p\
        P                  ! T.TOTN5!   \        R\        T4      R7      u Rp?# Rp?ii ; i5i)zPRun a blocking SMTP sender in the executor; wrap its Message-ID in a SendResult.TN©ÚsuccessrŠ  F©rÝ  r  )r   r@  rf  Úrun_in_executorr„   ro   r  rZ   )r¥   r¥  rÚ  r  Úlog_argsrÒ   s   &&&&* r2   Ú	_run_sendÚEmailAdapter._run_sendN  sq   é € ð	;Ü d¼W×=UÒ=UÓ=W×=gÒ=gÐhlÐnpÐ=xÐswÓ=x×7xÔyÐyÑ7xøÜô 	;Ü�LŠL˜Ð/ 8Ð/¨QÔ/Ü e´3°q³6Ô:Õ:ûð	;üsA   ‚B	„1A µ?
¶A ¾B	¿A ÁBÁ/BÁ;BÁ<B	ÂBÂB	Nc                ón   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[S[S[ S[3,          ,          RS[/# )rW   rÅ  ÚcontentÚreply_tor�  rY   ©rZ   r   r×   r   r   )r\   r±   s   "€r2   r]   rº  V  sS   ø€ ÷ ~ñ ~¡#ð ~±ð ~¹xÉ½}ð ~Ñ_gÑhlÑmpÑruÐmuÕhvÕ_wð ~ñ  DNñ ~r4   c              ƒ  ó^   "  € V P                  V P                  WV3RV4      G Rj  x€L
 #  L5i)z)Send an email reply to the given address.z[Email] Send failed to %s: %sN)rá  Ú_send_email)r¥   rÅ  rä  rå  r�  s   &&&&&r2   ÚsendÚEmailAdapter.sendV  s-   é € à—^‘^ D×$4Ñ$4°wÈÐ6RÐTsÐu|Ó}×}Ð}Ñ}ùs   ‚$-¦+§-c                ó    <€ V ^8„  d   QhRS[ /# rò   r  )r\   r±   s   "€r2   r]   rº  Z  s   ø€ ÷ añ a¡Cñ ar4   c                ó‚   € RV P                   9   d$   V P                   P                  R^4      R,          MR;'       g    R# )zODomain for generated Message-IDs; ``localhost`` when EMAIL_ADDRESS lacks ``@``.r4  rJ   rx   r9  )rØ  ÚrsplitrI  s   &r2   Ú_message_id_domainÚEmailAdapter._message_id_domainZ  s4   € à47¸4¿=¹=Ô4H�—‘×$Ñ$ S¨!Ó,¨RÖ0Èb×`Ð`ÐU`Ð`r4   Úattach_empty_bodyc                ób   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[RS[S[S[ S[ 3,          /# )rW   Úto_addrr›  Úreply_to_msg_idrð  rY   )rZ   r   r=   rX  r   )r\   r±   s   "€r2   r]   rº  ^  sC   ø€ ÷ $ñ $¡#ð $©Sð $Á8ÉCÅ=ð $Ù&*ð$Ù7<¹]ÉCÑQTÐ=TÕ7Uñ$r4   c               óD  € \        4       V P                  P                  V/ 4      reVP                  RR4      pVP                  R4      '       g   RV 2pT;'       g    VP                  R4      pV'       d	   RV3RV33MRp	R\        P
                  ! 4       P                  R	,           R
V P                  4        R2p
RV P                  3RV3RV3.V	OR\        RR7      3NRV
3N F	  w  r¼WÅV&   K  	  V'       g	   V'       d   VP                  \        VRR4      4       WZV3# )zDBuild a threaded reply skeleton. Returns ``(msg, msg_id, subject)``.r‰  zHermes AgentrÄ  zRe: rŠ  r�  Ú
Referencesz<hermes-:Né   Nr4  rN   r†  ÚTor‡  r�  T©Ú	localtimer‹  r*   r@   r¨   )r   rì  rq   rÏ  ÚuuidÚuuid4Úhexrî  rØ  r
   r³  r   )r¥   rò  r›  ró  rð  r  r½   r‰  Úoriginal_msg_idÚ	threadingÚmsg_idr¿  ri   s   &&&&$        r2   Ú
_new_replyÚEmailAdapter._new_reply^  s0  € ô !“? D×$8Ñ$8×$<Ñ$<¸WÀbÓ$IˆSØ—'‘'˜) ^Ó4ˆØ×!Ñ! %×(Ò(Ø˜W˜IÐ&ˆGØ)×BÐB¨S¯W©W°\Ó-Bˆß[j�m _Ð5¸ÀoÐ7VÑWÐprˆ	ØœDŸJšJ›L×,Ñ,¨SÕ1Ð2°!°D×4KÑ4KÓ4MÐ3NÈaÐPˆØ" D§M¡MÐ2°T¸7°OÀiÐQXÐEYð YÐ\eð YØ"¤J¸Ô$>Ð?ðYØBNÐPVÐAWóY‰JˆCà�‹HñY÷ ×$Ø�J‰J”x  g¨wÓ7Ô8Ø˜GÐ#Ð#r4   c                ó$   <€ V ^8„  d   QhRS[ RR/# )rW   r  rY   Nr   )r\   r±   s   "€r2   r]   rº  o  s   ø€ ÷ 
ñ 
™mð 
°ñ 
r4   c                ój  € V P                  4       p VP                  V P                  V P                  4       VP	                  V4        VP                  4        R#   \         d    TP                  4         R# i ; i   TP                  4        i   \         d    TP                  4         i i ; i; i)zGLogin, send, and always release the SMTP connection (quit, else close).N)r  r  rØ  rÙ  Úsend_messager5  r„   r–   )r¥   r  rÅ   s   && r2   Ú
_smtp_sendÚEmailAdapter._smtp_sendo  s…   € à×!Ñ!Ó#ˆð	Ø�J‰J�t—}‘} d§n¡nÔ5Ø×Ñ˜cÔ"ðØ—	‘	–øÜô Ø—
‘
—ðûðØ—	‘	•øÜô Ø—
‘
–ðýsA   ’7A> Á
A ÁA;Á:A;Á>B2Â BÂB2ÂB/Â,B2Â.B/Â/B2c                óB   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[ /# )rW   rò  r›  ró  rY   ©rZ   r   )r\   r±   s   "€r2   r]   rº  {  s.   ø€ ÷ ñ ¡3ð ©cð ÁHÉSÅMð Ñ]`ñ r4   c                ó‚   € V P                  WVRR7      w  rEpV P                  V4       \        P                  RW4       V# )z0Send an email via SMTP. Runs in executor thread.T)rð  z&[Email] Sent reply to %s (subject: %s))r   r  ro   rí  )r¥   rò  r›  ró  r  rÿ  r‰  s   &&&&   r2   rè  ÚEmailAdapter._send_email{  s<   € à#Ÿ™¨w¸oÐae˜ÓfÑˆ�WØ�‰˜ÔÜ�‰Ð<¸gÔOØˆr4   ró  c                ót   <€ V ^8„  d   QhRS[ RS[ RS[S[S[S[ 3,          ,          RS[RS[S[ ,          RS[ /# )rW   rò  r›  ÚfilesÚlenientró  rY   )rZ   r9   rX  r   r=   r   )r\   r±   s   "€r2   r]   rº  ‚  sM   ø€ ÷ ñ ©ð ±3ð ¹tÁEÉ$ÑPSÈ)ÕDTÕ?Uð Ñcgð Ù*2±3­-ðÙCFñr4   c               óò   € V P                  WV4      w  rgpV F  w  rš \        WiV
4       K  	  V P                  V4       V#   \         d+   pT'       g   h \        P	                  RY›4        Rp?KY  Rp?ii ; i)z±Send a reply with attachments; *lenient* logs-and-skips unattachable files instead of raising.
An explicit *reply_to_msg_id* threads the mail like ``_send_email`` does (#10131).z[Email] Failed to attach %s: %sN)r   rµ  r„   ro   rp   r  )r¥   rò  r›  r  r  ró  r  rÿ  rl   rœ  rX   rÒ   s   &&&&$$      r2   Ú_send_with_filesÚEmailAdapter._send_with_files‚  ss   € ð Ÿ™¨¸ÓH‰ˆ�QÛ‰JˆDðKÜ˜S¨Ö-ñ  ð 	�‰˜ÔØˆøô ô KßØÜ—‘Ð@À$×JÒJûðKús   žAÁA6ÁA1Á1A6c                ó„   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[S[ ,          RS[S[S[ S[3,          ,          RS[/# )rW   rÅ  Ú	image_urlÚcaptionrå  r�  rY   ræ  )r\   r±   s   "€r2   r]   rº  ‘  sZ   ø€ ÷ dñ d©ð d¹ð dÁhÉsÅmð dÙ#+©C¥=ðdÙCKÉDÑQTÑVYÐQYÍNÕC[ðdÙgqñdr4   c              ƒ  ó|   "  € T P                  Y;'       g    R RV 2P                  4       V4      G Rj  x€L
 #  L5i)zASend an image URL as part of an email body (``metadata`` unused).rJ   z	

Image: N)ré  r`   )r¥   rÅ  r  r  rå  r�  s   &&&&&&r2   Ú
send_imageÚEmailAdapter.send_image‘  s9   é € ð —Y‘Y˜w¯=¨=°b¨/¸ÀYÀKÐ(P×(VÑ(VÓ(XÐZbÓc×cÐcÑcùs   ‚3<µ:¶<c          
      ó„   <€ V ^8„  d   QhRS[ RS[S[S[ S[ 3,          ,          RS[S[S[ S[3,          ,          RS[RS[/# )rW   rÅ  Úimagesr�  Úhuman_delayrY   )rZ   r9   rX  r   r×   r   r‹   r   )r\   r±   s   "€r2   r]   rº  –  sM   ø€ ÷ ?ñ ?±#ð ?¹tÁEÉ#ÉsÈ(ÅOÕ?Tð ?Ù-5±d¹3Á¸8µnÕ-Eð?Ù[`ð?Ùkuñ?r4   c              ƒ  ó&  <"  € V'       g   \        RRR7      # ^ RIHp . . rvV Fª  w  r‰V	'       d   VP                  V	4       VP	                  R4      '       g   VP                  \        RVR7      4       KS  \        V! VR,          4      ;p
4      P                  4       '       d   VP                  V
4       K”  \        P                  R	V
4       K¬  	  V'       g   V'       g   \        RR
R7      #  \        P                  ! 4       P                  RV P                  VRP                  V4      V4      G Rj  x€L
 p\        RTR7      #  L  \         d<   p\        P!                  RTRR7       \"        ST `I  YY44      G Rj  x€L 
 u Rp?# Rp?ii ; i5i)z~One email per batch: local files attached, URL images linked in the body (no remote download); base-class fallback on failure.Fzno images to sendrÞ  )Úunquotezfile://zplatform.email.image_line)Úurl:é   NNz"[Email] Skipping missing image: %szno valid images in batchNrO   z1[Email] Multi-image send failed, falling back: %sT)Úexc_inforÜ  )r   Úurllib.parser  rP  rÏ  r   r   Úexistsro   rp   r@  rf  rß  Ú_send_email_with_attachmentsr  r„   r  rÕ  Úsend_multiple_images)r¥   rÅ  r  r�  r  Ú_unquoteÚ
body_partsÚlocal_pathsr  Úalt_textÚ
local_pathrŠ  rÒ   rð  s   &&&&&        €r2   r"  Ú!EmailAdapter.send_multiple_images–  sl  øé € ÷ Ü eÐ3FÔGÐGÝ4Ø"$ b�KÛ#)ÑˆIßØ×!Ñ! (Ô+Ø×'Ñ'¨	×2Ò2Ø×!Ñ!¤!Ð$?ÀYÔ"OÖPÜ¡H¨Y°r­]Ó$;Ð;�jÓ<×CÑC×EÒEØ×"Ñ" :Ö.ä—‘ÐCÀZÖPñ $*÷ §:Ü eÐ3MÔNÐNð	^Ü&×7Ò7Ó9×IÑIÈ$ÐPT×PqÑPqÐszð  }C÷  }Hñ  }Hð  ISó  }Tð  Vaó   b÷  bˆJô  $°:Ô>Ð>ñ	 bøÜô 	^Ü�L‰LÐLÈaÐZ^ˆLÔ_Ü™Ñ5°gÀxÓ]×]Ð]Õ]ûð	^üsh   ƒAFÁB FÃFÃ"FÃ0AE Ä4EÄ5E Ä9FÅE ÅFÅ+F	Å>FÅ?F	ÆFÆFÆ	FÆFc                óB   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[ /# )rW   rò  r›  Ú
file_pathsrY   )rZ   r9   )r\   r±   s   "€r2   r]   rº  ¯  s1   ø€ ÷ ñ ±Cð ¹sð ÑPTÑUXÕPYð Ñ^añ r4   c                óÔ   € T P                  YV Uu. uF#  p\        V4      \        V4      P                  3NK%  	  upRR7      p\        P	                  RV\        V4      4       V# u upi )zWSend an email with multiple file attachments via SMTP (unattachable files are skipped).T)r  z4[Email] Sent multi-attachment email to %s (%d files))r  r   rX   ro   rí  r;  )r¥   rò  r›  r*  r´  rÿ  s   &&&&  r2   r!  Ú)EmailAdapter._send_email_with_attachments¯  sa   € à×&Ñ& wÑXbÓ6cÑXbÐST¼¸Q»ÄÀaÃÇÁÓ7NÑXbÑ6cÐmqÐ&ÓrˆÜ�‰ÐJÈGÔUXÐYcÓUdÔeØˆùò 7ds   ‘)A%c                ón   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[S[ ,          RS[S[ ,          RS[/# )rW   rÅ  Ú	file_pathr  Ú	file_namerå  rY   )rZ   r   r   )r\   r±   s   "€r2   r]   rº  µ  sP   ø€ ÷ Hñ H©3ð H¹3ð HÉÑRUÍð HÙ'/±¥}ðHÙGOÑPSÅ}ðHÙjtñHr4   c              ‹  ór   "  € T P                  V P                  Y;'       g    RW$V3R4      G Rj  x€L
 #  L5i)z#Send a file as an email attachment.rJ   z [Email] Send document failed: %sN)rá  Ú_send_email_with_attachment)r¥   rÅ  r.  r  r/  rå  rÀ   s   &&&&&&,r2   Úsend_documentÚEmailAdapter.send_documentµ  sE   é € ð —^‘^ D×$DÑ$DÀw×P]ÐP]Ð[]Ð_hÐu}ÐF~Ø$FóH÷ Hð 	Hñ Hùs   ‚.7°5±7c                ó^   <€ V ^8„  d   QhRS[ RS[ RS[ RS[S[ ,          RS[S[ ,          RS[ /# )rW   rò  r›  r.  r/  ró  rY   r  )r\   r±   s   "€r2   r]   rº  »  sL   ø€ ÷ Fñ F±3ð F¹cð FÉcð FÑ^fÑgjÕ^kð FÙ5=¹cµ]ðFÙNQñFr4   c                ó~   € T P                  Y\        V4      T;'       g    \        V4      P                  3.RVR7      # )zNSend an email with a single file attachment via SMTP (raises if unattachable).F)r  ró  )r  r   rX   )r¥   rò  r›  r.  r/  ró  s   &&&&&&r2   r1  Ú(EmailAdapter._send_email_with_attachment»  sI   € ð ×$Ñ$ W´d¸9³oÀy×GhÐGhÔTXÐYbÓTc×ThÑThÐ5iÐ4jÐtyØ5Dð %ó Fð 	Fr4   c                ó<   <€ V ^8„  d   QhRS[ RS[S[ S[3,          /# )rW   rÅ  rY   )rZ   r×   r   )r\   r±   s   "€r2   r]   rº  Á  s'   ø€ ÷ Hñ H©3ð H±4¹¹S¸µ>ñ Hr4   c              ƒ  ór   "  € RVRRRVRV P                   P                  V/ 4      P                  RR4      /# 5i)z'Return basic info about the email chat.rX   rÁ   r·  rÅ  r‰  rJ   )rì  rq   )r¥   rÅ  s   &&r2   Úget_chat_infoÚEmailAdapter.get_chat_infoÁ  sR   é € à˜ ¨¨y¸'À9Èd×NbÑNb×NfÑNfÐgnÐprÓNs×NwÑNwð  yBð  DFó  OGð  Hð  	Hùs   ‚57c                óH   <€ V ^8„  d   Qh/ S[ S[S[3,          ;R&   S[;R&   # )rW   r)  r<  )r×   rZ   ræ  )r\   r±   s   "€r2   r]   rº  Â  s'   ø‡ ‚ ñ ™c¡3˜h�Ñ,ñ ñ Ñ$ò r4   )rØ  rå  rÚ  rÛ  rÜ  rÝ  rë  rê  rÙ  râ  ré  rä  r?  rç  rè  rã  rÞ  rß  rà  rá  rì  )NNr;   )NNN)Ng        )2rª   r«   r¬   r­   Ú__doc__Úserial_receive_loopÚsplits_long_messagesr)  ræ  r<  rÖ  rú  r  r   r  r  r  r/  r7  r”   rJ  rB  rN  rp  rh  r’  ry  rz  Ústaticmethodr¦  r®  rZ  ri  rá  ré  rî  r   r  rè  r  r  r"  r!  r2  r1  r9  Ú__annotate_func__r®   r¯   Ú__classcell__)rð  r±   s   @@r2   r·  r·  Â  sÐ  ù‡ € ÙEØÐàÐð
 +-Ðñ  #›uÐ÷$Ió $I÷L	Uð 	U÷ð ð ñó ð÷ 
qð 
q÷ð ÷uð u÷2cð cð&°E÷ ò ÷&-ð -÷	5ð 	5÷-ð -÷8Oð O÷4ð 4÷lwð w÷"_ð _÷ð ð ÷Uó ðU÷]ð ]÷
.ð .÷`)ð )÷,;ð ;÷~ò ~÷að añ$Ø-2÷$ó $÷"
ð 
÷ò ðØ:>÷ò ÷dò d÷
?õ ?÷2ð ÷Hò H÷Fò F÷Hð H÷ … r4   r·  Ú	thread_idÚmedia_filesÚforce_documentc          	   ƒ  óâ  "  € \        V R/ 4      ;'       g    / pVP                  R4      ;'       g    \        RR4      \        RR4      r‡VP                  R4      ;'       g    \        RR4      \        RR	4      r©\	        \        R
R4      ;'       g    VP                  R4      V
R8X  d   RMRR7      p\        R\        VP                  R4      RR7      4      p\        WxV	.4      '       g   \        R4      #  \        VRR4      pRV3RV3R\        R4      3R\        RR7      33 F	  w  rïWýV&   K  	  \        WšV\        WÉ4      \        P                  \        P                   4      pVP#                  Wx4       VP%                  V4       VP'                  4        RRRRRV/#   \(         dA   p ^ R IHp T! R!T 24      u R"p?#   \(         d    \        R!T 24      u u R"p?# i ; iR"p?ii ; i5i)#zQOut-of-process Email delivery via SMTP (one-shot); standalone_sender_fn contract.rÀ  rÕ   rø   rJ   rù   rÉ  rû   rÊ  rË  rÌ  rÍ  rÎ  r&   r)   re   rÏ  rÐ  TzNEmail not configured (EMAIL_ADDRESS, EMAIL_PASSWORD, EMAIL_SMTP_HOST required)r*   r@   r†  r÷  r‡  z!platform.email.standalone_subjectr�  rø  rÝ  ÚplatformÚemailrÅ  )Ú_errorzEmail send failed: N)r¹   rq   r_   ra   rr   rg   r   rü   r#   r   r   r
   rÆ   r{   rÂ   rÃ   r  r  r  r5  r„   Útools.send_message_toolrH  )ÚpconfigrÅ  r  rB  rC  rD  rÀ  rÕ   ÚpasswordrÉ  Ú	smtp_portrÍ  rÐ  r  r¿  ri   ÚserverrÒ   Ú_es   &&&$$$             r2   Ú_standalone_sendrO  Ç  s  é € ä�G˜W bÓ)×/Ð/¨R€EØŸ	™	 )Ó,×PÐP´¸OÈRÓ0PÔR]Ð^nÐprÓRsˆXØ Ÿ9™9 [Ó1×WÐW´[ÐARÐTVÓ5WÔYeÐfwÐy|ÓY}ˆyÜ'¬Ð4IÈ2Ó(N×(lÐ(lÐRW×R[ÑR[Ð\kÓRlð  @Ið  MPô  @PÑv{ð  V`ô  a€MÜ#Ð$;¼_ÈUÏYÉYÐWhÓMiÐswÔ=xÓy€OÜ� 9Ð-×.Ò.ÜÐjÓkÐkð9Ü�w ¨Ó1ˆØ" GÐ,¨t°W¨oÀ	Ì1ÐMpÓKqÐ?rÐu{ô  ~Hð  SWô  ~Xð  uYó  Z‰JˆCØ�‹Hñ Zä˜I°-ÄÈoÓAiÔkr×kwÑkwô  zA÷  zJñ  zJó  KˆØ�‰�WÔ'Ø×Ñ˜CÔ Ø�‰ŒØ˜4 ¨W°iÀÐIÐIøÜô 9ð	9Ý<ÙÐ+¨A¨3Ð/Ó0Õ0øÜô 	9ÜÐ 3°A°3Ð7Ó8×8ð	9þð	9üs`   ‚/G/²CG/Ã8B(F! Æ G/Æ!G,Æ-GÆ=G,Æ>G/ÇG$ÇG'ÇG,ÇG/Ç#G$Ç$G'Ç'G,Ç,G/c                ó$   € V ^8„  d   QhR\         /# rò   r<   )r\   s   "r2   r]   r]   á  s   € ÷ Lñ LœTñ Lr4   c                óÎ   € \        V R/ 4      ;'       g    / P                  R4      '       d   R# ^ RIHp \	        VP                  R4      ;'       g    RP                  4       4      # )zPConnected when an address is configured (PlatformConfig.extra or EMAIL_ADDRESS).rÀ  rÕ   TNrø   rJ   )r¹   rq   Úhermes_cli.gatewayÚgatewayr=   Úget_env_valuer`   )r¹  Úgateway_mods   & r2   Ú_is_connectedrV  á  sQ   € ä�˜ Ó$×*Ð*¨×/Ñ/°	×:Ò:ÙÝ,Ü�×*Ñ*¨?Ó;×AÐA¸r×HÑHÓJÓKÐKr4   uv  You are communicating via email. Write clear, well-structured responses suitable for email. Use plain text formatting (no markdown). Keep responses concise but complete. You can send file attachments â€” include MEDIA:/absolute/path/to/file in your response. The subject line is preserved for threading. Do not include greetings or sign-offs unless contextually appropriate.z6^\s*[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\s*$c                ó   € V ^8„  d   QhRR/# ró  r¨   )r\   s   "r2   r]   r]   õ  s   € ÷ ñ �Tñ r4   c           	     óV  € ^RI Hp V P                  ! R%/ R\        \        4      bR\        RR7      bRRbRR	bR
\        bR\        bR\        bRRbRRbRR&bRR&bR. R'ObRRbRRbR\        bRRbRRbRRbRRbR\        bR R!bR"VP                  bR#VP                  bVP                  B  R$# )(u:   Plugin entry point â€” called by the Hermes plugin system.)Úgateway_envÚtarget_ref_syntax_fnÚstandalone_sendT)Útext_directrX   rG  r  ÚEmailÚadapter_factoryÚcheck_fnÚis_connectedÚdashboard_descriptionz,Talk to Hermes through an IMAP/SMTP mailbox.Údocs_urlz@https://hermes-agent.nousresearch.com/docs/user-guide/messaging/Údashboard_env_varsÚdashboard_required_envÚrequired_envÚinstall_hintu@   Email uses the Python stdlib (smtplib/imaplib) â€” no extra depsÚcron_deliver_env_varÚEMAIL_HOME_ADDRESSÚstandalone_sender_fnÚmax_message_lengthr?   Úpii_safeÚemojiu   ðŸ“§Úallow_update_commandÚplatform_hintÚdisplay_tierÚminimalÚenv_overridesÚenv_enable_credentialsNr¨   r÷   )rø   rù   rû   )rJ   rY  Úregister_platformr%   Ú_SEND_TARGET_REr$   r·  rý   rV  rO  Ú_PLATFORM_HINTÚENV_OVERRIDESÚENV_ENABLE_CREDENTIALSÚAUTHZ)r½   rY  s   & r2   Úregisterry  õ  s$  € åØ×Òò Ü2´?ÔCðä,¸Õ>ðñ ðñ $ðõ 6Bðõ Meðõ tAðñ Mð	ñ
 Tðñ eðñ  iðó Lðñ Xðñ oCðõ Zjðñ "ðñ -1ðñ 9?ðñ VZðõ %ðñ ðð "×/Ò/ðð  +×AÒAÀ[×EVÑEVôr4   )Únoreplyzno-replyÚno_replyÚ
donotreplyzdo-not-replyzmailer-daemonÚ
postmasterÚbounceznotifications@z
automated@zauto-confirmz
auto-replyÚ
automailer>   Ú1ÚyesÚtrue>   ú.gifú.jpgú.pngú.jpegú.webpi   )F)r&   r;   )‚r<  r@  rG  r  Ú
contextlibr   r   r€   ÚloggingÚosr:  rÂ   rŒ   r'   rú  Úemail.headerr   Úemail.mime.multipartr   Úemail.mime.textr   Úemail.mime.baser   Úemail.parserr	   Úemail.utilsr
   r   r   Úpathlibr   Útypingr   r   r   r   r   r   Úagent.async_utilsr   Ú
agent.i18nr   Úgateway.platforms.baser   r   r   r   Úgateway.platforms.helpersr   Úgateway.platforms.eventr   r   Úgateway.configr   r   Úutilsr   Úgateway.platforms._sharedr    r_   r!   r"   r#   Úgateway.platforms.send_targetsr$   r%   Ú	getLoggerrª   ro   rn   rã   rä   ÚMAX_MESSAGE_LENGTHr  r¢  r¢  r  ÚcompileÚ
IGNORECASEr.  r>  rH  r<  rx  r  rw  r�  r‹  rŽ  r�  Ú_OPT_OUT_HINTrº  r>  Ú_QUOTEDrZ  ra   rg   rr   r{   r†   rŸ   rÃ   r¡   r  r³   rÆ   rÓ   ræ   rð   rý   r  r  r"  r+  r(  rD  r@  rV  r]  ra  ri  r”  r©  rµ  r·  rO  rV  ru  rt  ry  r¨   r4   r2   Ú<module>r¢     sá  ðñsó Û ß /Û Û Û 	Û 	Û Û Û 
Û Ý &Ý .Ý $Ý $Ý *ß -Ý Ý ß =× =å 6Ý ÷ó õ 2ß =ß 3Ý !ß yÓ yß Và	×	Ò	˜8Ó	$€à˜E 5¨%°¸UÀJÐPZÐ\cÐelÐntÐv}Ð~Ð ðkÐ à&Ñ(CØ"Ñ$SØ0Ñ2CÐEWÑYjðlÐ ð Ð ØÐ Ú
€Ú8€ð # G¨Y¸ÀÈgÐW`ÐbiØ&¨	°8¸WØ˜i¨°	Ð;KÈWðVÐ ð �zŠz˜,¨¯©Ó6¸Ð=ÀÇ
Â
È;ÐXZ×XeÑXeÓ@fÐhlÐ?mØ�zŠz˜' 2§=¡=Ó1°4Ð8¸2¿:º:ÀjÓ;QÐSUÐ:VÐY[×YcÒYcÐdmÓYnÐpsÐXtØ�zŠz˜(Ó# SÐ)¨B¯JªJ°wÓ,?ÀÐ+EÈÏ
Ê
ÐSZÓH[Ð]`ÐGaÐdf×dnÒdnÐoxÓdyð  |Bð  dCðD€
ð Ÿ*š*Ð%@ÓAÐ Ø�jŠj˜Ó'€ð €ð &Ð à<¸S¿X¹XÑElÑYkÓElÓ=lÐ<mð n
Ø
# aÕ
'Ð	(¨ð,ð ð
 —*’*ÐBÀBÇMÁMÓR€Ø<Ð ØQÐ ØdÐ Ø€ð Ð[Ð^kÕkØÐ uð€ð
 Ø"/õ0Ð ð €Ø—
’
ÐiÐjqÐirð s#Ø#* )¨9ð6Ø79·}±}óF€õO÷
m÷
/õ,õ÷"hô"`�—‘ô `ô
h�G×$Ñ$ô hõ
õDõ4mõOõDõ7õ$
qõõPõõ'õ(õAõDTõ6õ
Tõ.=÷bõ2ôAHÐ&ô AHðJ9À4ð 9ÐUYð 9Ðjoô 9õ4Lð\ð ð —*’*ÐVÓW€÷r4   