+
    jHàjwC  ã                   ó–   € R t ^ RIt^ RIHt ^ RIHt ]R 4       tR tR tR t	R t
R	 tR
 t/ t]R 4       tR tR tR tR tR tR tR# )zQReceipt-only adapter ingress: the authority, not an HTTP/WS task, owns execution.N)Úasynccontextmanager)ÚRuntimeStoreErrorc           
     óØ  "  € ^ RI Hp ^ RIHp ^ RIHp \        V P                  RR4      p\        VRR4      f   \        R4      hVP                  W P                  4      w  rg\        VR/ 4      P                  V4      pV'       d   Vf   \        R	4      hVP                  p	V'       d9   VP                  W—R
7       V	P                  '       d   VP                  V	4      MTp
M5VP!                  W˜4      p
V
f!   \#        V\        V	RR4      4       RV	n        Tp
W‰n        V! WZ4      pVe   \        VRR4      '       d"   \#        T\        V	RR4      ;'       g    T4       Vf   \        R	4      hV! WQW‡4      ;_uu_ 4        V! V
4      ;_uu_4       GRj  x€L
  V5x € RRR4      GRj  x€L
  RRR4       R#  L# L  + GRj  x€L 
 '       g   i     L'; i  + '       g   i     R# ; i5i)é    )Ú_async_profile_runtime_scope)Únative_callback©Úauthority_for_homeÚ__self__NÚsession_authorityÚ	not_foundÚ_native_transport_homesÚprofile_mismatch)Útransport_profileÚ_rejected_route_profileTÚretiringFÚprofile)Úgateway.runr   Úgateway.session_ingress_contextr   Úgateway.session_authoritiesr	   ÚgetattrÚ_message_handlerr   Ú_owning_profileÚplatformÚgetÚsourceÚ_canonicalizer   Ú _resolve_profile_home_for_sourceÚ_admit_primary_sourceÚ_refuse_parkedÚprofile_route_rejectedÚ_authorization_profile_home)ÚadapterÚeventr   r   r	   ÚrunnerÚ
registeredr   Úhomer   Úruntime_homeÚ	authoritys   &&          ÚF/home/ubuntu/.hermes/hermes-agent/gateway/platforms/webhook_ingress.pyÚproducer_scoper*      s�  é € å8Ý?å>Ü�W×-Ñ-¨z¸4Ó@€FÜˆvÐ*¨DÓ1Ò9Ü Ó,Ð,Ø ×0Ñ0°×:JÑ:JÓKÑ€JÜ�6Ð4°bÓ9×=Ñ=¸gÓF€Dß˜šÜÐ 2Ó3Ð3Ø�\‰\€F÷ Ø×Ñ˜VÐÔ?ØJPÏ.Ï.È.�v×>Ñ>¸vÔFÐ^b‰à×3Ñ3°FÓAˆØÒÜ˜6¤7¨6Ð3LÈdÓ#SÔTØ,0ˆFÔ)ØˆLØ)-Ô&ñ # 6Ó8€IØÒœG I¨z¸5×AÒAÜ�vœw v¨y¸$Ó?×JÐJÀ7ÔKØÒÜÐ 2Ó3Ð3Ù	˜¨×	6Õ	6Ù/°×=×=Õ=Ø‹O÷ >×=÷ 
7Ñ	6ß=×=×=Ô=ú÷ 
7×	6Ð	6üsy   ‚B'G*Â*B+G*Å'G*Å=GÆF6ÆGÆF:	ÆGÆ'F8Æ(GÆ,
G*Æ6GÆ8GÆ:GÇ GÇ
GÇGÇGÇG'	Ç!	G*c                óJ   € ^ RI Hp V! W4      '       d   ^ RIHp V! V4      hR# )aD  A delivery routed to a parked profile is retryable, never refused for good: a rescan serves the
profile again, so it is ``runtime_draining`` (a webhook answers 503; relay acknowledges and tells
the sender, ``parked_route_refusal``), not the permanent ``profile_mismatch`` of a route to a
profile this gateway does not serve.©Úprofile_parked)ÚParkedProfileRefusalN)Úgateway.run_runtimer-   Úgateway.parked_route_refusalr.   )r$   r   r-   r.   s   &&  r)   r   r   .   s%   € õ
 3Ù�f×&Ò&ÝEÙ" 7Ó+Ð+ñ 'ó    c                óþ   € ^ RI Hp \        W4      '       d   RV R2pM0\        WW#4      pVf   R# VR8X  d   VP	                  RR/RR	7      # R
p^ RIHp VP	                  RV/VP                  VP                  R7      # )a�  A 503 for a webhook whose profile is not served right now, else None: a ``/p/<profile>/``
prefix that is parked or has no serving authority here, or a coalesced route that
``profile_routes`` sends to a profile admission would refuse (a coalesced delivery is acknowledged
before admission applies that route). A parked target is retryable (``Retry-After``); any other
rejected target gets the answer the immediate route gives when admission refuses it.
``admission_source`` returns the ``SessionSource`` admission builds for this delivery
(``WebhookAdapter._admission_source``), so ``profile_routes`` match here exactly as there. Answered
before the delivery id is recorded: coalesced, ``deliver_only`` and ``cron_job`` routes act before
(or without) an admission, so the in-memory id is their only replay guard, and a recorded id would
answer the provider's retry as a duplicate once the profile is served again.)ÚwebzProfile z) is not being served; retry this deliveryNÚrefusedÚerrorz*Admission unavailable; retry this deliveryi÷  )ÚstatuszEThe routed profile is not being served right now; retry this delivery)ÚParkedRouteRefused)r6   Úheaders)	Úaiohttpr3   Ú_prefix_not_servedÚ_coalesced_route_refusalÚjson_responser0   r7   r6   r8   )r$   r   Úroute_configÚadmission_sourcer3   r5   Úrefusalr7   s   &&&&    r)   Úparked_profile_refusalr@   9   s�   € õ Ü˜&×*Ò*Ø˜7˜)Ð#LÐM‰ä*¨6¸LÓ[ˆØŠ?ÙØ�iÔà×$Ñ$ gÐ/[Ð%\ÐehÐ$ÓiÐiØWˆÝ?Ø×Ñ˜g uÐ-Ð6H×6OÑ6OÐYk×YsÑYsÐÓtÐtr1   c                óÊ   € ^ RI Hp V! W4      '       d   R# V'       d   \        V RR4      f   R# ^ RIHp ^ RIHp V! W! V4      4      pVRJ ;'       g    \        VRR4      RJ # )	zÃParked, or on disk with no serving authority here (its own gateway still runs, or it is not
picked up yet): the URL prefix resolves against the profiles on disk, the registry says what is
served.r,   TÚsession_authoritiesNFr   )Úget_profile_dirr   )r/   r-   r   r   r	   Úhermes_cli.profilesrC   )r$   r   r-   r	   rC   r(   s   &&    r)   r:   r:   S   sb   € õ 3Ù�f×&Ò&Ùß”g˜fÐ&;¸TÓBÒJÙÝ>Ý3Ù" 6¨?¸7Ó+CÓD€IØ˜Ð×MÐM¤¨	°:¸uÓ EÈÐ MÐMr1   c                ód  € V'       g&   \        VP                  R4      \        4      '       g   R# ^ RIHp V! 4       p\        VRR4      '       d(   \        VRR4      pV'       d   V! W4      '       d   R# R# VP                  pV'       g   R# V! W4      '       d   R# \        W4      '       d   R# R# )	a(  How admission would refuse a coalesced bare-route delivery that ``profile_routes`` sends away:
``'parked'`` (retryable), ``'refused'`` (a profile neither served here nor parked: standalone,
unknown, or without a live authority), else None. Reads the profile the admission's own source
resolved (``build_source`` asks ``GatewayRunner._profile_name_for_source`` on the same chat_id,
user_id and names), so this edge and admission give one answer: an explicit ``/p/<profile>/``
wins over ``profile_routes`` there, and routes apply only under multiplexing.ÚcoalesceNr,   r    Fr   Úparkedr4   )Ú
isinstancer   Údictr/   r-   r   r   r:   )r$   r   r=   r>   r-   r   ÚrejectedÚrouteds   &&&&    r)   r;   r;   b   s–   € ÷ ”j ×!1Ñ!1°*Ó!=¼t×DÒDÙÝ2ÙÓ€FÜˆvÐ/°×7Ò7ô ˜6Ð#<¸dÓCˆß#©°v×(HÒ(HˆxÐWÈiÐWØ�^‰^€FßÙÙ�f×%Ò%ÙÜ*¨6×:Ò:ˆ9ÐDÀÐDr1   c              ƒ  óî  "  € \        W4      ;_uu_4       GRj  x€L
 p^ RIHp ^ RIHp ^ RIHp V P                  VP                  8H  pRV3 Uu. uF  qu! V4      '       g   K  VNK  	  ppV'       g4   V'       g,   VP                  V4      G Rj  x€L
 uuRRR4      GRj  x€L
  # ^ RI
Hp	 \        W!4      G Rj  x€L
 w  r«V	P                  R4      p \        VP                  W±P                   34      ;_uu_4       GRj  x€L
  V
\#        W+VP                   4      3p\%        W!WhV4      G Rj  x€L
 uuRRR4      GRj  x€L
  V	P'                  V4       uuRRR4      GRj  x€L
  #  ELNu upi  Lß LÐ L¸ Lt LI L: L  + GRj  x€L 
 '       g   i     M…; i  \(        \*        P,                  3 de   p\/        T\*        P,                  4      '       d   T	P1                  4       '       g)   \*        P2                  ! \5        Y*4      4      G Rj  x€L 
  h Rp?ii ; i T	P'                  T4       M  T	P'                  T4       i ; iRRR4      GRj  x€L 
  R#   + GRj  x€L 
 '       g   i     R# ; i5i)a  Commit a producer delivery; ``None`` when a plugin skipped or consumed it.

``pre_gateway_dispatch`` and ``post_gateway_admission`` (#129958) fire once per admission, like
``GatewayInboundMixin._handle_message``: before the commit (a skipped or consumed delivery is
never admitted, a rewrite is what gets committed; a consumer's reply rides
``event._consumer_reply`` for the caller's own reply leg), and never for a replay of an
already-committed delivery (provider retry, relay re-send) nor at execution (PLG-5).N)ÚPlatform©ÚPOST_ADMISSION_HOOK)Úhas_hookÚpre_gateway_dispatch)Únative_write_startedF)r*   Úgateway.configrM   Úgateway.run_inbound_consumerrO   Úhermes_cli.lifecyclerP   r   ÚWEBHOOKÚadmit_nativeÚgateway.session_authorityrR   Ú	_preparedÚsetÚ_delivery_turnÚ
profile_idÚ
message_idÚ
_committedÚ_admit_onceÚresetÚ	ExceptionÚasyncioÚCancelledErrorrH   r   ÚshieldÚ_release_preparation)r"   r#   r(   rM   rO   rP   ÚwebhookÚnameÚhooksrR   ÚpayloadÚ	principalÚwritingÚ	committedÚexcs   &&             r)   Úadmit_producerrn   z   sã  é € ô ˜g×-×-Ô-°Ý+ÝDÝ1Ø×"Ñ" h×&6Ñ&6Ñ6ˆØ#9Ð;NÑ"OÓbÑ"O˜$ÐS[Ð\`×Sa—�Ñ"OˆÐbßŸ5Ø"×/Ñ/°Ó6×6÷ .×-Ò-õ 	CÜ#,¨YÓ#>×>ÑˆØ&×*Ñ*¨5Ó1ˆð	0ô & y×';Ñ';¸Y×HXÑHXÐ&Y×Z×ZÕZØ#¤Z°	Àe×FVÑFVÓ%WÐW�	Ü(¨¸7È9ÓU×U÷ [×ZÑZð !×&Ñ& wÔ/÷3 .×-Õ-ùò
 cá6ñ .ñ ?ñ
 [áUñ [ñ .÷ [×Z×ZÐZûô œ7×1Ñ1Ð2ô 	ô ˜s¤G×$:Ñ$:×;Ò;Ð@T×@XÑ@X×@ZÒ@ZÜ—n’nÔ%9¸)Ó%MÓN×NÑNØûð	úð [ð !×&Ñ& wÕ/øÐ ×&Ñ& wÕ/ú÷3 .×-×-×-×-Ô-üsj  ‚I5šE(›I5ž2IÁE+Á$E+Á*IÁ<IÂE0ÂIÂI5Â!E2Â"I5Â'IÂ;E4Â<IÃ-FÄE6ÄFÄ)E>	Ä.E8Ä/E>	Ä2FÄ?E:
Å FÅIÅI5Å"E<Å#I5Å+IÅ2I5Å4IÅ6FÅ8E>	Å:FÅ<I5Å>FÆFÆ
FÆFÆFÆH/ÆFÆHÆ55HÇ+"HÈH
ÈHÈHÈH/ÈIÈ/IÉIÉI5ÉIÉI5ÉI2	ÉI!É
I2	É*I2	É,	I5c              ƒ   óÄ  "  € ^ RI Hp V'       d   \        W.VO5!  G Rj  x€L
 pVe   V# TpV'       Ed   V'       g   V^,          '       gí   V P                  pRV9   dn   VP	                  WP
                  4      G Rj  x€L
 pVf   \        W^ ,          4      G Rj  x€L
  R# WqJd&   ^ RIHp	 V	! V^ ,          VP                  4      Vn
        WS9   dg   ^ RI Hp
 V
! W‡VP
                  VP                  VP
                  4      4      G Rj  x€L
 w  q±n        V'       d   \        W^ ,          4      G Rj  x€L
  R# V P                  V4      G Rj  x€L
 #  EL2 LÖ Lº LO L( L5i)r   rN   NrQ   ©Úingress_fingerprint)Úrun_post_admission_hook)rT   rO   Ú_webhook_retryr$   Ú_hm_pre_gateway_dispatch_hookr   re   Úgateway.session_ingress_mediarq   Úraw_messageÚ_ingress_sha256rr   Ú_session_key_for_sourceÚ_consumer_replyrW   )r(   r#   rf   rh   rl   rO   ÚpriorÚadmittedr$   rq   rr   Úconsumeds   &&&&&       r)   r_   r_   ž   s-  é € Ý@ßÜ$ YÐB¸	ÓB×BˆØÒØˆLØ€Hß€u—' ¨1§¤Ø×!Ñ!ˆØ! UÔ*Ø#×AÑAÀ%ÏÉÓV×VˆHØÒÜ*¨9ÀµlÓC×CÐCÙØÓ$õ NÙ+>¸yÈ½|ÈU×M^ÑM^Ó+_�Ô(ØÔ'ÝLÙ4KØ (§/¡/°6×3QÑ3QÐRZ×RaÑRaÓ3bó5d÷ /dÑ+ˆHÔ+çÜ*¨9ÀµlÓC×CÐCÙØ×'Ñ'¨Ó1×1Ð1ò/ Cñ WáCñ/dñ Dá1ùsz   ‚E ¡E¢E ·E ¿E Á1E Á?EÂ E ÂEÂA,E Ä
EÄ(E Ä3EÄ4E ÅEÅE ÅE ÅE ÅE ÅE ÅE c                óî   "  € V ^,          '       g   R5x € R# ^ RI Hp V! \        V 4      ;_uu_4       GRj  x€L
  R5x € RRR4      GRj  x€L
  R#  L L  + GRj  x€L 
 '       g   i     R# ; i5i)é   N)Ú
keyed_turn)rX   r   Ú_deliveries)Úkeyr   s   & r)   r[   r[   À   s>   é € àˆq�6Œ6ÜÙÝ4Ùœ+ s×+×+Õ+Ü÷ ,×+×+×+×+×+üsJ   ‚6A5¸A¹A5¼AÁA5ÁAÁA5ÁA5ÁA2	ÁA!Á
A2	Á*A2	Á,	A5c              ƒ  ó¸   "  € ^ RI Hp VR,          P                  R4      ;p'       d.   \        P                  ! W P
                  VRR7      G Rj  x€L
  R# R#  L5i)a  A delivery a plugin skipped or consumed, or one refused or cancelled after preparing, is never
admitted: release the media its preparation (``_prepared``) copied into the retained store. A path
another admission or an in-flight capture holds is kept, as for a refused admission.)Úrelease_unheld_mediaÚnative_text_v1ÚmediaF)Úretain_historyN)ru   rƒ   r   rb   Ú	to_threadÚdb)r(   ri   rƒ   r…   s   &&  r)   re   re   Ê   sM   é € õ CØÐ(Õ)×-Ñ-¨gÓ6Ð6€uÖ6Ü×ÒÐ 4·l±lÀEÐZ_Ô`×`Ò`ñ 7Ù`ùs   ‚AAÁAÁ	Ac              ƒ  óì  "  € ^ RI p^ RIHpHp ^ RIHpHp V! V 4      ;_uu_ 4       p V! V P                  V4      G Rj  x€L
 p RRR4       T! X4      P                  p	TP                  T	P                  T	P                  P                  T	P                  T	P                  T	P                   .RR7      p
TRT
,           3#  L~  \         d    T! T4      G Rj  x€L 
  h i ; i  + '       g   i     L¤; i5i)z•``(validated payload, principal)`` of this delivery. Preparing the payload runs the same
authorization as admission, so a refused sender raises here.N)Úprepare_nativeÚrestore_native)Úabandon_captureÚcapture_lease)Ú
separatorsz
messaging:)Ú,Ú:)ÚjsonÚgateway.session_enveloperŠ   r‹   ru   rŒ   r�   r$   ÚBaseExceptionr   Údumpsr   r   ÚvalueÚchat_idÚ	thread_idÚuser_id)r(   r#   r‘   rŠ   r‹   rŒ   r�   Úscoperi   r   Úidentitys   &&         r)   rY   rY   Ó   sÏ   é € ó ßGßLÙ	�y×	!Ô	! Uð	Ù*¨9×+;Ñ+;¸UÓC×C‰G÷ 
"ñ ˜GÓ$×+Ñ+€FØ�z‰z˜6Ÿ>™>¨6¯?©?×+@Ñ+@À&Ç.Á.Ø!×+Ñ+¨V¯^©^ð=ØISð ó U€Hà�L 8Õ+Ð+Ð+ñ DøÜô 	Ù! %Ó(×(Ñ(Øð	ú÷ 
"×	!üsK   ‚%C4§C!©C ¿B>Á C ÁA9C4Â>C Ã CÃC
ÃCÃC!Ã!C1	Ã,C4c                ó<   € V P                   P                  RW34      # )z1The rows of this delivery's identity in the FIFO.zQSELECT admission_id FROM session_admissions WHERE principal_id=? AND request_id=?)rˆ   Ú	_read_all)r(   rj   Ú
request_ids   &&&r)   r^   r^   å   s&   € à�<‰<×!Ñ!ð #0Ø2;Ð1HóJð Jr1   c              ƒ   óF  "  € ^ RI Hp ^ RIHp V'       g   R# V! V P                  V^ ,          R,          R7      pVR,          R,          pRV9   d   VR,          V! W!P
                  4      8H  pMjR	V9  dX   R
V9  dQ   VR,          P                  R	4       VR,          P                  R
4       RV9  d   VR,          P                  RR4       VR,          V8H  p\        V4      ^8w  g	   V'       g   \        R4      hRVn	        V P                  V4      p	\        W	4       V	# 5i)r   rp   )Úget_session_admissionNÚadmission_id©r    ri   r„   Úingress_sha256Úwebhook_deliveryÚwebhook_routeÚ
provenanceÚadmission_conflictT)ru   rq   Úhermes_state_runtimerŸ   rˆ   rv   ÚpopÚlenr   Ú_webhook_duplicateÚ_receiptÚfinalize_webhook)
r(   r#   ri   Úrowsrq   rŸ   ÚrowÚretainedÚsameÚreceipts
   &&&&      r)   rs   rs   ê   s  é € õ BÝ:ßÙÙ
 	§¡¸4À½7À>Õ;RÔ
S€CØ�9�~Ð.Õ/€HØ˜8Ô#àÐ(Õ)Ñ-@À×J[ÑJ[Ó-\Ñ\‰à XÔ-°/ÈÔ2Qð Ð$Õ%×)Ñ)Ð*<Ô=ØÐ$Õ%×)Ñ)¨/Ô:Ø 8Ô+ØÐ(Õ)×-Ñ-¨l¸DÔAØ�9�~ Ñ(ˆÜ
ˆ4ƒy�A„~ŸTÜÐ 4Ó5Ð5Ø#€EÔØ× Ñ  Ó%€GÜ�YÔ(Ø€Nùs   ‚C.D!Ã10D!c                óÚ   a aaa€ ^ RI oSP                  R8w  g   SP                  f   R# SP                  P                  oV VVV3R lp\        S P                  P                  V4      4      # )zJEnd only the settled admitted generation, atomically with the epoch fence.NÚterminalFc                 óÖ   <€ SP                   P                  V R SP                  4       RSSP                  SP                  SP
                  SSP                  SP                  S3
SR4      # )a  
            UPDATE sessions SET ended_at=?, end_reason=?
            WHERE id=? AND ended_at IS NULL AND runtime_generation=?
              AND EXISTS (SELECT 1 FROM runtime_epoch WHERE singleton=1 AND epoch=?)
              AND EXISTS (SELECT 1 FROM session_admissions WHERE admission_id=?
                AND target_session_id=? AND status='terminal' AND generation=? AND owner_epoch=?)
              AND NOT EXISTS (SELECT 1 FROM session_admissions WHERE target_session_id=? AND status!='terminal')
            Úwebhook_complete)rˆ   Ú_end_and_bumpÚtimeÚexecution_generationÚepochr    Úauthority_epoch)Úconnr(   r±   Úsidr·   s   &€€€€r)   ÚwriteÚfinalize_webhook.<locals>.write  sj   ø€ Ø�|‰|×)Ñ)¨$ð 1ð —)‘)“+Ð1°3¸×8TÑ8TØ—/‘/ 7×#7Ñ#7¸¸g×>ZÑ>ZØ×)Ñ)¨3ð0à14Ð6Hó	Jð 		Jr1   )r·   r6   r¸   ÚrefÚ
session_idÚboolrˆ   Ú_execute_write)r(   r±   r½   r¼   r·   s   ff @@r)   r¬   r¬     sW   û€ ãØ‡~�~˜Ô# w×'CÑ'CÒ'KÙØ
�+‰+×
 Ñ
 €C÷
Jð 
Jô �	—‘×+Ñ+¨EÓ2Ó3Ð3r1   c              ƒ  ó8  "  € ^ RI Hp ^ RIHp ^ RIHpHp V P                  P                  R4      p/ pV EFB  pV! V P                  VR,          R7      pVf   K%  VR,          p	 VR	,          R
,          p
V P                  P                  P                  V
R,          4      pVe!   V P                  VP                  4      V	8w  d	   V! R4      hVP                  e&   V P                  P                  VP                  4      MRpV P!                  V! V P"                  V	4      4      pV! V P                  VR	,          WÛP                  V4      G Rj  x€L
  \%        W P'                  V4      4      '       d   RMRWi&   EKE  	  V#  L1  \(        T3 d
    RYi&    EK`  i ; i5i)zPClose settled original webhooks only after current route authorization succeeds.)Úcheck_native_route)Ú
SessionRef)r   rŸ   a�  
        SELECT a.admission_id FROM sessions AS s
        JOIN session_admissions AS a ON a.target_session_id=s.id
        WHERE s.source='webhook' AND s.ended_at IS NULL
          AND a.status='terminal' AND a.generation IS NOT NULL
          AND json_extract(a.payload_json, '$.native_text_v1.source.platform')='webhook'
          AND json_extract(a.payload_json, '$.native_text_v1.automation') IS NULL
        r    r¡   NÚtarget_session_idri   r„   Úrouter¦   Ú	finalizedÚ	unchangedÚunavailable)r’   rÄ   Úgateway.session_contractrÅ   r§   r   rŸ   rˆ   rœ   r$   Úsession_storeÚlookup_by_session_keyÚlogical_ownerrÀ   ÚoriginÚ_adapter_for_sourceÚphysical_targetr\   r¬   r«   ÚKeyError)r(   rÄ   rÅ   r   rŸ   r­   ÚresultsÚ	candidater®   r¼   ÚenvelopeÚentryr"   Útargets   &             r)   Úrecover_webhook_finalizationsrØ     sw  é € å;Ý3ßMà�<‰<×!Ñ!ð #ó €Dð €GÜˆ	Ù# I§L¡L¸yÈÕ?XÔYˆØŠ;ÙØÐ%Õ&ˆð	)Ø˜9•~Ð&6Õ7ˆHØ×$Ñ$×2Ñ2×HÑHÈÐRYÕIZÓ[ˆEØŠ} 	× 7Ñ 7¸×8HÑ8HÓ IÈSÔ PÙ'Ð(<Ó=Ð=ØLQÏLÉLÒLd�i×&Ñ&×:Ñ:¸5¿<¹<ÔHÐjnˆGØ×.Ñ.©z¸)×:NÑ:NÐPSÓ/TÓUˆFÙ$ Y×%5Ñ%5°s¸9µ~ÀvÏ|É|Ð]dÓe×eÐeÜ*:Ø×-Ñ-¨cÓ2÷+4ò +4™;Ø9Dð ŒLñ ð" €Nñ føô Ð+Ð,ô 	)Ø(ˆG�Lð	)üs=   ‚A"FÁ%C(FÅE?Å*FÅ8FÅ?FÆFÆFÆFÆF)Ú__doc__rb   Ú
contextlibr   r§   r   r*   r   r@   r:   r;   rn   r_   r€   r[   re   rY   r^   rs   r¬   rØ   © r1   r)   Ú<module>rÜ      sƒ   ðÙ WÛ Ý *å 2ð ñ"ó ð"òJ,òuò4NòEò0!0òH2ð> €ð ñó ðòaò,ò$Jò
ò:4ô( r1   