+
    iHàj˜¤  ã                   ó@  a € R� te0 t R 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
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HtHt ^ RIHt ^ RIHtHt ^ RIHt ]P>                  ! ] 4      t!Rt"R	R
.t#Rt$Rt%Rt&Rt'R‚R R llt(R R lt)R R lt*R R lt+RR/R R llt, ! R R]-4      t.R R lt/R R  lt0R! R" lt1]Pd                  ! 4       t3]4! 4       t5] ^ k ]! 4       t6] ^k ^@t7R#t8R$ R% lt9R& R' lt:R( R) lt;R* R+ lt<R, R- lt=R.R/R/ R0 llt>R.R/R1 R2 llt?R3R4 R5R6 /t@R7 R8 ltAR9tBR: R; ltCR< R= ltDR> R? ltER@ RA ltFRB RC ltGRD RE ltHRF RG ltIRH RI ltJRJ RK ltK]L! 0 Rƒm4      tM ! RL RM]N4      tORN RO ltPRP RQ ltQRR]$/RS RT lltRRUR/RV RW lltSRXRY/RZ R[ lltTR\ R] ltUR^RR_R/R` Ra lltVRb Rc ltWRd Re ltXR„Rf Rg lltYRh Ri ltZRjRY/Rk Rl llt[Rm Rn lt\RoR/Rp Rq llt]Rr Rs lt^Rt Ru lt_Rv Rw lt`Rx Ry ltaRz R{ ltbR| R} ltcR~R/R R€ lltdR# )…aK  Anthropic credential sources, OAuth flows, and token resolution.

``resolve_anthropic_token()`` order: ``ANTHROPIC_TOKEN`` / ``CLAUDE_CODE_OAUTH_TOKEN``,
``ANTHROPIC_API_KEY``, Hermes-owned OAuth grants in the ``auth.json`` credential
pool, then ``~/.claude/.credentials.json`` / macOS Keychain as a borrowed fallback.
``~/.hermes/.anthropic_oauth.json`` (Hermes PKCE) and
the Claude Code file are *singletons*: ``credential_pool._seed_from_singletons()``
re-reads them on every ``load_pool()``, so a failed write here is a failed refresh
(``CredentialPersistError``), not a cache miss.
N)ÚOrderedDict©ÚPath)ÚAnyÚDictÚOptional©Úget_hermes_home)Úatomic_json_writeÚbase_url_hostname)Ú
get_secretz$9d1c250a-e61b-44d9-88ed-5944d1962f5ez*https://platform.claude.com/v1/oauth/tokenz,https://console.anthropic.com/v1/oauth/tokenzaxios/1.7.9z1https://console.anthropic.com/oauth/code/callbackz.org:create_api_key user:profile user:inferencezClaude Code-credentialsÚ c                ó<   € V ^8„  d   QhR\         R\         R\         /# )é   ÚnameÚdefaultÚreturn©Ústr)Úformats   "Ú@/home/ubuntu/.hermes/hermes-agent/agent/anthropic_credentials.pyÚ__annotate__r   3   s!   € ÷ /ñ /”#ð /¤ð /¬Sñ /ó    c                ó(   € \        W4      pVe   V# T# )z`Profile-scoped os.getenv for credential reads (fail-closed on unscoped reads when multiplexing).)Ú_get_secret)r   r   Úvals   && r   Ú_getenvr   3   s   € ä
�dÓ
$€CØ’/ˆ3Ð. wÐ.r   c                ó0   € V ^8„  d   QhR\         R\         /# )r   Únamesr   r   )r   s   "r   r   r   9   s   € ÷ Kñ K”sð Kœsñ Kr   c                 ó6   € \        R R V  4        4       R4      # )z8First non-blank (stripped) value among *names*, else ''.c              3   ó8   "  € T F  q'       g   K  Vx € K  	  R # 5i©N© )Ú.0Úvs   & r   Ú	<genexpr>Ú_first_env.<locals>.<genexpr>;   s   é € ÐEÑ?�qÃ1—’Ó?ùs   ‚	�
c              3   óT   "  € T F  p\        V4      P                  4       x € K   	  R # 5ir!   )r   Ústrip)r#   Úns   & r   r%   r&   ;   s    é € Ð?¹°AœW Q›Z×-Ñ-×/Ð/»ùs   ‚&(r   )Únext)r   s   *r   Ú
_first_envr+   9   s   € äÑEÑ?¹Ô?ÓEÀrÓJÐJr   c                ó0   € V ^8„  d   QhR\         R\        /# )r   Úkeyr   )r   Úbool)r   s   "r   r   r   >   s   € ÷ 5ñ 5œð 5¤ñ 5r   c                óf   € V '       d   V P                  R4      '       d   R# V P                  R4      # )u{  True for Anthropic OAuth/setup tokens (sk-ant-oat*, eyJ JWTs, cc-); False for the Console
API-key families sk-ant-api*, sk-ant-usr*, sk-ant-svc* and sk-ant-admin* (#133856) â€” they pay
per token and authenticate as x-api-key, so the Claude Code identity must not ride along.
Unknown sk-ant-* prefixes still classify as OAuth so OAuth prefixes Anthropic ships later keep working.F)z
sk-ant-apiz
sk-ant-usrz
sk-ant-svczsk-ant-admin)zsk-ant-ÚeyJzcc-)Ú
startswith)r-   s   &r   Ú_is_oauth_tokenr2   >   s)   € ÷
 �#—.‘.Ð![×\Ò\ÙØ�>‰>Ð3Ó4Ð4r   c                ó0   € V ^8„  d   QhR\         R\        /# )r   Úbase_urlr   )r   r.   )r   s   "r   r   r   H   s   € ÷ Fñ F¤sð F¬tñ Fr   c                ó‚   € \        T ;'       g    R4      P                  4       pV'       * ;'       g    \        V4      R8H  # )z`True when *base_url* is exactly ``api.anthropic.com`` (an empty base_url is the native default).r   zapi.anthropic.com)r   r(   r   )r4   Útexts   & r   Úis_native_anthropic_hostr7   H   s7   € äˆx�~ˆ~˜2Ó×$Ñ$Ó&€DØŒ8×EÐEÔ(¨Ó.Ð2EÑEÐEr   Úproviderc                ó^   € V ^8„  d   QhR\         R\         R\        \        ,          R\        /# )r   r4   Ú
credentialr8   r   )r   r   r   r.   )r   s   "r   r   r   N   s4   € ÷ Gñ G¤sð G¼ð GÌ(ÔSVÍ-ð GÔcgñ Gr   c               óJ  € \        V 4      '       g0   T;'       g    RP                  4       P                  4       R8X  g   R# \        V4      '       d   \	        V\
        4      '       g	    V! 4       p\	        V\
        4      ;'       d    \        V4      #   \         d     R# i ; i)uÅ  Claude Code OAuth identity for one Anthropic Messages route (#114967).

The route qualifies when it is the ``anthropic`` provider itself or its host is exactly
``api.anthropic.com`` (an empty base_url is the native default) â€” a named custom provider
pointed at the native host carries the same identity, while third-party Anthropic-protocol
endpoints never do (Claude Code headers and tool-name transforms 401/403 there). ``credential``
is a static string or a ``key_cmd``/per-request callable token source; a callable is
materialized once for the shape test (``CommandTokenSource`` caches, so this never double-mints)
and a mint failure classifies as non-OAuth â€” the wire client surfaces the real error.
r   Ú	anthropicF)r7   r(   ÚlowerÚcallableÚ
isinstancer   Ú	Exceptionr2   )r4   r:   r8   s   &&$r   Úanthropic_route_is_oauthrA   N   s…   € ô % X×.Ò.°8·>°>¸r×2HÑ2HÓ2J×2PÑ2PÓ2RÐVaÔ2aÙÜ�
×Ò¤J¨z¼3×$?Ò$?ð	Ù#›ˆJô �j¤#Ó&×FÐF¬?¸:Ó+FÐFøô ô 	Úð	ús   Á)B ÂB"Â!B"c                   óB   a a€ ] tR t^ct oRtV3R lV 3R lltRtVtV ;t# )ÚCredentialPersistErrorzÖA rotated single-use credential could not be durably committed. The refresh POST already spent the old
refresh token, so a swallowed write failure leaves a consumed pair on disk that later replays as invalid_grant.c                ó*   <€ V ^8„  d   QhRS[ RS[RR/# )r   ÚpathÚcauser   N)r   ÚBaseException)r   Ú__classdict__s   "€r   r   Ú#CredentialPersistError.__annotate__g   s"   ø€ ÷ ñ ™Sð ©ð ¸4ñ r   c                ó>   <€ \         SV `  R V RV 24       Wn        R# )z;failed to durably persist rotated Anthropic credentials to z: N)ÚsuperÚ__init__rE   )ÚselfrE   rF   Ú	__class__s   &&&€r   rL   ÚCredentialPersistError.__init__g   s(   ø€ Ü‰ÑÐVÐW[ÐV\Ð\^Ð_dÐ^eÐfÔgØŽ	r   )rE   )	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__rL   Ú__static_attributes__Ú__classdictcell__Ú__classcell__©rN   rH   s   @@r   rC   rC   c   s   ù‡ € ñw÷÷ ó r   rC   c                óR   € V ^8„  d   QhR\         R\        R\        \        ,          /# )r   rE   Úwhatr   )r   r   r   r   )r   s   "r   r   r   l   s%   € ÷ ñ œtð ¬3ð ´8¼Cµ=ñ r   c                óþ   € V P                  4       '       g   R#  \        P                  ! V P                  RR7      4      #   \        P                  \
        3 d"   p\        P                  RY4        Rp?R# Rp?ii ; i)zPParsed JSON from *path*, or None when missing/unreadable/corrupt (debug-logged).Nú	utf-8-sig©ÚencodingzFailed to read %s: %s)ÚexistsÚjsonÚloadsÚ	read_textÚJSONDecodeErrorÚOSErrorÚloggerÚdebug)rE   rZ   Úes   && r   Ú_load_json_if_existsrh   l   s\   € à�;‰;�=Š=ÙðÜ�zŠz˜$Ÿ.™.°+˜.Ó>Ó?Ð?øÜ× Ñ ¤'Ð*ô Ü�‰Ð,¨dÔ6Ýûðús   š%A  Á A<ÁA7Á7A<c                ó4   € V ^8„  d   QhR\         R\        RR/# )r   rE   Úpayloadr   N)r   r   )r   s   "r   r   r   w   s!   € ÷ 1ñ 1¤Tð 1´Cð 1¸Dñ 1r   c                ó    € \        WRR7       R# )z¬0600-from-creation temp file + fsync + atomic replace (the token is never briefly umask-readable).
The parent dir's mode is left alone (~/.claude/ is owned by Claude Code).i€  )ÚmodeN)r
   )rE   rj   s   &&r   Ú_atomic_write_private_jsonrm   w   s   € ô �d¨%×0r   c                ó@   € V ^8„  d   QhR\         R\        R\        RR/# )r   rE   rj   rZ   r   N)r   r   r   )r   s   "r   r   r   }   s(   € ÷ 5ñ 5œtð 5¬cð 5¼ð 5Àñ 5r   c                ó–   €  \        W4       R#   \        \        3 d)   p\        P	                  RY T4       \        Y4      ThRp?ii ; i)zeAtomic private write; any failure becomes ``CredentialPersistError`` (the commit step of a rotation).z&Failed to write refreshed %s to %s: %sN)rm   rd   Ú
ValueErrorre   ÚerrorrC   )rE   rj   rZ   rg   s   &&& r   Ú_commit_private_jsonrr   }   sB   € ð5Ü" 4Ö1øÜ”ZÐ ô 5Ü�‰Ð=¸tÈ1ÔMÜ$ TÓ-°1Ð4ûð5ús   ‚ �A #AÁAa  Non-secret one-way fingerprints of Anthropic OAuth credentials whose rotation was consumed server-side but never durably committed. Written by Hermes so sibling processes sharing this credential source fail closed instead of replaying a spent single-use refresh token.c                ó0   € V ^8„  d   QhR\         R\         /# ©r   Úsource_pathr   r   )r   s   "r   r   r   —   s   € ÷ Tñ T¬dð T´tñ Tr   c                 óF   € V P                  V P                  R ,           4      # )z.hermes-spent-rotations.json)Ú	with_namer   ©ru   s   &r   Ú_spent_rotation_sidecar_pathry   —   s   € Ø× Ñ  ×!1Ñ!1Ð4RÕ!RÓSÐSr   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r   Úsourcer   ©r   r   r   )r   s   "r   r   r   ›   s   € ÷ (ñ (¤sð (¬x¼­~ñ (r   c                ó~   € \        V \        4      '       d   \        P                  V 4      MRpV'       d   V! 4       # R# )zOMap a pool-entry source to the shared singleton file it borrows from (or None).N)r?   r   Ú_SINGLETON_SOURCE_PATHSÚget)r{   Úgetters   & r   Úspent_rotation_source_pathr�   ›   s1   € ä4>¸vÄs×4KÒ4KÔ$×(Ñ(¨Ô0ÐQU€Fß‰6‹8Ð' 4Ð'r   c                óF   € V ^8„  d   QhR\         \        ,          R\        /# rt   )r   r   Úset)r   s   "r   r   r   ¡   s"   € ÷ 
rñ 
r¬h´t­nð 
rÄñ 
rr   c                 óÄ  € V f   \        4       #  \        P                  ! \        V 4      P	                  RR7      4      p\        T\        4      '       d   TP                  R4      MR p\        T\        4      '       d5   T Uu0 uF'  p\        T\        4      '       g   K  T'       g   K%  TkK)  	  up# \        4       #   \
        \        3 d    \        4       u # i ; iu upi )Nr\   r]   Úfingerprints)rƒ   r`   ra   ry   rb   rd   rp   r?   Údictr   Úlistr   )ru   Úrawr…   Úfps   &   r   Ú_read_spent_rotation_sidecarrŠ   ¡   s³   € ØÒÜ‹uˆðÜ�jŠjÜ(¨Ó5×?Ñ?ÈÐ?ÓUó
ˆô
 /9¸¼d×.CÒ.C�3—7‘7˜>Ô*È€LÜHRÐS_Ôae×HfÒHf™ÓD™�2¬°B¼×)<ŒBÄ�BˆB™ÑDÐqÔloÓlqÐqøô ”ZÐ ô Ü‹uŠðüò Es#   �/B< ÂCÂCÂ)CÂ<CÃCc                ó4   € V ^8„  d   QhR\         R\        RR/# )r   ru   r…   r   N)r   r‡   )r   s   "r   r   r   ®   s&   € ÷ dñ d´ð dÄDð dÈTñ dr   c           
     óî  € \        V 4      p \        V 4      pVP                  V4       \        P                  ! R^R\
        R\        V4      \        ) ^,          R /^R7      pVP                  P                  RRR7       VP                  VP                  R,           4      pVP                  VR	R
7       \        P                  ! WR4       R#   \         d    \         P#                  RTRR7        R# i ; i)zŸMerge fingerprints into the sidecar (atomic replace; caller holds the path lock). Fail-soft: a sidecar
write failure must never mask the process-local verdict.ÚversionÚcommentr…   N)ÚindentT)ÚparentsÚexist_okz.tmpúutf-8r]   z3Failed to persist spent-rotation fingerprints to %s©Úexc_info)ry   rŠ   Úupdater`   ÚdumpsÚ_SPENT_ROTATION_SIDECAR_COMMENTÚsortedÚ_SPENT_ROTATION_MAX_TRACKEDÚparentÚmkdirrw   r   Ú
write_textÚosÚreplacer@   re   rf   )ru   r…   ÚsidecarÚmergedrj   Útmps   &&    r   Ú_append_spent_rotation_sidecarr¢   ®   sÚ   € ô +¨;Ó7€GðdÜ-¨kÓ:ˆØ�‰�lÔ#Ü—*’*Ø�qØÔ6ØœF 6›NÔ,GÐ+GÈ!Õ+KÐ+MÐNð
ð ô	ˆð
 	�‰×Ñ T°DÐÔ9Ø×Ñ §¡¨vÕ 5Ó6ˆØ�‰�w¨ˆÔ1Ü
�
Š
�3Ö øÜô dÜ�‰ÐJÈGÐ^bˆ×cðdús   �B>C Ã#C4Ã3C4c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r   Úsecretr   )r   r   r   )r   s   "r   r   r   Â   s   € ÷ >ñ >œð >¤¬#¥ñ >r   c                 óx   € ^ RI Hp \        T ;'       g    R4      P                  4       pV'       d	   V! V4      # R# )é    )Úfingerprint_secret_valuer   N)Úagent.credential_persistencer§   r   r(   )r¤   r§   Úvalues   &  r   Ú_fingerprintrª   Â   s1   € ÝEÜ�—�˜"Ó×#Ñ#Ó%€Eß.3Ñ# EÓ*Ð=¸Ð=r   ru   c                óJ   € V ^8„  d   QhR\         R\        \        ,          RR/# )r   Úsecretsru   r   Nr|   )r   s   "r   r   r   È   s&   € ÷ >ñ >´ð >Ä8ÌDÅ>ð >Ð]añ >r   c                óš  € \        \        V4       Uu. uF  q"'       g   K  VNK  	  pp\        ;_uu_ 4        V FR  p\        P	                  VR4       R\        V&   \        \        4      \        8”  g   K<  \        P                  RR7       K2  	  RRR4       V'       d   V e   \        W4       R# R# R# u upi   + '       g   i     L2; i)zœRecord the pre-rotation pair of a refresh whose replacement never committed; with ``source_path`` the
verdict is also persisted to that singleton's sidecar.NF)Úlast)	Úmaprª   Ú_SPENT_ROTATION_LOCKÚ_SPENT_ROTATION_FINGERPRINTSÚpopÚlenr™   Úpopitemr¢   )ru   r¬   r‰   ÚrecordedÚfingerprints   $*   r   Ú"mark_rotation_consumed_uncommittedr·   È   sš   € ô !¤¨wÔ7Ó>Ñ7�r»2—�Ñ7€HÐ>ß	Ö	Û#ˆKÜ(×,Ñ,¨[¸$Ô?Ø8<Ô(¨Ñ5ÜÔ2Ó3Ô6QÖQÜ,×4Ñ4¸%Ð4Ö@ñ	 $÷ 
÷ �KÒ+Ü& {Ö=ñ ,�xùò ?ß	×	ús   “	B5¡B5·:B:Á6B:Â:C
	c                óR   € V ^8„  d   QhR\         R\        \        ,          R\        /# )r   r¤   ru   r   )r   r   r   r.   )r   s   "r   r   r   Ö   s+   € ÷ Dñ D¬Sð DÄ(Ì4Å.ð DÔ\`ñ Dr   c               óÊ   € \        V 4      pV'       g   R# \        ;_uu_ 4        V\        9   d    RRR4       R#  RRR4       V\        V4      9   #   + '       g   i     L; i)zJTrue when *secret* belongs to a rotation that was spent but not committed.FNT)rª   r°   r±   rŠ   )r¤   ru   r¶   s   &$ r   Ú is_rotation_consumed_uncommittedrº   Ö   sP   € ä˜vÓ&€KßÙß	Ö	ØÔ6Ô6Ø÷ 
Ñ	Ø6÷ 
ð Ô6°{ÓCÑCÐC÷ 
×	ús   ¤AÁA"	Úclaude_codec                  ó   € \        4       # r!   )Úclaude_code_credentials_pathr"   r   r   Ú<lambda>r¾   ä   s   € Ô7Ô9r   Úhermes_pkcec                  ó   € \        4       # r!   )Ú_get_hermes_oauth_filer"   r   r   r¾   r¾   ä   s   € ÔRhÔRjr   c          	      ót   € V ^8„  d   QhR\         R\        R\        \        \        \         3,          ,          /# )r   Údatar{   r   )r   r   r   r†   )r   s   "r   r   r   è   s.   € ÷ 	ñ 	œsð 	¬Cð 	´H¼TÄ#ÄsÀ(½^Õ4Lñ 	r   c           	     óà   € V P                  R4      p\        V\        4      '       d   VP                  RR4      MRpV'       g   R# RVRVP                  RR4      RVP                  R^ 4      RV/# )zJNormalise a ``{"claudeAiOauth": {...}}`` payload into our credential dict.ÚclaudeAiOauthÚaccessTokenr   NÚrefreshTokenÚ	expiresAtr{   )r   r?   r†   )rÃ   r{   Ú
oauth_dataÚaccess_tokens   &&  r   Ú_claude_oauth_recordrË   è   sh   € à—‘˜/Ó*€JÜ8BÀ:Ìt×8TÒ8T�:—>‘> -°Ô4ÐZ\€LßÙà�| ^°Z·^±^ÀNÐTVÓ5WØ�Z—^‘^ K°Ó3°X¸vðð r   z.(?:0x(?P<hex>[0-9A-Fa-f]+)\b.*|"(?P<text>.*)")c                óp   € V ^8„  d   QhR\         \        P                  \        ,          ,          R\        /# )r   Úmatchr   )r   ÚreÚMatchr   )r   s   "r   r   r   ÷   s'   € ÷ %ñ %¤¬"¯(©(´3­-Õ!8ð %¼Sñ %r   c                óþ   € V f   R# V P                  R4      '       d5    \        P                  V P                  R4      4      P                  R4      # V P                  R4      ;'       g    R#   \         d     R# i ; i)zÿ``security`` prints an attribute as ``"text"`` when it is plain printable ASCII and as
``0x<HEX>  "<octal-escaped echo>"`` otherwise; the quoted form is NOT escaped (an embedded
``"`` appears raw), so the text group must run to the last quote on the line.r   Úhexr’   r6   )ÚgroupÚbytesÚfromhexÚdecoderp   )rÍ   s   &r   Ú_decode_keychain_attrrÖ   ÷   sp   € ð ‚}ÙØ‡{�{�5×Òð	Ü—=‘= §¡¨UÓ!3Ó4×;Ñ;¸GÓDÐDð �;‰;�vÓ×$Ð$ "Ð$øô ô 	Úð	ús   Ÿ2A- Á-A<Á;A<c                ó~   € V ^8„  d   QhR\         \        \        \        \        \        3,          3,          ,          /# ©r   r   )r   Útupler   r†   r   )r   s   "r   r   r     s-   € ÷ Eñ E¬´%¼¼TÄ#ÄsÀ(½^Ð8KÕ2LÕ)Mñ Er   c                 óè  € \         P                  ! 4       R8w  d   R#  \        P                  ! RRR\        R.RRRR	^\        P
                  R
R7      p T P                  ^ 8w  d   R# \        \        P                  ! R\        ,           R,           T P                  \        P                  4      4      p\        \        P                  ! R\        ,           R,           T P                  \        P                  4      4      pT'       d	   T'       g   R#  \         P"                  ! T4      p\'        T\(        4      '       d   Y3# R#   \        \        P                  3 d     R# i ; i  \$         d     R# i ; i)uv  ``(account, payload)`` of the ``Claude Code-credentials`` login Keychain item, or None.

One ``find-generic-password -g`` call: attributes on stdout, ``password: â€¦`` on stderr. The
account matters because ``add-generic-password -U`` matches on account AND service â€” writing
under another account would create a second item instead of updating the one Claude Code reads.
ÚDarwinNÚsecurityúfind-generic-passwordú-sz-gTr’   rž   F©Úcapture_outputr6   r^   ÚerrorsÚtimeoutÚstdinÚcheckz^\s*"acct"<blob>=z\s*$z^password: )ÚplatformÚsystemÚ
subprocessÚrunÚ_CLAUDE_CODE_KEYCHAIN_SERVICEÚDEVNULLrd   ÚTimeoutExpiredÚ
returncoderÖ   rÎ   ÚsearchÚ_KEYCHAIN_ATTRÚstdoutÚ	MULTILINEÚstderrr`   ra   rp   r?   r†   )ÚresultÚaccountrˆ   rj   s       r   Ú_find_claude_code_keychain_itemrô     s-  € ô ‡‚Ó˜HÔ$ÙðÜ—’ØÐ0°$Ô8UÐW[Ð\Ø d°WÀYÐXYÔak×asÑasØô
ˆð ×Ñ˜AÔÙÜ#¤B§I¢IÐ.BÄ^Õ.SÐV]Õ.]Ð_e×_lÑ_lÔnp×nzÑnzÓ${Ó|€GÜ
¤§	¢	¨.¼>Õ*IÈGÕ*SÐU[×UbÑUbÔdf×dpÑdpÓ qÓ
r€CßŸ#ÙðÜ—*’*˜S“/ˆô ",¨G´T×!:Ò!:ˆGÐÐDÀÐDøô ”Z×.Ñ.Ð/ô Úðûô ô Úðús#   ž5E  ÄE" Å EÅEÅ"E1Å0E1c                ó\   € V ^8„  d   QhR\         \        \        \        3,          ,          /# rØ   ©r   r†   r   r   )r   s   "r   r   r   #  s    € ÷ :ñ :¬H´T¼#¼s¸(µ^Õ,Dñ :r   c                 óz  € \         P                  ! 4       R8w  d   R#  \        P                  ! RRR\        R.RRRR	^\        P
                  R
R7      p T P                  ^ 8w  d   \        P                  R\        4       R# T P                  P                  4       pT'       g   R#  \        P                  ! T4      p\!        T\"        4      '       d   T# R#   \        \        P                  3 d    \        P                  R4        R# i ; i  \        P                   d    \        P                  R4        R# i ; i)a2  Raw ``{"claudeAiOauth": {...}, ...}`` payload from the macOS Keychain, or None.

Returns the full entry (not the normalised credential record) so a refresh
write can merge the rotated token triple over the existing metadata
(``subscriptionType`` / ``rateLimitTier`` / ``scopes``) instead of clobbering it.
rÛ   NrÜ   rÝ   rÞ   z-wTr’   rž   Frß   z5Keychain: security command not available or timed outzKeychain: no entry found for %rz/Keychain: credentials payload is not valid JSON)rå   ræ   rç   rè   ré   rê   rd   rë   re   rf   rì   rï   r(   r`   ra   rc   r?   r†   )rò   rˆ   rj   s      r   Ú"_read_claude_code_keychain_payloadrø   #  s
  € ô ‡‚Ó˜HÔ$ÙðÜ—’ØÐ0°$Ô8UÐW[Ð\Ø d°WÀYÐXYÔak×asÑasØô
ˆð ×Ñ˜AÔÜ�‰Ð6Ô8UÔVÙØ
�-‰-×
Ñ
Ó
€CßÙðÜ—*’*˜S“/ˆô ! ¬$×/Ò/ˆ7Ð9°TÐ9øô ”Z×.Ñ.Ð/ô Ü�‰ÐLÔMÚðûô ×Ñô Ü�‰ÐFÔGÚðús#   ž5C Â%D Ã0D	ÄD	Ä*D:Ä9D:c                ó–   € V ^8„  d   QhR\         R\        \         \        3,          R\        \        \         ,          \         3,          /# )r   ró   rj   r   )r   r†   r   rÙ   r‡   )r   s   "r   r   r   C  s8   € ÷ $ñ $¤cð $´D¼¼c¸µNð $ÄuÌTÔRUÍYÔX[È^ÕG\ñ $r   c                ó¾   € R R lp\         P                  ! VRRR7      P                  R4      P                  4       pRV! V 4       RV! \        4       RV R	2pR
R.V3# )u   ``(argv, stdin)`` that updates the Claude Code Keychain item with ``payload``.

The command line goes to ``security -i`` on stdin, with the secret hex-encoded (``-X``):
a bare ``-w`` prompts twice on /dev/tty when a terminal exists (hangs the CLI) and, with
no terminal, reads only the first line and stores an EMPTY password when the confirmation
read hits EOF â€” either way the live token must never sit on argv.
c                ó0   € V ^8„  d   QhR\         R\         /# )r   r©   r   r   )r   s   "r   r   Ú._keychain_mirror_command.<locals>.__annotate__K  s   € ÷ Kñ K”cð Kœcñ Kr   c                 ób   € R V P                  RR4      P                  R R4      ,           R ,           # )Ú"Ú\z\\z\")rž   )r©   s   &r   ÚquotedÚ(_keychain_mirror_command.<locals>.quotedK  s*   € Ø�U—]‘] 4¨Ó0×8Ñ8¸¸eÓDÕDÀsÕJÐJr   T)Ú
separatorsÚensure_asciir’   zadd-generic-password -U -a z -s z -X Ú
rÜ   z-i)Ú,Ú:)r`   r–   ÚencoderÑ   ré   )ró   rj   r   ÚencodedÚlines   &&   r   Ú_keychain_mirror_commandr
  C  sk   € õKô �jŠj˜¨ZÀdÔK×RÑRÐSZÓ[×_Ñ_Óa€GØ(©°«Ð(9¸¹fÔEbÓ>cÐ=dÐdhÐipÐhqÐqsÐt€DØ˜Ð˜tÐ#Ð#r   c                ó\   € V ^8„  d   QhR\         \        \        \        3,          ,          /# rØ   rö   )r   s   "r   r   r   S  s#   € ÷ Pñ P´X¼dÄ3ÌÀ8½nÕ5Mñ Pr   c                 óB   € \        4       p V '       d   \        V R4      # R# )zPRead the "Claude Code-credentials" macOS Keychain entry (Claude Code >=2.1.114).Úmacos_keychainN)rø   rË   )rj   s    r   Ú+_read_claude_code_credentials_from_keychainr  S  s    € ä0Ó2€Gß>EÔ Ð)9Ó:ÐOÈ4ÐOr   c                ó$   € V ^8„  d   QhR\         /# rØ   r   )r   s   "r   r   r   Y  s   € ÷ &ñ &¤dñ &r   c                 óê   € \         P                  P                  RR4      P                  4       p V '       d   \	        V 4      P                  4       M\        P                  ! 4       R,          pVR,          # )a"  Claude Code's shared OAuth file; every profile reads/writes this same path. Honours ``CLAUDE_CONFIG_DIR``
like the Claude CLI itself (blank = unset, as in ``hermes_cli.foreign_sessions``). The supported opt-out of
borrowing the login is ``auth.adopt_external_logins: false`` in config.yaml.ÚCLAUDE_CONFIG_DIRr   z.claudez.credentials.json)r�   Úenvironr   r(   r   Ú
expanduserÚhome)ÚoverrideÚroots     r   r½   r½   Y  sO   € ô �z‰z�~‰~Ð1°2Ó6×<Ñ<Ó>€Hß*2Œ4�‹>×$Ñ$Ô&¼¿	º	»ÀiÕ8O€DØÐ%Õ%Ð%r   c                ó\   € V ^8„  d   QhR\         \        \        \        3,          ,          /# rØ   rö   )r   s   "r   r   r   b  s#   € ÷ dñ d´¼$¼sÄC¸x½.Õ1Iñ dr   c                  óN   € \        \        4       R 4      p V e   \        V R4      # R# )z~/.claude/.credentials.jsonNÚclaude_code_credentials_file)rh   r½   rË   ©rÃ   s    r   Ú'_read_claude_code_credentials_from_filer  b  s-   € ÜÔ <Ó >Ð@]Ó^€DØIMÒIYÔ Ð&DÓEÐcÐ_cÐcr   c                ó\   € V ^8„  d   QhR\         \        \        \        3,          ,          /# rØ   rö   )r   s   "r   r   r   g  s#   € ÷ tñ t¤h¬t´C¼°H­~Õ&>ñ tr   c                 óX  € ^ RI Hp  V ! 4       '       g   R# \        4       p\        4       pV'       d	   V'       g   T;'       g    T# \	        V4      \	        V4      rCW48w  d   V'       d   V# T# VP                  R^ 4      ;'       g    ^ VP                  R^ 4      ;'       g    ^ 8¼  d   V# T# )a  Read refreshable Claude Code OAuth credentials (Keychain and/or file). When both exist: prefer the only
non-expired one (Claude Code 2.1.x refreshes one source but not the other), else the later ``expiresAt`` so a
refresh uses the freshest refreshToken. ~/.claude.json primaryApiKey is deliberately excluded.

This is the only reader of the borrowed login, so ``auth.adopt_external_logins: false`` is enforced here:
every resolver, pool seed/sync and 401 refresher then sees "no Claude Code login" and never touches the file.)Úadopt_external_logins_enabledNrÈ   )Úagent.credential_sourcesr  r  r  Úis_claude_code_token_validr   )r  Úkc_credsÚ
file_credsÚkc_validÚ
file_valids        r   Úread_claude_code_credentialsr%  g  s˜   € õ GÙ(×*Ò*ÙÜ:Ó<€HÜ8Ó:€JßŸØ×%Ð%˜:Ð%Ü5°hÓ?ÔA[Ð\fÓAgˆjØÔß#ˆxÐ3¨Ð3Ø Ÿ™ [°!Ó4×9Ð9¸¸z¿~¹~ÈkÐ[\Ó?]×?bÐ?bÐabÔcˆ8ÐsÐisÐsr   c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# ©r   Úcredsr   )r†   r   r   r.   )r   s   "r   r   r   {  s&   € ÷ mñ m¤d¬3´¨8¥nð m¼ñ mr   c                óÈ   € V P                  R^ 4      pV'       d0   \        \        P                  ! 4       R,          4      VR,
          8  # \        V P                  R4      4      # )u[   Non-expired access token (60s buffer); no expiresAt means managed key â†’ valid if present.rÈ   éè  i`ê  rÆ   )r   ÚintÚtimer.   )r(  Ú
expires_ats   & r   r   r   {  sK   € à—‘˜;¨Ó*€Jß>HŒ3Œt�yŠy‹{˜TÕ!Ó" j°6Õ&9Ñ:ÐlÌdÐSX×S\ÑS\Ð]jÓSkÓNlÐlr   c                   ó^   a a€ ] tR tRt oRtV3R lV 3R llt]V3R lR l4       tRtVt	V ;t
# )ÚAnthropicOAuthErrori‰  z`Token endpoint rejected the request. ``code`` is the OAuth ``error`` field of the response body.c          
      ó6   <€ V ^8„  d   QhRS[ RS[RS[RS[RR/# )r   ÚstatusÚcodeÚdescriptionrZ   r   N)r+  r   )r   rH   s   "€r   r   Ú AnthropicOAuthError.__annotate__Œ  s8   ø€ ÷ dñ d™sð d©#ð d¹Cð dÉ#ð dÐRVñ dr   c          	     óˆ   <€ Wn         W n        V'       d   R V R2MRp\        ST `  RT RT RT;'       g    R V 24       R# )z (Ú)r   úAnthropic token z failed: HTTP Ú rq   N)r1  r2  rK   rL   )rM   r1  r2  r3  rZ   ÚdetailrN   s   &&&&$ €r   rL   ÚAnthropicOAuthError.__init__Œ  sN   ø€ ØŒØŒ	ß(3�2�k�] !Ñ$¸ˆÜ‰ÑÐ+¨D¨6°À¸xÀqÈÏÈÐQXÐHYÐZ`ÐYaÐbÖcr   c                ó    <€ V ^8„  d   QhRS[ /# rØ   )r.   )r   rH   s   "€r   r   r4  “  s   ø€ ÷ Rñ R¡$ñ Rr   c                óV   € V P                   R9   ;'       d    V P                  \        9   # )é�  )r=  i‘  )r1  r2  Ú_OAUTH_GRANT_DEAD_CODES)rM   s   &r   Úrelogin_requiredÚ$AnthropicOAuthError.relogin_required’  s#   € à�{‰{˜jÑ(×QÐQ¨T¯Y©YÔ:QÑ-QÐQr   )r2  r1  )rP   rQ   rR   rS   rT   rL   Úpropertyr?  rU   rV   rW   rX   s   @@r   r/  r/  ‰  s0   ù‡ € Ùj÷dó dð ÷Ró ÷Rð Rr   r/  c                ó0   € V ^8„  d   QhR\         R\        /# )r   Úexcr   )rG   r.   )r   s   "r   r   r   —  s   € ÷ Iñ I¬]ð I¼tñ Ir   c                óJ   € \        V \        4      ;'       d    V P                  # )zPTrue when retrying the same Anthropic refresh token cannot succeed (dead grant).)r?   r/  r?  )rC  s   &r   Ú#is_terminal_anthropic_refresh_errorrE  —  s   € ä�cÔ.Ó/×HÐH°C×4HÑ4HÐHr   c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r   rC  rZ   r   )r   r   r/  )r   s   "r   r   r   œ  s'   € ÷ 	Lñ 	Lœ3ð 	L¬ð 	LÔ1Dñ 	Lr   c               óv  € RRr2 \         P                  ! V P                  4       P                  4       ;'       g    R4      p\	        VP                  R4      ;'       g    R4      p\	        VP                  R4      ;'       g    R4      p\        \        V P                  4      W#VR7      #   \         d     L.i ; i)zX``urllib.error.HTTPError`` -> structured error carrying the body's OAuth ``error`` code.r   z{}rq   Úerror_description©rZ   )
r`   ra   ÚreadrÕ   r   r   r@   r/  r+  r2  )rC  rZ   r2  r3  rj   s   &$   r   Ú_oauth_http_errorrK  œ  s—   € à˜Bˆ+ðÜ—*’*˜SŸX™X›Z×.Ñ.Ó0×8Ð8°DÓ9ˆÜ�7—;‘;˜wÓ'×-Ð-¨2Ó.ˆÜ˜'Ÿ+™+Ð&9Ó:×@Ð@¸bÓAˆô œs 3§8¡8›}¨dÀdÔKÐKøô ô Ùðús   …AB* Á#B* ÂB* Â*B8Â7B8Ú
user_agentc                ó‚   € V ^8„  d   QhR\         R\        R\        R\        R\        R\        \        \        3,          /# )r   rÃ   Úcontent_typerâ   rZ   rL  r   )rÓ   r   r+  r†   r   )r   s   "r   r   r   ¨  sL   € ÷ Eñ EÜ
ðEÜ"%ðEÜ03ðEÜ;>ðEÜLOðEä	Œ#Œsˆ(…^ñEr   c          
     óº  € ^ RI p^ RIpRp\         F‡  pVP                  P	                  WpRRVRV/R7      p VP                  P                  W‚R7      ;_uu_ 4       p	\        P                  ! V	P                  4       P                  4       4      uuRRR4       u # 	  T;'       g    \#        R	V R
24      h  + '       g   i     Kµ  ; i  TP                  P                   dI   p
\        Y£R7      p\        P                  RY7T4       TP                  '       d    Rp
?
 K„   Rp
?
EK  Rp
?
i\          d&   p
T
p\        P                  RY7T
4        Rp
?
EKD  Rp
?
ii ; i)zGPOST to the token endpoints in order; raise the last error if all fail.NÚPOSTzContent-Typez
User-Agent)rÃ   ÚmethodÚheaders)râ   rI  z#Anthropic token %s failed at %s: %sr7  z failed)Úurllib.errorÚurllib.requestÚ_OAUTH_TOKEN_URLSÚrequestÚRequestÚurlopenr`   ra   rJ  rÕ   rq   Ú	HTTPErrorrK  re   rf   r?  r@   rp   )rÃ   rN  râ   rZ   rL  ÚurllibÚ
last_errorÚendpointÚreqÚresprC  s   &$$$$      r   Ú_post_oauth_tokenr_  ¨  s   € ó ÛØ€Jß%ˆØ�n‰n×$Ñ$Ø¨¸ÈÐWcÐeoÐ8pð %ó 
ˆð
	UØ—‘×'Ñ'¨Ð'×=Ô=ÀÜ—z’z $§)¡)£+×"4Ñ"4Ó"6Ó7÷ >Ô=ñ &ð ×
DÐ
Dœ
Ð%5°d°V¸7Ð#CÓDÐD÷ >×=Ð=ûà�|‰|×%Ñ%ô 	Ü*¨3Ô:ˆJÜ�L‰LÐ>ÀÐPZÔ[Ø×*×*Ð*Þö +ûäô 	UØˆJÜ�L‰LÐ>ÀÐPS×TÓTûð	UúsG   ·$C	Á2B5Â
C	Â5CÃ C	ÃC	Ã	EÃ$5D'Ä'EÄ4EÄ5EÅEÚfallback_refresh_tokenc                ó€   € V ^8„  d   QhR\         \        \        3,          R\        R\         \        \        3,          /# )r   rò   r`  r   )r†   r   r   )r   s   "r   r   r   Á  s6   € ÷ ñ œt¤C¬ H�~ð Ì#ð ÔW[Ô\_ÔadÐ\dÕWeñ r   c          
     óÔ   € RV P                  RR4      RV P                  RV4      R\        \        P                  ! 4       R,          4      V P                  RR4      R,          ,           /# )zgToken-endpoint JSON -> ``{access_token, refresh_token, expires_at_ms}`` (expires_in defaults to 3600s).rÊ   r   Úrefresh_tokenÚexpires_at_msr*  Ú
expires_ini  )r   r+  r,  )rò   r`  s   &$r   Ú_oauth_token_staterf  Á  sZ   € ð 	˜Ÿ
™
 >°2Ó6Ø˜Ÿ™ OÐ5KÓLØœœTŸYšY›[¨4Õ/Ó0°F·J±J¸|ÈTÓ4RÐUYÕ4YÕZðð r   Úuse_jsonFc                ó^   € V ^8„  d   QhR\         R\        R\        \         \        3,          /# )r   rc  rg  r   )r   r.   r†   r   )r   s   "r   r   r   Ê  s3   € ÷ Lñ L´ð LÄ$ð LÔSWÔX[Ô]`ÐX`ÕSañ Lr   c               ó\  € ^ RI pV '       g   \        R4      hRRRV R\        /pV'       d   \        P                  R3MVP
                  P                  R3w  rE\        V! V4      P                  4       V^
R\        R	7      pVP                  R
4      '       g   \        R4      h\        W`R7      # )zIRefresh an Anthropic OAuth token without mutating local credential files.Nzrefresh_token is requiredÚ
grant_typerc  Ú	client_idúapplication/jsonz!application/x-www-form-urlencodedÚrefresh)rN  râ   rZ   rL  rÊ   z3Anthropic refresh response was missing access_token)r`  )Úurllib.parserp   Ú_OAUTH_CLIENT_IDr`   r–   ÚparseÚ	urlencoder_  r  Ú_OAUTH_TOKEN_USER_AGENTr   rf  )rc  rg  rZ  rj   r  rN  rò   s   &$     r   Úrefresh_anthropic_oauth_purers  Ê  s›   € ãßÜÐ4Ó5Ð5Ø˜_¨o¸}ÈkÔ[kÐl€Gß@HœTŸZ™ZÐ);Ñ<Ø"(§,¡,×"8Ñ"8Ð:]Ð!^ñ €Fä™v g›×5Ñ5Ó7ÀlÐ\^ÐenÜ*AôC€Fà�:‰:�n×%Ò%ÜÐNÓOÐOÜ˜fÔKÐKr   c                óh   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          /# r'  )r†   r   r   r   )r   s   "r   r   r   Ù  s*   € ÷ Cñ C¤¤S¬# X¥ð C´8¼Cµ=ñ Cr   c                óÀ  €  ^ RI HpHpHp V! R^4      p\	        \        V4      \        V4      R,           4      p\        4       pV! WVR7      ;_uu_ 4        \        4       ;'       g    / pVP                  RR4      pV'       dj   W€P                  RR4      8w  dT   VP                  R^ 4      ;'       g    ^ ^ 8”  d3   \        V4      '       d"   \        P                  R4       VuuR	R	R	4       # VP                  R
R4      ;'       g    V P                  R
R4      p	V	'       g!   \        P                  R4        R	R	R	4       R	# \        W–R7      '       d!   \        P                  R4        R	R	R	4       R	# \        P                  ! V	P                  R4      4      P!                  4       R,          p
V
\"        9   d!   \        P                  R4        R	R	R	4       R	#  \%        V	RR7      p \/        TR,          TR,          TR,          T	R7       \        P                  R4       TR,          uuR	R	R	4       #   \&         dg   p\)        T4      '       d-   \"        P+                  T
4       \        P-                  RT4       M\        P                  RT4        R	p?R	R	R	4       R	# R	p?ii ; i  \&         di   p\        P1                  RYl4       \3        Y�P                  RR4      TP                  RR4      TP                  R
R4      TR7        R	p?R	R	R	4       R	# R	p?ii ; i  + '       g   i     R	# ; i  \&         d"   p\        P                  RT4        R	p?R	# R	p?ii ; i)a‘  Refresh an expired Claude Code OAuth token, returning the new access token. Refresh tokens are single-use and
Claude Code refreshes on its own schedule, so we first re-read the live sources and adopt an already-rotated
token instead of racing it into ``invalid_grant``. Read, decision, POST and write-back share the pool's
path-keyed cross-process lock (else two profiles can spend one refresh token).)ÚAUTH_LOCK_TIMEOUT_SECONDSÚ_auth_store_lockÚ	env_floatÚ(HERMES_ANTHROPIC_REFRESH_TIMEOUT_SECONDSg      @)Útimeout_secondsÚtarget_pathrÆ   r   rÈ   z3Adopted Claude Code's already-refreshed OAuth tokenNrÇ   u-   No refresh token available â€” cannot refreshrx   zvRefresh token was already consumed by an uncommitted rotation - refusing to replay it; run 'hermes auth add anthropic'r’   :Né    NzWClaude Code refresh token was already rejected as terminally invalid - not replaying itF)rg  z—Claude Code OAuth refresh token is terminally invalid (%s); Hermes cannot use this login. Run 'hermes auth add anthropic' to give Hermes its own login.z'Failed to refresh Claude Code token: %srÊ   rc  rd  ©Úspent_refresh_tokenu¸   Anthropic OAuth refresh rotated the single-use token but could not commit it to %s (%s) â€” treating the refresh as failed; run 'hermes auth add anthropic' to give Hermes its own loginz.Successfully refreshed Claude Code OAuth tokenz.Failed to acquire Claude Code refresh lock: %s)Úhermes_cli.authrv  rw  rx  ÚmaxÚfloatr½   r%  r   r   re   rf   rº   ÚhashlibÚsha256r  Ú	hexdigestÚ _DEAD_REFRESH_TOKEN_FINGERPRINTSrs  r@   rE  ÚaddÚwarningÚ_write_claude_code_credentialsrq   r·   )r(  rv  rw  rx  Úrefresh_timeout_secondsÚlock_timeout_secondsÚ	cred_pathÚcurrentÚcurrent_tokenrc  r¶   Ú	refreshedrg   s   &            r   Ú_refresh_oauth_tokenr�  Ù  sÕ  € ð
>ßZÑZÙ"+Ð,VÐXZÓ"[ÐÜ"¤5Ð)BÓ#CÄUÐKbÓEcÐfiÕEiÓjÐÜ0Ó2ˆ	ÙÐ.B×ZÖZä2Ó4×:Ð:¸ˆGØ#ŸK™K¨°rÓ:ˆMß -·9±9¸]ÈBÓ3OÔ"OØ Ÿ™ [°!Ó4×9Ð9¸¸QÔ>ÔC]Ð^e×CfÒCfÜ—‘ÐRÔSØ$÷ [ÒZð $ŸK™K¨¸Ó;×\Ð\¸u¿y¹yÈÐY[Ó?\ˆMß Ü—‘ÐLÔMØ÷ [ÑZô 0°×UÓUÜ—‘ð Xô Yà÷# [ÑZô$ "Ÿ.š.¨×)=Ñ)=¸gÓ)FÓG×QÑQÓSÐTWÕXˆKØÔ>Ô>Ü—‘ÐvÔwØ÷+ [ÑZð,
Ü8¸ÐQVÔW�	ðÜ.Ø˜nÕ-¨y¸Õ/IÈ9ÐUdÕKeØ(5õô  �L‰LÐIÔJØ˜^Õ,÷k [ÒZøô0 ô Ü6°q×9Ò9Ü4×8Ñ8¸ÔEÜ—N‘Nð_Ø`aõcô —L‘LÐ!JÈAÔNÛ÷A [ÑZûð0ûô  ô Ü—‘ðSð ô	ô 3Ø!§9¡9¨]¸BÓ#?ÀÇÁÈ]Ð\^ÓA_Ø—K‘K °Ó3Àõó ÷g [ÑZûðPú÷Q [×ZÐZûôl ô ä�‰ÐEÀqÔIÝûðúsÕ   ‚AL1 Á.LÂ.LÂ3/LÃ"
L1 Ã-LÄLÄ!LÄ7L1 Å(LÅ)L1 Å3ALÇL1 ÇH3Ç'$J'ÈLÈ(
L1 È3J$È>AJÊLÊL1 ÊJ$Ê$LÊ'LÊ2ALÌLÌL1 ÌLÌLÌL.	Ì(L1 Ì.L1 Ì1MÌ<MÍMÚscopesr~  c                ón   € V ^8„  d   QhR\         R\         R\        R\        \        ,          R\         RR/# )r   rÊ   rc  rd  r�  r~  r   N)r   r+  r   r‡   )r   s   "r   r   r     sK   € ÷ ]ñ ]Üð]Ü&)ð]Ü:=ð]ÜJRÔSWÍ.ð]äð]ð 
ñ]r   c               óº  € \        4       p VP                  4       '       d'   \        P                  ! VP	                  RR7      4      M/ pRT RTRT/pTe   Y8R&   M(R	T9   d"   RTR	,          9   d   TR	,          R,          TR&   Y†R	&   \        YVR
4       \        YY$R7       R#   \
        \        3 d(   p\        P                  RYW4       \        YW4      ThRp?ii ; i)a  Commit refreshed credentials to ~/.claude/.credentials.json; ``CredentialPersistError`` on any failure (a
corrupt existing file included). *scopes* (or the previously stored scopes) are persisted because Claude Code
>=2.1.81 gates on ``"user:inference"`` being present.r\   r]   z/Failed to write refreshed credentials to %s: %sNrÆ   rÇ   rÈ   r�  rÅ   Úcredentialsr}  )r½   r_   r`   ra   rb   rd   rp   re   rq   rC   rr   Ú+_mirror_claude_code_credentials_to_keychain)	rÊ   rc  rd  r�  r~  r‹  Úexistingrg   rÉ   s	   &&&$$    r   rˆ  rˆ    sÝ   € ô -Ó.€Ið:ØLU×L\ÑL\×L^ÒL^”4—:’:˜i×1Ñ1¸;Ð1ÓGÔHÐdfˆð #0°¸~È}Ð^iÐkxÐ!y€JØÒØ%�8ÒØ	˜HÔ	$¨°X¸oÕ5NÔ)NØ'¨Õ8¸ÕBˆ
�8ÑØ *ˆ_ÑÜ˜¨mÔ<Ü/Ø ]÷]øô ”ZÐ ô :Ü�‰ÐFÈ	ÔUÜ$ YÓ2¸Ð9ûð:ús   Œ>B" Â"CÂ3"CÃCc                ó˜   € V ^8„  d   QhR\         \        \        3,          R\        R\        R\        R\         \        \        3,          /# )r   Úexisting_payloadrÊ   rc  rd  r   )r†   r   r   r+  )r   s   "r   r   r   7  sD   € ÷ ñ Üœ3¤˜8•nðÜ47ðÜHKðÜ\_ðä	Œ#Œsˆ(…^ñr   c                óš   € \        V 4      p\        V P                  R4      ;'       g    / 4      pVP                  RVRVRV/4       WTR&   V# )zôRotate the ``claudeAiOauth`` token triple over the existing Keychain payload,
preserving its metadata (``subscriptionType`` / ``rateLimitTier`` / ``scopes``).

Pure and host-agnostic so the merge semantics are unit-testable without a Keychain.
rÅ   rÆ   rÇ   rÈ   )r†   r   r•   )r—  rÊ   rc  rd  r    Úoauths   &&&&  r   Ú"_merge_keychain_credential_payloadrš  7  sT   € ô Ð"Ó#€FÜÐ!×%Ñ% oÓ6×<Ð<¸"Ó=€EØ	‡L�L�- ¨~¸}ÈkÐ[hÐiÔjØ#ˆ?ÑØ€Mr   c          
      óL   € V ^8„  d   QhR\         R\         R\        R\         RR/# )r   rÊ   rc  rd  r~  r   N)r   r+  )r   s   "r   r   r   F  s;   € ÷  sñ  sÜð sÜ&)ð sÜ:=ð sÜWZð sà	ñ sr   c               ó’  € \         P                  ! 4       R8w  d   R#  \        4       pVf   R# Vw  rVVP                  R4      p\	        V\
        4      '       d   VP                  R4      V8w  d   \        P                  R4       R# \        V\        W`W4      4      w  r‰\        P                  ! W‰RRRR^
R	R
7      p
T
P                  ^ 8w  dM   \        P                  RT
P                  T
P                  ;'       g    RP                  4       R,          4       R# R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)uB  After a Hermes refresh, write the rotated pair into the Claude Code Keychain item too (#98334).

Claude Code on macOS reads the login Keychain first. Refresh tokens are single-use, so a refresh
that only updates the file leaves the Keychain holding a spent token and Claude Code logs itself
out. Only the item that held the pair we just spent is updated â€” a different pair there means a
different login (``CLAUDE_CONFIG_DIR``) or a rotation Claude Code already made, and clobbering it
would be the bug in the other direction. Best-effort: never raises, never creates an item.
rÛ   NrÅ   rÇ   zJKeychain mirror skipped: item does not hold the pair that was just rotatedTr’   rž   F)Úinputrà   r6   r^   rá   râ   rä   zKeychain mirror skipped (%s)z"Keychain mirror failed (rc=%s): %sr   :NéÈ   N)rå   ræ   rô   r   r?   r†   re   rf   r
  rš  rç   rè   r@   rì   rñ   r(   )rÊ   rc  rd  r~  Úitemró   r•  r™  Úargvr	  rò   rg   s   &&&$        r   r”  r”  F  s  € ô ‡‚Ó˜HÔ$ÙðÜ.Ó0ˆØŠ<ÙØ ÑˆØ—‘˜_Ó-ˆÜ˜%¤×&Ò&¨%¯)©)°NÓ*CÐGZÔ*ZÜ�L‰LÐeÔfÙÜ-ØÔ7¸ÐP]Ómóo‰
ˆä—’Ø¨T¸ÀwÐW`ÐjlØô
ˆð ×Ñ˜AÔÜ�‰Ð9¸6×;LÑ;LÈvÏ}É}×ObÐObÐ`b×NiÑNiÓNkÐlpÕNqÖrñ øô ô Ü�‰Ð3°QÔ7Ýûðús#   žD ®AD Â5D ÄEÄ%EÅEc                ó~   € V ^8„  d   QhR\         \        \        \        3,          ,          R\         \        ,          /# r'  rö   )r   s   "r   r   r   l  s.   € ÷ ñ ´xÄÄSÌ#ÀXÅÕ7Oð Ô[cÔdgÕ[hñ r   c                ó²  € T ;'       g    \        4       p V '       g   R# \        V P                  RR4      \        4       R7      '       d   \        P                  R4       R# \        V 4      '       d   \        P                  R4       V R,          # \        P                  R4       \        V 4      pV'       g   \        P                  R4       T;'       g    R# )	zHResolve a token from Claude Code credential files, refreshing if needed.NrÆ   r   rx   zGClaude Code credentials hold a rotated-but-uncommitted token - refusingz-Using Claude Code credentials (auto-detected)u6   Claude Code credentials expired â€” attempting refreshuU   Token refresh failed â€” run 'hermes auth add anthropic' to give Hermes its own login)r%  rº   r   r½   re   rf   r   r�  )r(  rŽ  s   & r   Ú+_resolve_claude_code_token_from_credentialsr£  l  s�   € à×3Ð3Ô1Ó3€EßÙÜ'¨¯	©	°-ÀÓ(DÔRnÓRp×qÓqä�‰Ð^Ô_ÙÜ! %×(Ò(Ü�‰ÐDÔEØ�]Õ#Ð#Ü
‡L�LÐIÔJÜ$ UÓ+€IßÜ�‰ÐlÔmØ×Ð˜Ðr   c                óŠ   € V ^8„  d   QhR\         R\        \        \         \        3,          ,          R\        \         ,          /# )r   Ú	env_tokenr(  r   )r   r   r†   r   )r   s   "r   r   r     s6   € ÷ 	ñ 	´Sð 	ÄÌ$ÌsÔTWÈxÍ.ÕAYð 	Ô^fÔgjÕ^kñ 	r   c                óö   € V '       d?   \        V 4      '       d.   \        V\        4      '       d   VP                  R4      '       g   R# \	        V4      pV'       d   W 8w  d   \
        P                  R4       V# R# )zØPrefer refreshable Claude Code creds over a static env OAuth token: Hermes historically persisted setup tokens
into ANTHROPIC_TOKEN, and that static token would otherwise win before the refreshable file is inspected.rÇ   NzYPreferring Claude Code credential file over static env OAuth token so refresh can proceed)r2   r?   r†   r   r£  re   rf   )r¥  r(  Úresolveds   && r   Ú%_prefer_refreshable_claude_code_tokenr¨    sY   € ÷ œ/¨)×4Ò4¼ÀEÌ4×9PÒ9PÐUZ×U^ÑU^Ð_m×UnÒUnÙÜ:¸5ÓA€Hß�HÔ)Ü�‰ÐpÔqØˆÙr   Úskip_borrowedc                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r   r©  r   )r.   r   r   )r   s   "r   r   r   ‹  s   € ÷ ñ ´Dð ÄXÌcÅ]ñ r   c           
     ó–  a€  ^ RI HpHp V! R4      P                  RRR7      w  r4T Fô  pT '       d   TP                  R	8X  d   K  \        TR
R4      ;'       g    RP                  4       p\        TRR4      T8w  g	   T'       g   K_  \        \        TRR4      4      o\        ;QJ d,    T3R lT\        TRR4      3 4       F  '       g   K   RM!	  RM! T3R lT\        TRR4      3 4       4      '       d$   \
        P                  R\        TRR4      4       Kò  Tu # 	  R#   \         d    \
        P                  RRR7        R# i ; i)a9  First available Anthropic OAuth token from credential_pool, read-only: enumerates with ``clear_expired=False,
refresh=False`` (never ``select()``) so diagnostic call sites (account_usage, ``hermes models``) never mutate
auth.json or hit the network; refresh-on-expiry belongs to the API call path's pool recovery.)ÚAUTH_TYPE_OAUTHÚ	load_poolr<   F)Úclear_expiredrm  z(Failed to read Anthropic credential_poolTr“   Nr»   rÊ   r   Ú	auth_typer{   c              3   ó>   <"  € T F  p\        VSR 7      x € K  	  R# 5i)rx   N)rº   )r#   r¤   Úentry_source_paths   & €r   r%   Ú0_resolve_anthropic_pool_token.<locals>.<genexpr>Ÿ  s#   øé € ð 
áH�ô -¨VÐAR×SÑSÛHùs   ƒrc  zDSkipping Anthropic pool entry %s: rotated-but-uncommitted credentialÚidÚ?)Úagent.credential_poolr¬  r­  Ú_available_entriesr@   re   rf   r{   Úgetattrr(   r�   Úany)r©  r¬  r­  ÚentriesÚ_pendingÚentryÚtokenr±  s   $      @r   Ú_resolve_anthropic_pool_tokenr½  ‹  s.  ø€ ðßDÙ% kÓ2×EÑEÐTYÐchÐEÓiÑˆó ˆß˜UŸ\™\¨]Ô:Ùä˜ °Ó5×;Ð;¸×BÑBÓDˆÜ�5˜+ tÓ,°Ô?ÇuÙô 7´w¸uÀhÐPTÓ7UÓVÐß‹3ô 
à ¤'¨%°À$Ó"GÑHó
�3�3Š3ô 
à ¤'¨%°À$Ó"GÑHó
÷ 
ò 
ô �L‰LÐ_ÔahÐinÐptÐvyÓazÔ{ÙØŠñ! ñ" øô) ô Ü�‰Ð?È$ˆÔOÚðús   ƒ#D" Ä""EÅEc                ó~   € V ^8„  d   QhR\         \        ,          R\         \        ,          R\         \        ,          /# )r   r¼  Úmodelr   ©r   r   )r   s   "r   r   r   ©  s.   € ÷ ñ ¤h¬s¥mð ¼HÄS½Mð ÌhÔWZÍmñ r   c                óà   € V '       d	   V'       g   T ;'       g    R#  ^ RI Hp V! R4      P                  WR7      '       d   R#  V #   \         d    \        P                  RRR7        T # i ; i)zàReturn *token* unless the pool holds an active cooldown for it on *model*.

Only model-aware callers (the API-call paths) are gated: diagnostics that
resolve a token without a model (usage display, model discovery) keep it.
N)r­  r<   )r¿  z(Failed to check Anthropic model cooldownTr“   )rµ  r­  Útoken_is_blockedr@   re   rf   )r¼  r¿  r­  s   && r   Ú_available_anthropic_tokenrÃ  ©  sr   € ÷ ŸØ�}ˆ}˜ÐðPÝ3Ù�[Ó!×2Ñ2°5Ð2×FÒFÙð Gð €Løô	 ô Pô 	�‰Ð?È$ˆÕOØ€Lð	Pús   ž$A Á"A-Á,A-r¿  c                ó\   € V ^8„  d   QhR\         \        ,          R\         \        ,          /# )r   r¿  r   rÀ  )r   s   "r   r   r   ¼  s"   € ÷ ñ ¤h¬s¥mð ¼xÌ½}ñ r   c                ó>  € \         P                  ! \        4      p\        RR4      pV'       d%   \	        \        W!! 4       4      ;'       g    TV 4      # \        R4      pV'       d   \	        W04      # \	        \        RR7      ;'       g    \        V! 4       4      V 4      # )a  Resolve an Anthropic token from all sources in priority order (see module docstring).

With *model*, a token the credential pool has benched for that model resolves to ``None``
instead of being handed straight back to the caller that just saw it rate-limited.ÚANTHROPIC_TOKENÚCLAUDE_CODE_OAUTH_TOKENÚANTHROPIC_API_KEYT)r©  )Ú	functoolsÚcacher%  r+   rÃ  r¨  r½  r£  )r¿  Ú_read_credsr¼  Úapi_keys   $   r   Úresolve_anthropic_tokenrÍ  ¼  s�   € ô
 —/’/Ô">Ó?€KÜÐ(Ð*CÓD€EßÜ)Ü1°%¸»ÓG×PÐPÈ5ÐRWó
ð 	
ô Ð,Ó-€GßÜ)¨'Ó9Ð9ä%Ü%°DÔ9×wÐwÔ=hÑitÓivÓ=wØóð r   c                ó:   € V ^8„  d   QhR\         \        ,          /# rØ   rÀ  )r   s   "r   r   r   Ñ  s   € ÷ Lñ Lœx¬�}ñ Lr   c                 ó.  € ^ RI Hp  V ! R4      pV'       g   \        R4      h \        P                  ! VR.RR7       \        4       pT'       d   \        T4      '       d
   TR,          # \        R	R
4      ;'       g    R#   \
        \        3 d     R# i ; i)zjRun 'claude setup-token' interactively; the resulting token or None. FileNotFoundError if no 'claude' CLI.)Úfind_claude_code_cliÚclaudez\The 'claude' CLI is not installed. Install it with: npm install -g @anthropic-ai/claude-codezsetup-tokenF)rä   NrÆ   rÇ  rÆ  )
Úagent.anthropic_adapterrÐ  ÚFileNotFoundErrorrç   rè   ÚKeyboardInterruptÚEOFErrorr%  r   r+   )rÐ  Úclaude_pathr(  s      r   Úrun_oauth_setup_tokenr×  Ñ  s‰   € å<Ù& xÓ0€KßÜÐ ~ÓÐðÜ�Š˜ ]Ð3¸5ÕAô )Ó*€EßÔ+¨E×2Ò2Ø�]Õ#Ð#ÜÐ/Ð1BÓC×KÐKÀtÐKøô œxÐ(ô Úðús   £A? Á?BÂBc                ó$   € V ^8„  d   QhR\         /# rØ   r   )r   s   "r   r   r   å  s   € ÷ 7ñ 7¤ñ 7r   c                  ó$   € \        4       R ,          # )ú.anthropic_oauth.jsonr   r"   r   r   rÁ   rÁ   å  s   € ÜÓÐ6Õ6Ð6r   c                ó:   € V ^8„  d   QhR\         \        ,          /# rØ   )r   r   )r   s   "r   r   r   é  s   € ÷ ñ ¤¬$¥ñ r   c                 ó¶   €  ^ RI Hp  V ! 4       pVP                  RR7      \        4       P                  RR7      8X  d   R# VR,          #   \         d     R# i ; i)z¬Global-root ``.anthropic_oauth.json`` inside a named profile (None in classic mode); used to commit a
rotation of a grant the profile borrowed via the pool's root fallback.)Úget_default_hermes_rootF)ÚstrictNrÚ  )Úhermes_constantsrÝ  Úresolver	   r@   )rÝ  r  s     r   Ú_root_hermes_oauth_filerá  é  sh   € ðÝ<Ù&Ó(ˆØ—|‘|¨5�|Ó1´_Ó5F×5NÑ5NÐV[Ð5NÓ5\Ô\ˆtð  	AÐbfð  jAõ  cAð  	AøÜô Úðús   ‚=A	 Á A	 Á	AÁAc                ó$   € V ^8„  d   QhR\         /# rØ   )rÙ   )r   s   "r   r   r   ô  s   € ÷ ñ œñ r   c                 ó\  € \         P                  ! \        P                  ! ^ 4      4      P	                  R4      P                  4       p \         P                  ! \        P                  ! V P                  4       4      P                  4       4      P	                  R4      P                  4       pW3# )z6Generate PKCE code_verifier and code_challenge (S256).ó   =)
Úbase64Úurlsafe_b64encoder¬   Útoken_bytesÚrstriprÕ   r‚  rƒ  r  Údigest)ÚverifierÚ	challenges     r   Ú_generate_pkcerì  ô  sx   € ä×'Ò'¬×(;Ò(;¸BÓ(?Ó@×GÑGÈÓM×TÑTÓV€HÜ×(Ò(¬¯ª¸¿¹Ó8IÓ)J×)QÑ)QÓ)SÓT×[Ñ[Ð\`Óa×hÑhÓj€IØÐÐr   c                ó\   € V ^8„  d   QhR\         \        \        \        3,          ,          /# rØ   rö   )r   s   "r   r   r   û  s    € ÷ 4&ñ 4&¤X¬d´3¼°8­nÕ%=ñ 4&r   c                 ó„  € ^ RI p ^ RIHp \        4       w  r#\        P
                  ! ^ 4      pRRR\        RRR\        R\        R	VR
RRV/pRV! V4       2p\        RP                  RRRRRRRRRV 2R.
4      4        ^ RIHp V! 4       '       dH   \        P                  ! \        4      ;_uu_ 4        V P!                  V4       \        R4       RRR4       \        R4        \#        R4      P%                  4       pT'       g   \        R4       R# TP+                  R4      p	T	^ ,          \-        T	4      ^8”  d
   T	^,          MRrºY´8w  d   \.        P1                  R4       R#  \2        P4                  ! RRR\        RT
RTR\        R T/4      P7                  4       p\9        TR!^R"R#7      pTP;                  R%4      '       g   \        R&4       R# \=        T4      #   \         d    R p ELgi ; i  + '       g   i     EL(; i  \&        \(        3 d     R# i ; i  \         d   p\        R$T 24        Rp?R# Rp?ii ; i)'z>Run Hermes-native OAuth PKCE flow and return credential state.N)rq  r2  Útruerk  Úresponse_typeÚredirect_uriÚscopeÚcode_challengeÚcode_challenge_methodÚS256Ústatez"https://claude.ai/oauth/authorize?r  r   z7Authorize Hermes with your Claude Pro/Max subscription.uc   â•­â”€ Claude Pro/Max Authorization â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•®u9   â”‚                                                   â”‚u9   â”‚  Open this link in your browser:                  â”‚uŸ   â•°â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•¯z  )Ú_can_open_graphical_browserc                  ó   € R # )Tr"   r"   r   r   r¾   Ú-run_hermes_oauth_login_pure.<locals>.<lambda>  s   € ¡r   z   (Browser opened automatically)z7
After authorizing, you'll see a code. Paste it below.
zAuthorization code: zNo code entered.Ú#u0   OAuth state mismatch â€” possible CSRF, abortingrj  Úauthorization_codeÚcode_verifierrl  Úexchange)rN  râ   rZ   zToken exchange failed: rÊ   zNo access token in response.)Ú
webbrowserrn  rq  rì  r¬   Útoken_urlsafero  Ú_OAUTH_REDIRECT_URIÚ_OAUTH_SCOPESÚprintÚjoinr  r÷  r@   Ú
contextlibÚsuppressÚopenr�  r(   rÔ  rÕ  Úsplitr³   re   r‡  r`   r–   r  r_  r   rf  )rþ  rq  rê  rë  Úoauth_stateÚparamsÚauth_urlÚ_can_open_guiÚ	auth_codeÚsplitsr2  Úreceived_stateÚexchange_datarò   rg   s                  r   Úrun_hermes_oauth_login_purer  û  s3  € ãÝ&Ü(Ó*Ñ€HÜ×'Ò'¨Ó+€Kà�˜Ô%5°ÈÐP^Ô`sØ”Ð 0°)Ð=TÐV\Ð^eÐgrð€Fð 4±I¸fÓ4EÐ3FÐG€HÜ	ˆ$�)‰)Ø
ÐEÀrØmØCØCð 	jØ
ˆb��
ˆO˜Rðó ô ð%ÝPñ ‡‚Ü× Ò ¤×+Õ+Ø�O‰O˜HÔ%ÜÐ4Ô5÷ ,ô 
Ð
EÔFðÜÐ0Ó1×7Ñ7Ó9ˆ	÷ ÜÐ Ô!ÙØ�_‰_˜SÓ!€FØ! !�9´C¸³KÀ!´O v¨a¦yÈˆ.ØÔ$Ü�‰ÐIÔJÙðÜŸ
š
ØÐ.°Ô=MÈvÐW[Ð]dÐftØÔ/°À(ð$
ó ÷ ‰6‹8ð 	ô # =Ð?QÐ[]ÐdnÔoˆð �:‰:�n×%Ò%ÜÐ,Ô-ÙÜ˜fÓ%Ð%øô? ô %Ù$‹ð%ú÷ ,×+Ð+ûô œxÐ(ô Úðûô  ô ÜÐ'¨ sÐ+Ô,ÝûðúsI   Á>G Â3G/Ã$H Å$AH ÇG,Ç+G,Ç/H 	ÈHÈHÈH?È&H:È:H?c                ó\   € V ^8„  d   QhR\         \        \        \        3,          ,          /# rØ   rö   )r   s   "r   r   r   2  s#   € ÷ Jñ J¤x´´S¼#°XµÕ'?ñ Jr   c                 óh   € \        \        4       R4      p V e   V P                  R4      '       d   V # R# )zKRead Hermes-managed OAuth credentials from ~/.hermes/.anthropic_oauth.json.úHermes OAuth credentialsNrÆ   )rh   rÁ   r   r  s    r   Úread_hermes_oauth_credentialsr  2  s1   € äÔ 6Ó 8Ð:TÓU€DØÒ#¨¯©°×(?Ò(?ˆ4ÐIÀTÐIr   Útargetc          
      óŽ   € V ^8„  d   QhR\         R\        \         ,          R\        \        ,          R\        \        ,          RR/# )r   rÊ   rc  rd  r  r   N)r   r   r+  r   )r   s   "r   r   r   8  sB   € ÷ ñ ÜðÜ&.¬s¥mðÜDLÌSÅMðÜ^fÔgkÕ^lðà	ñr   c          	     óH   € \        Ve   TM	\        4       RV RVRV/R4       R# )a‘  Commit refreshed hermes_pkce tokens to ~/.hermes/.anthropic_oauth.json (``CredentialPersistError`` on failure).
``target`` lets a named profile commit a grant it BORROWED from the global root back to the ROOT singleton
instead of forking a copy under its own HERMES_HOME; without this write-through the next ``load_pool()``
re-seeds the stale (consumed) pair from the file over the rotated pool entry.NrÆ   rÇ   rÈ   r  )rr   rÁ   )rÊ   rc  rd  r  s   &&&$r   Ú_write_hermes_oauth_credentialsr  8  s.   € ô ØÒ$‰Ô*@Ó*BØ	˜ n°mÀ[ÐR_Ð`Ø"ör   c                ó‚   € V ^8„  d   Qh/ ^ \         9   d
   \        ;R&   ^\         9   d   \        \        R3,          ;R&   # )r   r…  Nr±   )Ú__conditional_annotations__rƒ   r   r   )r   s   "r   r   r      s>   € ÷ 	ñ 	÷V .Ò -¤#Ñ -ñW	÷X EÒ Dœk¬#¨t¨)Õ4Ñ DòY	r   )r   >   Úinvalid_grantÚinvalid_tokenÚrefresh_token_reusedr!   )fr  rT   rå  r  rÉ  r‚  r`   Úloggingr�   rå   rÎ   r¬   rç   Ú	threadingr,  Úcollectionsr   Úpathlibr   Útypingr   r   r   rß  r	   Úutilsr
   r   Úagent.secret_scoper   r   Ú	getLoggerrP   re   ro  rU  rr  r   r  ré   r   r+   r2   r7   rA   ÚRuntimeErrorrC   rh   rm   rr   ÚLockr°   rƒ   r…  r±   r™   r—   ry   r�   rŠ   r¢   rª   r·   rº   r~   rË   rî   rÖ   rô   rø   r
  r  r½   r  r%  r   Ú	frozensetr>  rp   r/  rE  rK  r_  rf  rs  r�  rˆ  rš  r”  r£  r¨  r½  rÃ  rÍ  r×  rÁ   rá  rì  r  r  r  r   )r  s   @r   Ú<module>r)     se  øðö	ó Û Û Û Û Û Û 	Û Û 	Û Û Û Û Ý #Ý ß &Ñ &å ,ß 6Ý 8à	×	Ò	˜8Ó	$€à9Ð ð 1Ð2`ðÐ ð
 (Ð ØIÐ Ø@€ð !:Ð ÷/õKõ
5õFðGÐZ^÷ Gô*˜\ô õõ1õ5ð !—~’~Ó'Ð ñ ),«Ð  Ó -Ù7B³}Ð Ó DØ Ð ð ð  õTõ(õ
rõdõ(>ð>ÐTX÷ >ðDÐSW÷ Dð Ñ9¸=ÑJjðÐ õ
	ð C€õ%õEõ<:õ@$õ Põ&õdõ
tõ(mñ $Ò$^Ó_Ð ôR˜*ô RõIõ
	LðEØRi÷Eð2ÐPR÷ ðLÈ÷ LõCðL]Ø[_ð]à!÷]õ0õ s÷Lõ&	ð¸5÷ õ<ð&°d÷ õ*Lõ(7õõõ4&õnJðØos÷ñ r   