+
    jHàjut ã                   óª  a € R½ t¥0 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HtHt ^ RIHtHtHt ^ RIHt ^ RIHtHtHtHtHtHt ^ RIHtHtH t H!t!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/H0t0 ^ RI1H2t3 ^ RI4H5t5H6t6H7t7H8t8H9t9H:t:H;t;H<t<H=t= ]P|                  ! ]?4      t@R R ltARtBR R ltCRRRRR]BRRRRRRRR R!R"R#R$0tD]]/R%0,
          ,          tE]F! R&04      tGR'R(R)R*R+R,](0tHR- R. ltIR¾tJR/R0.]JO5tK0 R¿mtLR1R2]$ 23tM0 RÀmtN ^ RIOtO]OP                   3tQ] ^ k ]P¦                  ]P¨                  ]U.]QO5tV] ^k 0 RÂmtWR3tX ! R4 R5]Y4      tZ ! R6 R7]Y4      t[]RÃR8 R9 ll4       t\]RÄR: R; ll4       t]R< R= lt^R> R? lt_R@ RA lt`RB RC ltaRD RE ltbRÄRF RG lltcRH RI ltdRJ^dRKRL/RM RN llteROtfRÅtgRPRQRRRQRS]g/RT RU llthRV RW ltiRX RY ltjRZ R[ ltkR\ R] ltlR^ R_ ltmR`tnRa Rb ltoRc Rd ltpRe Rf ltqRg Rh ltrRi Rj ltsRk Rl lttRm Rn ltuRo Rp ltvRq Rr ltwRs Rt ltxRu Rv ltyRw Rx ltzRÆt{^t|RÄRz R{ llt}R| R} lt~RytR~ R lt€Rt�R€t‚^tƒR�t„^t…R‚t†Rƒ R„ lt‡R… R† ltˆR‡ Rˆ lt‰R]ƒ3R‰ RŠ lltŠR]…3R‹ RŒ llt‹RÇR� RŽ lltŒRÇR� R� llt�RÈR‘ R’ lltŽR“ R” lt�RÄR• R– llt�R— R˜ lt‘R™ Rš lt’RÄR› Rœ llt“R� Rž lt”RŸ R  lt•RÄR¡ R¢ llt–R£ R¤ lt—RÉR¥ R¦ llt˜RÊt™] ^k R§ R¨ ltšR© Rª lt›R« R¬ ltœRÄR­ R® llt�RÄR¯ R° lltžRÄR± R² lltŸ]|3R³ R´ llt ]|R3Rµ R¶ llt¡R· R¸ lt¢R¹ Rº lt£R» R¼ lt¤R#   ]R d    RÁtQ ELi ; i)Ëz*Backup and import commands for hermes CLI.N)ÚcontextmanagerÚsuppress)ÚdatetimeÚtimezoneÚUTC©ÚPath)ÚAnyÚCallableÚDictÚListÚOptionalÚTuple)ÚLOCAL_RUNTIME_ROOT_DIRSÚ!_get_platform_default_hermes_homeÚget_default_hermes_rootÚget_hermes_homeÚdisplay_hermes_home)ÚRETIRED_GENERATION_DIR_SUFFIX)Úread_only_db_uri)ÚGENERATED_SUBDIR)Únormalize_archive_parts)Ú_close_quietlyÚ_safe_copy_db)ÚPM_RUNTIME_ROOT_DIRSÚprofile_root_entry)Úformat_bytes)	Ú_count_session_rowsÚ_default_new_file_modeÚ_detect_prefixÚ_extract_member_atomicallyÚ_import_db_memberÚ_restore_auth_jsonÚ_restore_destination_epochÚ_safe_restore_dbÚ_validate_backup_zipc                ó\   € V ^8„  d   QhR\         R\        \        \        ,          ,          /# )é   Údb_pathÚreturn)r   r   ÚlistÚint)Úformats   "Ú6/home/ubuntu/.hermes/hermes-agent/hermes_cli/backup.pyÚ__annotate__r.   0   s#   € ÷ ñ ¤Tð ¬h´t¼CµyÕ.Añ ó    c                 ó   € R # ©N© )r(   s   &r-   Ú_foreign_db_holder_pidsr3   0   s   € ñ r/   zstate-snapshotsc                ó$   € V ^8„  d   QhR\         /# ©r'   r)   ©Ústr)r,   s   "r-   r.   r.   =   s   € ÷ 4ñ 4¤ñ 4r/   c                 ó   € R# )u¢   How to restore a state snapshot. There is no `hermes snapshot` subcommand â€” only the /snapshot
slash command inside a `hermes` session (hermes_cli/commands.py).z}To restore a newer snapshot, start `hermes` in a terminal and run `/snapshot list`, then `/snapshot restore <id>` (CLI only).r2   r2   r/   r-   Ú_snapshot_recovery_hintr9   =   s   € ñ3r/   úhermes-agentÚ__pycache__z.gitÚnode_modulesÚbackupsÚcheckpointszbrowser-profileszbrowser-profilez.venvÚvenvzsite-packagesz.cachez.toxz.noxz.pytest_cachez.mypy_cachez.ruff_cacheÚcacheÚbrowser_profilesÚimagesÚaudioÚvideosÚ	documentsÚscreenshotsÚ	citationsc                ó0   € V ^8„  d   QhR\         R\        /# ©r'   Úrel_pathr)   ©r   Úbool)r,   s   "r-   r.   r.   n   s   € ÷ [ñ [¤Dð [¬Tñ [r/   c                ó6  € \        V P                  4      pV\        9   g   V\        9   d   R# V P                  p\	        V4      ^8¼  d   V^ ,          R8X  d
   VR,          p\	        V4      ^8¬  ;'       d%    V^ ,          R8H  ;'       d    V^,          \
        9  # )zITrue when *rel_path* is inside a regenerable tree at a profile-home root.TÚprofiles:r'   NNr@   )r   ÚpartsÚ_EXCLUDED_ROOT_DIRSÚ_EXCLUDED_BACKUP_ROOT_DIRSÚlenÚ_KEPT_CACHE_SUBDIRS)rJ   Ú
root_entryrO   s   &  r-   Ú_in_excluded_root_dirrU   n   s}   € ä# H§N¡NÓ3€JØÔ(Ô(¨JÔ:TÔ,TÙØ�N‰N€EÜ
ˆ5ƒz�Q„˜5 �8 zÔ1Ø�b•	ˆÜˆu‹:˜‰?×ZÐZ˜u Q�x¨7Ñ2×ZÐZ°u¸QµxÔGZÑ7ZÐZr/   z.pycz.pyozstate.db.pre-update-emergency-ústate.dbz
_external/c                   ó   € ] tR t^­tRtRtR# )ÚBackupInProgressErrorz@Raised when another process already owns the Hermes backup slot.r2   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__static_attributes__r2   r/   r-   rX   rX   ­   s   † ÝJr/   rX   c                   ó   € ] tR t^±tRtR# )Ú_SQLiteSnapshotErrorr2   N)rY   rZ   r[   r\   r^   r2   r/   r-   r`   r`   ±   s   † Ûr/   r`   c                ó0   € V ^8„  d   QhR\         R\        /# )r'   Úhermes_homeÚtimeout_seconds)r   Úfloat)r,   s   "r-   r.   r.   ¶   s   € ÷ #ñ #¬ð #¼uñ #r/   c           	   #  óZ  aa	a
"  € V R,          pVP                   P                  RRR7       VP                  R4      o	Rp\        P                  ! 4       \        RV4      ,           p \        P                  R8X  dg   ^ RIo
VP                  4       P                  ^ 8X  d"   S	P                  R	4       S	P                  4        R
 V	V
3R llpS
P                  S
P                  rvM6^ RIoR VV	3R llpSP                   SP"                  ,          SP$                  rvV'       g    V! V4       RpK  Rx € V'       d)   \-        \&        4      ;_uu_ 4        V! V4       RRR4       S	P/                  4        R#   \&         d@    \        P                  ! 4       T8¼  d   \)        R4      h\        P*                  ! R4        K¤  i ; i  + '       g   i     Lo; i  T'       d=   \-        \&        4      ;_uu_ 4        X! X4       RRR4       M  + '       g   i     M; iS	P/                  4        i ; i5i)zCAcquire one cross-process backup slot for full and quick snapshots.ú.backup.lockT©ÚparentsÚexist_okza+bFg        ÚntNó    c                ó(   € V ^8„  d   QhR\         RR/# ©r'   Úflagr)   N©r+   )r,   s   "r-   r.   Ú,_backup_operation_lock.<locals>.__annotate__Ã   s   € ÷ 9ñ 9œsð 9 tñ 9r/   c                 ól   <€ SP                  ^ 4       SP                  SP                  4       V ^4       R# )é    N)ÚseekÚlockingÚfileno)rn   ÚhandleÚmsvcrts   &€€r-   Ú_lock_opÚ(_backup_operation_lock.<locals>._lock_opÃ   s$   ø€ Ø—‘˜A”Ø—‘˜vŸ}™}›°°aÖ8r/   c                ó(   € V ^8„  d   QhR\         RR/# rm   ro   )r,   s   "r-   r.   rp   É   s   € ÷ 3ñ 3œsð 3 tñ 3r/   c                 óH   <€ SP                  SP                  4       V 4       R # r1   )Úflockru   )rn   Úfcntlrv   s   &€€r-   rx   ry   É   s   ø€ Ø—‘˜FŸM™M›O¨TÖ2r/   z(another Hermes backup is already runninggš™™™™™©?)ÚparentÚmkdirÚopenÚtimeÚ	monotonicÚmaxÚosÚnamerw   ÚstatÚst_sizeÚwriteÚflushÚLK_NBLCKÚLK_UNLCKr}   ÚLOCK_EXÚLOCK_NBÚLOCK_UNÚOSErrorrX   Úsleepr   Úclose)rb   rc   Ú	lock_pathÚacquiredÚdeadlinerx   Ú	lock_flagÚunlock_flagr}   rv   rw   s   &&      @@@r-   Ú_backup_operation_lockr—   µ   s‚  úé € ð ˜nÕ,€IØ×Ñ×Ñ 4°$ÐÔ7Ø�^‰^˜EÓ"€FØ€HÜ�~Š~Ó¤# c¨?Ó";Õ;€HðÜ�7‰7�dŒ?ÛØ�~‰~Ó×'Ñ'¨1Ô,Ø—‘˜TÔ"Ø—‘”÷9ñ 9ð &,§_¡_°f·o±o‘{ã÷3ñ 3à%*§]¡]°U·]±]Õ%BÀEÇMÁM�{ßð!Ù˜Ô#Ø’ó
 	çÜœ'×"Õ"Ù˜Ô%÷ #à�‰Žøô ô !Ü—>’>Ó# xÔ/Ü/Ð0ZÓ[Ð[Ü—
’
˜4× ð!ú÷ #×"û÷ Üœ'×"Õ"Ù˜Ô%÷ #×"×"Ð"úà�‰�üst   …A H+Á&B8G Ä 
E2 Ä*G Ä0H+Å	F?ÅH+Å2AF<Æ8G Æ;F<Æ<G Æ?G	Ç
H+Ç H(Ç2	H	Ç;	H(ÈHÈH(È(H+c                óv   € V ^8„  d   QhR\         R\        \        . \        \         ,          3,          ,          /# )r'   Ú
final_pathÚpublish_path)r   r   r
   )r,   s   "r-   r.   r.   Ý   s.   € ÷ ñ ¤Dð ¼ÄÈ"ÌhÔW[ÍnÐJ\ÕA]Õ8^ñ r/   c           	   #  ó”  "  € V P                  RV P                   R\        P                  ! 4        R\        P
                  ! 4        R24      pVP                  RR7        Vx € V'       d   V! 4       MT pVf   VP                  RR7       R# \        P                  ! W#4       R#   \         d    TP                  RR7       h i ; i5i)a5  Yield a hidden sibling path and publish it only after a clean close.

``publish_path`` picks the destination at publish time (default ``final_path``) so a caller
can divert an incomplete archive elsewhere without ever touching ``final_path``; returning
``None`` discards the partial instead of publishing it.
Ú.Ú-ú.partialT©Ú
missing_okN)	Ú	with_namer…   r„   ÚgetpidÚ	threadingÚ	get_identÚunlinkÚreplaceÚBaseException)r™   rš   Úpartial_pathÚdestinations   &&  r-   Ú_atomic_output_pathrª   Ü   s®   é € ð ×'Ñ'¨!¨J¯O©OÐ+<¸A¼b¿iºi»k¸]È!ÌI×L_ÒL_ÓLaÐKbÐbjÐ(kÓl€LØ×Ñ 4ÐÔ(ð	ØÒß(4‘l”n¸*ˆØÒØ×Ñ¨4ÐÖ0ä�JŠJ�|Ö1øÜô Ø×Ñ tÐÔ,Øðüs*   ‚ACÁ!+B& ÂCÂB& Â$CÂ&CÃCc                ó:   € V ^8„  d   QhR\         \        ,          /# r5   )r*   r   )r,   s   "r-   r.   r.   ò   s   € ÷ ñ ´´dµñ r/   c                 óR  €  ^ RI Hp Hp V ! 4       pV'       d	   V! V4      MRpTf   . #  TP	                  4       ;'       g    . p/ pT FW  p \        T4      P                  4       pTP                  4       '       g   K5   TP                  4       p	TP                  Y˜4       KY  	  \        TP                  4       4      #   \         d    . u # i ; i  \         d#   p\
        P                  RY%4       . u Rp?# Rp?ii ; i  \         d     KÅ  i ; i  \        \        3 d     KÝ  i ; i)z�Existing paths the active memory provider declares via ``backup_paths()``; ``[]`` on any
provider failure (backup must never fail because of a flaky plugin).)Ú_get_active_memory_providerÚload_memory_providerNz0backup_paths() failed for memory provider %r: %s)Úplugins.memoryr­   r®   Ú	ExceptionÚbackup_pathsÚloggerÚwarningr   Ú
expanduserÚexistsÚresolver�   Ú
ValueErrorÚ
setdefaultr*   Úvalues)
r­   r®   ÚactiveÚproviderÚdeclaredÚexcÚoutÚrawÚpÚresolveds
             r-   Ú'_collect_memory_provider_external_pathsrÂ   ò   s  € ðßTÙ,Ó.ˆß39Ñ'¨Ô/¸tˆð ÒØˆ	ðØ×(Ñ(Ó*×0Ð0¨bˆð €CÛˆð	Ü�S“	×$Ñ$Ó&ˆAð �x‰x�zŠzÙð	Ø—y‘y“{ˆHð 	�‰�xÖ#ñ ô �—
‘
“ÓÐøô- ô ØŠ	ðûô ô Ü�‰ÐIÈ6ÔWØ�	ûðûô ô 	Úð	ûô œÐ$ô 	Úð	ús]   ‚B< ™
B< ªC ÁC ÁC?Á>DÂ<CÃCÃC<ÃC7Ã1C<Ã7C<Ã?DÄDÄD&Ä%D&c                óF   € V ^8„  d   QhR\         R\        \         ,          /# )r'   Úbaser)   ©r   r*   )r,   s   "r-   r.   r.     s   € ÷ ñ œtð ¬¬T­
ñ r/   c                ón  a€ V P                  4       '       d   V P                  4       '       g   V .# V P                  4       '       g   . # . p\        P                  ! V RR7       FI  w  or#V Uu. uF  qD\
        9  g   K  VNK  	  upVR&   VP                  R V3R lV 4        4       4       KK  	  V# u upi )zWRegular files under *base* (a file or a directory), skipping symlinks, caches, and pyc.F©ÚfollowlinksºNNNc              3   óÈ   "  € T FX  p\        V4      '       d   K  VP                  \        9   d   K-  VP                  P                  \        4      '       d   KT  Vx € KZ  	  R # 5ir1   )Ú_is_non_regular_pathr…   Ú_EXCLUDED_NAMESÚendswithÚ_EXCLUDED_SUFFIXES)Ú.0Úfps   & r-   Ú	<genexpr>Ú'_iter_external_files.<locals>.<genexpr>  sK   é € ð GÑ"H˜BÜ1°"×5ô Ø9;¿¹ÄOÑ9Sô à "§¡× 0Ñ 0Ô1C× D÷ ’RÓ"Hùs   ‚A"šA"±"A"Á
A"c              3   óH   <"  € T F  p\        S4      V,          x € K  	  R # 5ir1   r   )rÏ   ÚfÚdirpaths   & €r-   rÑ   rÒ     s   øé € Ð"H¹i¸¤4¨£=°1×#4Ò#4»iùó   ƒ")Úis_fileÚ
is_symlinkÚis_dirr„   ÚwalkÚ_EXCLUDED_DIRSÚextend)rÄ   ÚfilesÚdirnamesÚ	filenamesÚdrÕ   s   &    @r-   Ú_iter_external_filesrá     sž   ø€ à‡|�|‡~‚~˜dŸo™o×/Ò/ØˆvˆØ�;‰;�=Š=Øˆ	Ø€EÜ(*¯ª°À%×(HÑ$ˆ�Ù"*ÓF¡(˜Q´~Ñ.E—q�q¡(ÑFˆ�‰Ø�‰ñ GÔ"H¹iÔ"Hó Gö 	Gñ )Ið
 €Lùò	 Gs   Á-B2Á>B2c                ó0   € V ^8„  d   QhR\         R\        /# ©r'   Úpathr)   rK   )r,   s   "r-   r.   r.   !  s   € ÷ 	ñ 	œtð 	¬ñ 	r/   c                óŽ   €  \         P                  ! V P                  4       P                  4      '       * #   \         d     R# i ; i)zôTrue for symlinks, sockets, devices, and other non-regular filesystem entries.

A failed ``lstat`` is not treated as an exclusion: the archive writer must see the path and
report the read failure instead of silently claiming a complete backup.
F)r†   ÚS_ISREGÚlstatÚst_moder�   )rä   s   &r-   rË   rË   !  s7   € ðÜ—<’< §
¡
£× 4Ñ 4Ó5Ô5Ð5øÜô Úðús   ‚25 µAÁAc                ó0   € V ^8„  d   QhR\         R\        /# rã   rK   )r,   s   "r-   r.   r.   -  s   € ÷ 
pñ 
pœð 
p¤ñ 
pr/   c                ó$  €  V P                  4       p\        P                  ! TP                  4      '       d   R# \
        P                  R8H  ;'       d,    \        \        TR^ 4      \        P                  ,          4      #   \         d     R# i ; i)uÒ   True for symlinks and Windows junctions/reparse points â€” the only
directory entries a strict walk must never descend (os.walk already
refuses POSIX dir symlinks; this also covers junctions, which it follows).FTrj   Úst_file_attributes)
rç   r�   r†   ÚS_ISLNKrè   r„   r…   rL   ÚgetattrÚFILE_ATTRIBUTE_REPARSE_POINT)rä   Úinfos   & r-   Ú_is_link_pathrð   -  sn   € ðØ�z‰z‹|ˆô ‡|‚|�D—L‘L×!Ò!ÙÜ�7‰7�d‰?×oÐoœt¤G¨DÐ2FÈÓ$JÌT×MnÑMnÕ$nÓoÐoøô	 ô Úðús   ‚B  Â BÂBc                ó0   € V ^8„  d   QhR\         R\        /# rI   rK   )r,   s   "r-   r.   r.   :  s   € ÷ 	oñ 	oœdð 	o¤tñ 	or/   c                ód  a€ V P                   o\        V 4      '       d   R# \        ;QJ d    V3R lS 4       F  '       g   K   RM	  RM! V3R lS 4       4      '       d   R# V P                  pV\        9   ;'       g3    VP                  \        4      ;'       g    VP                  \        4      # )zFReturn True if *rel_path* (relative to hermes root) should be skipped.Tc              3   óv   <"  € T F.  q\         9   ;'       d    VR 8g  ;'       g    VS^ ,          8H  x € K0  	  R# 5i)r:   N)rÛ   )rÏ   rÀ   rO   s   & €r-   rÑ   Ú"_should_exclude.<locals>.<genexpr>@  s6   øé € Ð
YÑSXÈa”Ñ×IÐI A¨Ñ$7×$HÐ$H¸1ÀÀaÅ¹=ÔIÓSXùs   ƒ9—9¤9F)	rO   rU   Úanyr…   rÌ   Ú
startswithÚ_EXCLUDED_PREFIXESrÍ   rÎ   )rJ   r…   rO   s   & @r-   Ú_should_excluderø   :  sx   ø€ à�N‰N€EÜ˜X×&Ò&Ùç
ƒsÔ
YÑSXÓ
Y‡s‡s‚sÔ
YÑSXÓ
Y×YÒYÙØ�=‰=€DØ”?Ñ"×nÐn d§o¡oÔ6HÓ&I×nÐnÈTÏ]É]Ô[mÓMnÐnr/   c                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# )r'   Úhermes_rootÚout_pathÚskipped_dirs)r   r   Úset)r,   s   "r-   r.   r.   F  s&   € ÷ ñ ¤Dð ´Dð ÌÔQTÍñ r/   c           	   #  ó†  a"  € \         P                  ! V RR7       EF�  w  r4p\        V4      P                  V 4      oS\        R4      8H  pV Uu. uF=  pV\        9  g   VR8X  g   K  V'       d   K!  \        SV,          4      '       d   K;  VNK?  	  ppVe5   VP                  V3R l\        V4      \        V4      ,
           4       4       V U	u. uF(  p	\        \        V4      V	,          4      '       d   K&  V	NK*  	  up	VR&   V F“  p
SV
,          pW,          p\        V4      '       d   K'  \        V4      '       d   K:  \        \        \        4      ;_uu_ 4        VP                  4       VP                  4       8X  d    RRR4       K…   RRR4       WË3x € K•  	  EK„  	  R# u upi u up	i   + '       g   i     L*; i5i)aN  Yield ``(abs_path, rel_path)`` for every file a full backup should hold.

The one owner of the walk policy (directory pruning so os.walk never descends a multi-GB
excluded tree, the root-only ``hermes-agent`` carve-out, root runtime trees, per-file rules),
shared by ``hermes backup`` and the pre-update path so they can never drift.
FrÇ   rœ   r:   Nc              3   óH   <"  € T F  p\        SV,          4      x € K  	  R # 5ir1   r6   )rÏ   rà   Úrel_dirs   & €r-   rÑ   Ú%_iter_backup_files.<locals>.<genexpr>U  s   øé € ÐTÑ:S°Q¤ G¨a¥K× 0Ð 0Ó:SùrÖ   rÉ   )r„   rÚ   r   Úrelative_torÛ   rU   Úupdaterý   rð   rø   rË   r   r�   r·   r¶   )rú   rû   rü   rÕ   rÞ   rß   Úis_rootrà   Úkeptr…   ÚfnameÚrelÚfpathr   s   &&&          @r-   Ú_iter_backup_filesr	  F  sr  øé € ô )+¯ª°È×(OÐ(OÑ$ˆ˜9Ü�w“-×+Ñ+¨KÓ8ˆØœT #›YÑ&ˆáó8Ù�!ØœÔ'¨A°Ñ,?ô ÜHOô ä)¨'°A­+×6÷ ˆA‘xð 	ð 8ð Ò#Ø×ÑÔT¼#¸h»-Ì#ÈdË)Ö:SÓTÔTá(,ÓX© ´MÄ$ÀwÃ-ÐRVÕBV×4W—t�t©ÑXˆ�‰ÛˆEØ˜E•/ˆCØÕ%ˆEô ˜s×#Ò#ÙÜ# E×*Ò*ÙÜœ'¤:×.Õ.Ø—=‘=“? h×&6Ñ&6Ó&8Ô8Ø÷ /Ñ.Ø8÷ /ð �*Ôô ó )Pùò8ùò Y÷ /×.üsU   ƒAGÁF$Á(F$Á2F$ÂF$Â>GÃ#F)Ã8F)Ã>AGÅ%F.	Æ
GÆ"GÆ.F>Æ9Gc                ó$   € V ^8„  d   QhR\         /# )r'   rä   r   )r,   s   "r-   r.   r.   i  s   € ÷ 	ñ 	œ4ñ 	r/   c                óä   € Rp \         P                  ! \        V 4      RRR7      pV! V4      R3\        V4       #   \         d   pRT3u Rp?\        T4       # Rp?ii ; i  \        T4       i ; i)zbRun ``fn(conn)`` on a read-only connection to *path*; return ``(value, None)`` or ``(None, exc)``.NTg      ð?)ÚuriÚtimeout)Úsqlite3Úconnectr   r   r°   )rä   ÚfnÚconnr½   s   &&  r-   Ú_query_ro_sqliter  i  sh   € à€DðÜ�ŠÔ/°Ó5¸4ÈÔMˆÙ�$‹x˜ˆ~ô 	�tÕøô ô Ø�SˆyÔä�tÕûðûô 	�tÕús-   „+; »AÁAÁ	AÁ
A" ÁAÁA" Á"A/Úprobe_bytesÚforceFc                óH   € V ^8„  d   QhR\         R\        R\        R\        /# )r'   rä   r  r  r)   )r   r+   rL   )r,   s   "r-   r.   r.   u  s/   € ÷ Zñ Z¤ð Z´cð ZÌð ZÔY]ñ Zr/   c               ó8  €  V P                  4       '       g   R#  ^ RIHpHp T'       g   T! T 4      '       d   R# T! T \        ^T4      TR7      pTRJ;'       d/    TP                  R4      '       * ;'       d    \        T4      '       * #   \         d     R# i ; i)u©  True when *path* looks like the #68474 zeroed-state.db signature.

Only regular files qualify: probing a FIFO/device/socket could block indefinitely.

Signature: no ``SQLite format 3`` header and no data â€” either empty (size 0, the total-loss case,
#97568) or first *probe_bytes* all NUL. Used at SessionDB open and for snapshot diagnostics so a silent
all-zero file becomes a guided recovery instead of a generic failure.
F)Úhas_live_connectionÚread_header_bytes_preopen)Úlengthr  Ns   SQLite format 3)r×   r�   Úhermes_cli.sqlite_safe_readr  r  rƒ   rö   rõ   )rä   r  r  r  r  Úheads   &$$   r-   Úis_zeroed_sqlite_filer  u  s‹   € ðØ�|‰|�~Š~Ùð ÷ [ßÑ(¨×.Ò.Ùá$ T´#°b¸+Ó2FÈeÔT€Dà�tÐ×YÐY D§O¡OÐ4FÓ$GÔ G×YÐYÔPSÐTXÓPYÌMÐYøô ô Úðús   ‚B
 Â
BÂBs   SQLite format 3 Úcheck_headerTÚ
run_pragmaÚ	max_bytesc          
      óT   € V ^8„  d   QhR\         R\        R\        R\        R\        /# )r'   rä   r  r  r  r)   )r   rL   r+   Údict)r,   s   "r-   r.   r.   ˜  s4   € ÷ /?ñ /?Ü
ð/?Ü!%ð/?Ü:>ð/?äð/?ä;?ñ/?r/   c               óœ  € R#R R llp V P                  4       pTP                  pT^d8  d   T! RT R2TR7      # T'       d[   ^ R	IHp T! T \        \        4      R
7      p	T	f   T! RTR7      # T	\        8w  d%   T! RT	R,          P                  4       : R2TR7      # T^ 8”  db   Ys8”  d\   \        T R 4      w  r¦Te5   \        T\        P                  4      '       d   RMRpT! RT RT 2TR7      # T! RTR RTR R2RTR7      # T'       d}   \        T R 4      w  rÆTe4   \        T\        P                  4      '       d   RMRpT! T RT 2TR7      # TR.8X  d   T! RRTR7      # T! RR P                  TR!,          4       2TR7      # T! R"RTR7      #   \         d    T! RT  24      u # \         d   pT! RT 24      u Rp?# Rp?ii ; i)$z Verify a SQLite database: existence + minimum size, header magic, then a read-only
``PRAGMA integrity_check`` (or a cheap structural probe above ``max_bytes``).Nc                ó^   € V ^8„  d   QhR\         R\        R\        \        ,          R\        /# )r'   ÚmessageÚvalidÚsizer)   )r7   rL   r   r+   r!  )r,   s   "r-   r.   Ú-verify_sqlite_integrity.<locals>.__annotate__�  s3   € ÷ Bñ B”sð B¤4ð B´xÄµ}ð BÔPTñ Br/   c                 ó   € R VRV RV/# )r%  r$  r&  r2   )r$  r%  r&  s   &&&r-   Ú_doneÚ&verify_sqlite_integrity.<locals>._done�  s   € Ø˜ 	¨7°F¸DÐAÐAr/   znot found: zcannot stat: ztoo small (z% bytes) to be a valid SQLite database)r&  )r  )r  zcannot read headerz!missing SQLite header magic (got :Né   NÚ)c                 ó~   € V P                  R 4      P                  4       V P                  R4      P                  4       3# )zPRAGMA schema_versionz"SELECT count(*) FROM sqlite_master)ÚexecuteÚfetchone)Úcs   &r-   Ú<lambda>Ú)verify_sqlite_integrity.<locals>.<lambda>´  s4   € Ø�I‰IÐ-Ó.×7Ñ7Ó9Ø�I‰IÐ:Ó;×DÑDÓFñ3Hr/   ÚfailedÚerrorzschema probe ú: zsize Ú,z bytes exceeds max_bytes z?; skipped PRAGMA integrity_check (header + schema probe passed)T)r%  r&  c                 ón   € V P                  R 4       Uu. uF  p\        V^ ,          4      NK  	  up# u upi )zPRAGMA integrity_check)r.  r7   )r0  Úrs   & r-   r1  r2  À  s*   € °·	±	Ð:RÔ0SÓTÑ0S¨1œS  1¥žYÑ0SÒTùÒTs   ”2zcannot open databasezintegrity check errorÚokzintegrity check passedzintegrity check failed: ú; :Né   Nzheader check passed)FN)r†   ÚFileNotFoundErrorr�   r‡   r  r  rR   Ú_SQLITE_HEADERÚhexr  Ú
isinstancer  ÚDatabaseErrorÚjoin)rä   r  r  r  r)  Ústr½   r&  r  r  Ú_ÚkindÚrowss   &$$$         r-   Úverify_sqlite_integrityrF  ˜  s  € ÷
Bð,Ø�Y‰Y‹[ˆð
 �:‰:€DØˆc„zÙ�{ 4 &Ð(MÐNÐUYÔZÐZßõ 	JÙ(¨´c¼.Ó6IÔJˆØŠ<ÙÐ-°DÔ9Ð9Ø”>Ô!ÙÐ<¸TÀ#½Y¿]¹]»_Ñ<OÈqÐQÐX\Ô]Ð]Ø�1„}˜Ô)ô " $ñ )Hó I‰ˆð Š?Ü)¨#¬w×/DÑ/D×EÒE‘8È7ˆDÙ˜=¨¨¨b°°Ð6¸TÔBÐBÙØ�D˜�8Ð4°Y¸q°Mð BLð Là˜Tô#ð 	#÷ Ü$ØÑTóV‰	ˆàŠ?Ü-7¸¼W×=RÑ=R×-SÒ-SÑ)ÐYpˆDÙ˜D˜6  C 5Ð)°Ô5Ð5Ø�D�6Œ>ÙÐ1¸ÀDÔIÐIÙÐ/°·	±	¸$¸r½(Ó0CÐ/DÐEÈDÔQÐQÙÐ&¨d¸Ô>Ð>øôM ô +Ù�{ 4 &Ð)Ó*Ò*Üô ,Ù�} S EÐ*Ó+Õ+ûð,ús)   ŠF ÆGÆ,GÆ5GÆ6
GÇ GÇGc                óH   € V ^8„  d   QhR\         P                  R\        RR/# )r'   ÚzfÚfilelist_lenr)   N)ÚzipfileÚZipFiler+   )r,   s   "r-   r.   r.   Ê  s*   € ÷ Hñ H¤G§O¡Oð HÄ3ð HÈ4ñ Hr/   c                ó˜  € \        V P                  4      V8:  d   R# V P                  V,          P                  pV P                  P	                  V4       V P                  P                  4        W n        V P                  VR1 V P                  P                  4        V P                  P                  R V P                   4       4       R# )aŽ  Drop the member(s) created by a failed write, both from the central directory and the file.

ZipFile.write finalizes its destination member while unwinding a source-read
failure, so the partial bytes can otherwise become a CRC-valid archive member.
This runs immediately after that failed write, so the dropped bytes are the tail
of the file: truncate at the first dropped local header and rewind start_dir so
later members overwrite it. Leaving the bytes (with a valid local header) would
still expose a ghost member to streaming readers. Rebuilding NameToInfo from the
surviving file list also restores the previous entry when a duplicate name failed.
Nc              3   ó<   "  € T F  qP                   V3x € K  	  R # 5ir1   )Úfilename)rÏ   rï   s   & r-   rÑ   Ú._discard_failed_zip_members.<locals>.<genexpr>Ý  s   é € ÐG¹;°4Ÿ-™-¨Õ.»;ùs   ‚)
rR   ÚfilelistÚheader_offsetrÐ   rs   ÚtruncateÚ	start_dirÚ
NameToInfoÚclearr  )rH  rI  Úoffsets   && r-   Ú_discard_failed_zip_membersrW  Ê  s‰   € ô ˆ2�;‰;Ó˜<Ô'ÙØ�[‰[˜Õ&×4Ñ4€FØ‡E�E‡J�JˆvÔØ‡E�E‡N�NÔØ„LØ
�‰�L‘MÐ"Ø‡M�M×ÑÔØ‡M�M×ÑÑG¸2¿;º;ÓGÖGr/   c                óT   € V ^8„  d   QhR\         P                  R\        R\        RR/# )r'   rH  rä   Úarcnamer)   N)rJ  rK  r   r7   )r,   s   "r-   r.   r.   à  s,   € ÷ ñ œŸ™ð ¬tð ¼cð Àdñ r/   c                óŒ   € \        V P                  4      p V P                  WR7       R#   \         d    \	        Y4       h i ; i)zSWrite one member while keeping a failed partial write out of the central directory.)rY  N)rR   rP  rˆ   r°   rW  )rH  rä   rY  rI  s   &&& r-   Ú_write_zip_filer[  à  s=   € ä�r—{‘{Ó#€LðØ
�‰�ˆÖ'øÜô Ü# BÔ5Øðús	   —+ «Ac                ó~   € V ^8„  d   QhR\         P                  R\        R\        R\        R\        \        ,          /# )r'   rH  Úabs_pathrJ   rû   r)   )rJ  rK  r   r   r+   )r,   s   "r-   r.   r.   ê  s;   € ÷ 'ñ 'œWŸ_™_ð '¼ð 'Ìð 'ÔX\ð 'ÔaiÔjmÕanñ 'r/   c                óÌ  € \         P                  ! RR\        VP                  4      R7      ;_uu_ 4       p\	        VP
                  4      pRRR4        \        VX4      '       g    VP                  RR7       R# \        W\        V4      4       VP                  4       P                  VP                  RR7       #   + '       g   i     Ly; i  XP                  RR7       i ; i)z´Add a WAL-safe snapshot of *abs_path* to *zf*; return its byte size, or None on failure.

Staged beside the output zip: /tmp may be a small tmpfs that cannot hold large databases.
ú.dbF)ÚsuffixÚdeleteÚdirNTrŸ   )ÚtempfileÚNamedTemporaryFiler7   r~   r   r…   r   r¥   r[  r†   r‡   )rH  r]  rJ   rû   ÚtmpÚtmp_dbs   &&&&  r-   Ú_zip_sqlite_snapshotrg  ê  s¥   € ô
 
×	$Ò	$¨E¸%ÄSÈÏÉÓEY×	ZÕ	ZÐ^aÜ�c—h‘h“ˆ÷ 
[ð'Ü˜X v×.Ò.Øð 	�‰ ˆÖ&ô 	˜¤C¨£MÔ2Ø�{‰{‹}×$Ñ$à�‰ ˆÕ&÷ 
[×	Zûð 	�‰ ˆÕ&ús   µB<ÁC Á;.C Â<C	ÃC#c          
      ó    € V ^8„  d   QhR\         P                  R\        \        \        \        3,          ,          R\        R\
        R\        /# )r'   rH  Úfiles_to_addrû   Útrack_bytesr)   )rJ  rK  r*   Útupler   rL   r+   )r,   s   "r-   r.   r.   ú  sF   € ÷ ñ Ü�‰ðÜ'+¬E´$¼°*Õ,=Õ'>ðÜJNðä:>ðäCFñr/   c               ó¦  € ^ p\        V^4       F’  w  pw  rš V	P                  R8X  d$   \        W	W¢4      pVf   V! V
4       K4  W{,          pM=\        W	\	        V
4      4       V'       d!   WyP                  4       P                  ,          pVR,          ^ 8X  g   KŠ  V! V4       K”  	  V#   \        \        \        3 d   pT! Y¬4        Rp?K¼  Rp?ii ; i)aC  Add every ``(abs_path, rel_path)`` to *zf*, WAL-safe for ``*.db``; return bytes archived.

``on_db_failure(rel_path)`` runs when a SQLite snapshot fails (may raise to abort);
``on_error(rel_path, exc)`` records a read failure; ``on_progress(i)`` fires every 500 files;
``track_bytes`` stats plain files for the size total.
r_  Néô  )
Ú	enumerater`  rg  r[  r7   r†   r‡   ÚPermissionErrorr�   r·   )rH  ri  rû   Úon_db_failureÚon_errorÚon_progressrj  Útotal_bytesÚir]  rJ   r&  r½   s   &&&$$$$      r-   Ú_write_zip_entriesru  ú  s¼   € ð €KÜ#,¨\¸1Ö#=ÑˆÑˆHð	Ø�‰ %Ô'Ü+¨B¸(ÓM�Ø’<Ù! (Ô+ÙØÕ#‘ä ¬c°(«mÔ<ßØ§=¡=£?×#:Ñ#:Õ:�Kð ˆs�7�aŽ<Ù˜ŽNñ! $>ð" Ðøô  ¤¬*Ð5ô 	Ù�XÔ#Ýûð	ús#   ˜)B'ÁB'Á=B'Â'CÂ=CÃCc                óV   € V ^8„  d   QhR\         R\        \         ,          R\         RR/# )r'   ÚheaderÚlinesÚindentr)   N)r7   r*   )r,   s   "r-   r.   r.     s,   € ÷ 9ñ 9œ#ð 9¤d¬3¥ið 9¼ð 9Àñ 9r/   c                óÀ   € \        V 4       VR,           F  p\        V V 24       K  	  \        V4      ^
8”  d$   \        V R\        V4      ^
,
           R24       R# R# )zcPrint *header*, then at most 10 of *lines* (each prefixed by *indent*) and a "... and N more" tail.ºNé
   Nz... and ú moreN)ÚprintrR   )rw  rx  ry  Úlines   &&& r-   Ú_print_cappedr€    sX   € ä	ˆ&„MØ�c—
�
ˆÜ��˜˜ÐÖ ñ ä
ˆ5ƒz�B„Ü��˜¤ U£¨b¥Ð 1°Ð7Ö8ñ r/   zhermes-backup-c                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r'   Úoutputr)   )r   r7   r   )r,   s   "r-   r.   r.   &  s   € ÷ ñ ¬´­ð ¼$ñ r/   c                ój  € Rp\          \        P                  ! 4       P                  R4       R2p V '       dG   \	        V 4      P                  4       P                  4       pVP                  4       '       d	   W,          pM\        P                  ! 4       V,          pVP                  P                  4       R8w  d#   VP                  VP                  R,           4      pVP                  P                  RRR7       V#   \         d-   p\        RT ;'       g    T RT 24       \!        ^4      ThRp?ii ; i)z—Turn ``--output`` (file, directory, or None) into a ``.zip`` path whose parent exists;
an unwritable path exits with a one-line error, not a traceback.Nú%Y-%m-%d-%H%M%Sú.zipTrg   zError: cannot write backup to r5  )Ú_RUN_BACKUP_PREFIXr   ÚnowÚstrftimer   r´   r¶   rÙ   Úhomer`  ÚlowerÚwith_suffixr~   r   r�   r~  Ú
SystemExit)r‚  rû   Údefault_namer½   s   &   r-   Ú_resolve_backup_output_pathrŽ  &  s   € ð €HÜ(Ð)¬(¯,ª,«.×*AÑ*AÐBSÓ*TÐ)UÐUYÐZ€Lð%ßÜ˜F“|×.Ñ.Ó0×8Ñ8Ó:ˆHØ�‰× Ò Ø#Õ2�øä—y’y“{ \Õ1ˆHØ�?‰?× Ñ Ó" fÔ,Ø×+Ñ+¨H¯O©O¸fÕ,DÓEˆHØ�‰×Ñ d°TÐÔ:ð €Oøô ô %ÜÐ.¨v×/AÐ/A¸Ð.BÀ"ÀSÀEÐJÔKÜ˜‹m Ð$ûð%ús   ±C; ¹C C; Ã;D2Ä'D-Ä-D2c                ó”   € V ^8„  d   QhR\         \        \         \        \        3,          ,          \        \        ,          3,          /# r5   )rk  r*   r   r7   )r,   s   "r-   r.   r.   ;  s/   € ÷ -ñ -¤5¬¬e´D¼#°IÕ.>Õ)?ÄÄcÅÐ)JÕ#Kñ -r/   c            
     óH  € \         P                  ! 4       P                  4       p . p. p\        4        F¥  p VP                  4       P	                  V 4       \        T4       Fs  p\        \
        \        4      ;_uu_ 4        TP                  4       P	                  T 4      pTP                  T\        TP                  4       ,           34       RRR4       Ku  	  K§  	  W3#   \
        \        3 d    TP                  \        T4      4        KÚ  i ; i  + '       g   i     KÁ  ; i)z²``([(abs_path, arcname)], [skipped])`` for the memory provider's external state, arc-named
``_external/<home-relative>``; paths outside home are skipped (security + portability).N)r   r‰  r¶   rÂ   r  r·   r�   Úappendr7   rá   r   Ú_EXTERNAL_PREFIXÚas_posix)Úhome_dirÚexternal_to_addÚskipped_externalrÄ   r  Úrel_to_homes         r-   Ú_collect_external_entriesr˜  ;  sé   € ô �yŠy‹{×"Ñ"Ó$€HØ.0€OØ"$ÐÜ7Ö9ˆð	Ø�L‰L‹N×&Ñ& xÔ0ô *¨$Ö/ˆEÜœ*¤g×.Õ.Ø#Ÿm™m›o×9Ñ9¸(ÓC�Ø×&Ñ&¨Ô/?À+×BVÑBVÓBXÕ/XÐ'YÔZ÷ /Ñ.ó 0ñ :ð Ð,Ð,øô œGÐ$ô 	Ø×#Ñ#¤C¨£IÔ.Úð	ú÷ /×.Ð.ús   ¶CÁ?AD	Ã+DÄDÄD!c                ó$   € V ^8„  d   QhR\         /# r5   ©rL   )r,   s   "r-   r.   r.   N  s   € ÷ %ñ %œñ %r/   c                ó`  € \        4       pVP                  4       '       g%   \        RV 24       \        P                  ! ^4        \        V4      ;_uu_ 4        \        W4      uuRRR4       #   + '       g   i     R# ; i  \         d    p\        RT 24       \        ^4      ThRp?ii ; i)uŸ  Create a zip backup of the Hermes home directory.

True when every selected file landed in the archive (or there was nothing to back up); False
when the zip was written but is incomplete â€” it is kept so the rest can still be restored, and
the caller turns False into exit status 1 so a cron/systemd timer never publishes a "successful"
archive that is missing state.db. Hard failures keep raising ``SystemExit``.
z*Error: Hermes home directory not found at NúError: )	r   rÙ   r~  ÚsysÚexitr—   Ú_run_backup_lockedrX   rŒ  )Úargsrú   r½   s   &  r-   Ú
run_backupr¡  N  s†   € ô *Ó+€Kà×Ñ×ÒÜÐ:¸;¸-ÐHÔIÜ�Š�Œð%Ü# K×0Õ0Ü% dÓ8÷ 1×0×0Ó0ûä ô %Ü�˜�uˆoÔÜ˜‹m Ð$ûð%ús6   ÁB ÁA/Á$
B Á/B 	Á:B Â B ÂB-ÂB(Â(B-c                ó0   € V ^8„  d   QhR\         R\        /# )r'   rú   r)   rK   )r,   s   "r-   r.   r.   d  s   € ÷ Cñ C¬$ð C´4ñ Cr/   c                ó	  aa€ \        V P                  4      p\        P                  ! 4       p\        P                  R4       \        R\        4        R24       \        4       p\        \        WV4      4      p\        4       w  rgV'       gM   V'       gE   \        P                  R\        P                  ! 4       V,
          R,          4       \        R4       R# \        V4      \        V4      ,           o\        P                  R\        P                  ! 4       V,
          R,          S4       \        P                  R	S4       \        R
S R24       . o\        P                  ! 4       pR V3R llp	\        V4      ;_uu_ 4       p
\        P                  ! V
R\        P                   ^R7      ;_uu_ 4       p\#        WµW)RV3R lV3R lR7      pV F2  w  rÞ \%        W½V4       WÍP'                  4       P(                  ,          pK4  	  RRR4       RRR4       \        P                  ! 4       V,
          pVP'                  4       P(                  p\        P                  RVR,          S\        S4      V4       \        RS'       d   RMR RV RS R\3        X4       R\3        V4       RVR R24       V'       d$   \        R\        V4       R \        4        R!24       V'       dF   \        R"\        V4       R#2R$P5                  R% \7        V4      R&,           4       4      ,           4       V'       d2   \        R'R$P5                  R( \7        V4       4       4      ,           4       S'       d   \9        R)\        S4       R*2SR+4       M\        R,VP:                   24       \=        V R-^ 4      pV'       dk   S'       gc   VP:                  P?                  \@        4      '       d>   \C        VPD                  \@        VR.4      pV'       d   \        R/V R0\@         R1V R224       S'       * #   \*        \,        \.        3 d#   pSP1                  T RT 24        Rp?EK…  Rp?ii ; i  + '       g   i     EL`; i  + '       g   i     ELl; i)3z@Write a full backup while the cross-process backup slot is held.z backup phase=scan status=startedz	Scanning z ...z/backup phase=scan status=empty duration_ms=%.1féè  zNo files to back up.Tz;backup phase=scan status=complete duration_ms=%.1f files=%dz,backup phase=archive status=started files=%dzBacking up ú
 files ...c                ó(   € V ^8„  d   QhR\         RR/# )r'   rt  r)   Nro   )r,   s   "r-   r.   Ú(_run_backup_locked.<locals>.__annotate__z  s   € ÷ añ a”Sð a˜Tñ ar/   c                 óZ   <€ \        R V  RS R24       \        P                  RV S4       R# )ú  Ú/r¥  z:backup phase=archive status=progress completed=%d total=%dN)r~  r²   rï   )rt  Ú
file_counts   &€r-   Ú	_progressÚ%_run_backup_locked.<locals>._progressz  s-   ø€ Ü��1�#�Q�z�l *Ð-Ô.Ü�‰ÐPÐRSÐU_Ö`r/   Úw©Úcompresslevelc                 ó,   <€ SP                  V  R 24      # )z: SQLite safe copy failed©r‘  )r  Úerrorss   &€r-   r1  Ú$_run_backup_locked.<locals>.<lambda>‚  s   ø€  f§m¡m°s°eÐ;TÐ4UÔ&Vr/   c                 ó0   <€ SP                  V  R V 24      # ©r5  r²  ©r  r½   r³  s   &&€r-   r1  r´  ƒ  s   ø€  f§m¡m°s°e¸2¸c¸U°OÔ&Dr/   )rr  rj  rp  rq  r5  NzQbackup phase=archive status=complete duration_ms=%.1f files=%d errors=%d bytes=%dz
Backup Ú
incompleteÚcompletez
  Files:       z
  Original:    z
  Compressed:  z
  Time:        ú.1fÚsz
  Included z( memory-provider file(s) stored outside rœ   z
  Skipped zE memory-provider path(s) outside your home directory (not portable):
Ú
c              3   ó,   "  € T F
  pR V 2x € K  	  R# 5i)ú    Nr2   )rÏ   rÀ   s   & r-   rÑ   Ú%_run_backup_locked.<locals>.<genexpr>™  s   é € Ð-`ÑB_¸Q°°Q°C­jÓB_ùs   ‚r{  z
  Excluded directories:
c              3   ó.   "  € T F  pR V R2x € K  	  R# 5i)r¾  rª  Nr2   ©rÏ   rà   s   & r-   rÑ   r¿  ›  s   é € Ð7bÑMaÈ¸$¸q¸cÀ½ÓMaùs   ‚z
  Archive kept, but z file(s) could not be added:r©  z
Restore with: hermes import ÚkeepÚbackupz	  Pruned z older z*.zip (keeping z).)#rŽ  r‚  r�   r‚   r²   rï   r~  r   rý   r*   r	  r˜  rR   rª   rJ  rK  ÚZIP_DEFLATEDru  r[  r†   r‡   ro  r�   r·   r‘  Ú_format_sizerA  Úsortedr€  r…   rí   rö   r†  Ú_prune_prefixed_zipsr~   )r   rú   rû   Úscan_startedrü   ri  r•  r–  Út0r¬  Úarchive_pathrH  rs  r]  rY  r½   ÚelapsedÚzip_sizerÂ  Úprunedr³  r«  s   &&                  @@r-   rŸ  rŸ  d  s·  ù€ ä*¨4¯;©;Ó7€HÜ—>’>Ó#€LÜ
‡K�KÐ2Ô3Ü	ˆIÔ)Ó+Ð,¨DÐ
1Ô2Ü›€LÜ,0Ô1CÀKÐ[gÓ1hÓ,i€LÜ(AÓ(CÑ%€Oß§Ü�‰ÐEÌÏÊÓHXÐ[gÕHgÐkoÕGoÔpÜÐ$Ô%Ùä�\Ó"¤S¨Ó%9Õ9€JÜ
‡K�KÐMÜ—’Ó! LÕ0°DÕ8¸*ôFä
‡K�KÐ>À
ÔKÜ	ˆK˜
�| :Ð
.Ô/Ø€FÜ	�ŠÓ	€B÷að aô 
˜X×	&Ô	&¨,¼¿ºØ˜#œw×3Ñ3À1÷9Fõ 9FØIKÜ(Ø˜hÈ4ÜVÜDôFˆó "1ÑˆHð3Ü ¨gÔ6ØŸ}™}›×6Ñ6Õ6’ñ "1÷9F×	&ô �nŠnÓ Õ#€GØ�}‰}‹×&Ñ&€HÜ
‡K�KÐcØ˜$• 
¬C°«K¸ôCä	ˆI§f‘l°*Ð=¸RÀ¸zð JØ&˜<ð (Ü(¨Ó5Ð6ð 7Ü(¨Ó2Ð3ð 4Ø# C˜=¨ð	+ô ,÷
 Ü�œc /Ó2Ð3Ð3[Ô\oÓ\qÐ[rÐrsÐtÔußÜ�œSÐ!1Ó2Ð3ð 4"ð "Ø$(§I¡IÑ-`Ä&ÐIYÓBZÐ[^ÖB_Ó-`Ó$`õaô 	bçÜÐ+¨d¯i©iÑ7bÌVÐT`ÔMaÓ7bÓ.bÕbÔcßÜÐ.¬s°6«{¨mÐ;WÐXÐZ`ÐbfÕgäÐ.¨x¯}©}¨oÐ>Ô?ô �4˜ Ó#€Dß—F˜xŸ}™}×7Ñ7Ô8J×KÒKÜ% h§o¡oÔ7IÈ4ÐQYÓZˆßÜ�I˜f˜X WÔ-?Ð,@ÀÐPTÈvÐUWÐXÔYØŒ:Ðøô; $¤W¬jÐ9ô 3Ø—‘  	¨¨C¨5Ð1×2Ó2ûð3ú÷9F÷ 9Fð 9Fú×	&×	&Ð	&úsN   Æ1Q0Æ4 Q	Ç,P!
ÈQ	ÈQ0Ð!QÐ7QÑQ	ÑQÑQ	ÑQ-Ñ'	Q0Ñ0R	c                ó|   € V ^8„  d   QhR\         P                  R\        \        ,          R\        \        ,          /# )r'   rH  Úmembersr)   )rJ  rK  r*   r7   )r,   s   "r-   r.   r.   ¬  s-   € ÷ ñ œgŸo™oð ¼¼S½	ð ÄdÌ3Åiñ r/   c                ó,  € . pV F@  p V P                  V4      ;_uu_ 4       pVP                  R4      '       d   K   RRR4       KB  	  V#   + '       g   i     KW  ; i  \        .\        O5 d"   pTP	                  T RT 24        Rp?K‰  Rp?ii ; i)a  Return ``"<member>: <error>"`` for every member whose data does not decompress or
fails its CRC, streaming each one in 1 MiB chunks so a multi-GB ``state.db`` is never
held in memory.

``is_zipfile()``/``namelist()`` only read the central directory, so an archive with a
rotten member passes them and the damage surfaces as ``zlib.error``/``BadZipFile`` in
the middle of the restore, after earlier members already replaced the user's files
(#121258). Not ``zf.testzip()``: it lets ``zlib.error`` escape and names at most the
first bad member.
Nr5  i   )r€   Úreadr�   Ú_ZIP_MEMBER_READ_ERRORSr‘  )rH  rÏ  ÚbadÚmemberÚsrcr½   s   &&    r-   Ú_find_corrupt_membersrÖ  ¬  sŠ   € ð €CÛˆð	+Ø—‘˜—” CØ—h‘h˜w×'Ò'Ùð (÷ !‘ñ ð €J÷ !—�ûô Ð2Ô1Ñ2ô 	+Ø�J‰J˜&˜  C 5Ð)×*Ò*ûð	+ús3   ‰A¢A½AÁAÁAÁAÁBÁ2BÂBc                ó0   € V ^8„  d   QhR\         R\        /# ©r'   r  r)   )r7   rL   )r,   s   "r-   r.   r.   Â  s   € ÷ 4ñ 4œð 4¤ñ 4r/   c                óÞ   €  \        \        V 4      4      pTR,          \        9   ;'       g0    \	        T4      \
        9   ;'       g    T P                  \        4      #   \         d     R# i ; i)aj  True for a HERMES_HOME-relative member the import deliberately does not restore: runtime
state (``_IMPORT_SKIP_NAMES``), PM-local interpreter/dependency roots, or an archived SQLite
WAL/SHM/journal. A ``.db`` member is page-restored into the live file, and a sidecar from a
different image would replay a foreign WAL on next open (older archives may ship these).Féÿÿÿÿ)rk  r   r·   Ú_IMPORT_SKIP_NAMESr   r   rÍ   Ú_SQLITE_SIDECAR_SUFFIXES)r  rO   s   & r-   Ú_import_skippedrÝ  Â  sn   € ð
ÜÔ-¨cÓ2Ó3ˆð �"�IÔ+Ñ+÷ 3ð 3Ü˜uÓ%Ô)=Ñ=÷3ð 3à�L‰LÔ1Ó2ð4øô ô Úðús   ‚A ÁA,Á+A,c                ó^   € V ^8„  d   QhR\         R\         R\        \         \        3,          /# )r'   rÔ  Úprefixr)   )r7   rk  rL   )r,   s   "r-   r.   r.   Ð  s*   € ÷ 	%ñ 	%œsð 	%¬Cð 	%´E¼#¼t¸)Õ4Dñ 	%r/   c                óØ   € V P                  \        4      '       d   V \        \        4      R R3# V'       d&   V P                  V4      '       d   V \        V4      R MT pV\        V4      3# )aO  Classify an archive member exactly as the restore does: return ``(rel, skipped)``.

``_external/`` members are home-relative and never skipped; every other member is
HERMES_HOME-relative after stripping the archive ``prefix``. Shared by the integrity
pre-flight and ``_import_members`` so the two cannot disagree on what gets restored.NF)rö   r’  rR   rÝ  )rÔ  rß  r  s   && r-   Ú_import_member_relrá  Ð  sc   € ð ×ÑÔ)×*Ò*Ø”cÔ*Ó+Ð,Ð-¨uÐ4Ð4ß"(¨V×->Ñ->¸v×-FÒ-Fˆ&”�V“�Ñ
ÈF€CØ” Ó$Ð$Ð$r/   c                ó:   € V ^8„  d   QhR\         \        ,          /# r5   )r   r+   )r,   s   "r-   r.   r.   Ü  s   € ÷ sDñ sDœ¤�ñ sDr/   c                ó¶  € \        V P                  4      P                  4       P                  4       pVP	                  4       '       g%   \        RV 24       \        P                  ! ^4       \        P                  ! V4      '       g%   \        RV 24       \        P                  ! ^4       \        4       p\        P                  ! VR4      ;_uu_ 4       p\        V4      w  rEV'       g%   \        RV 24       \        P                  ! ^4       \        V4      pVP                  4        Uu. uF  qwP                  R4      '       d   K  VNK  	  pp\        V4      p	\        RV	 R24       \        R\!        4        24       V'       d   \        R	V: R
24       VR,          P#                  4       p
VR,          P#                  4       pV
'       g	   V'       d‚   V P$                  '       gp   \        4        \        R4       \        R4       \        4         \'        R4      P)                  4       P+                  4       pXRM9  d   \        R4        RRR4       R# \        R4       \1        Y8 Uu. uF  p\3        WÖ4      ^,          '       d   K  VNK!  	  up4      pV'       d&   \5        R\        V4       R2VR4        RRR4       ^# \        RV	 R24       VP7                  RRR7       \8        P:                  ! 4       p^ RIHp  \A        W8WbV	4      w  ppppp\8        P:                  ! 4       V,
          p\        4        \        RX'       d   RMR R X R!VR" R#24       \        R$\!        4        24       X'       d   \        R%V R&\!        4        R'24       V'       dc   \        R(\        V4       R)24       VR*,           F  p\        V4       K  	  \        V4      ^
8”  d    \        R+\        V4      ^
,
           R,24       X'       de   \        R-4       V F=  w  ppp\        R.V R V^ ,           R/V^,           R0V^ ,           R1V^,           2
4       K?  	  \        R2\C        4        24       X'       do   \        R3\        V4       R424       \E        V4      R*,           F  p\        R.V 24       K  	  \        V4      ^
8”  d    \        R5\        V4      ^
,
           R,24       VR6,          p. pVPG                  4       '       Ed¨    ^ R7I$H%pH&pH'p H(p! \E        VPS                  4       4       F¶  p"V"PG                  4       '       g   K  V"PT                  p#V"R,          P#                  4       '       g    V"R,          P#                  4       '       g   Kc  V! V#4      p$V$'       d'   \        R8V# R9V$ 24       VPW                  V#R:34       K™  V! V#4      p%VPW                  V#V%RJ34       K¸  	  V'       dÀ   V UUu. uF  w  rtV'       g   K  VNK  	  p&ppV UUu. uF  w  rtV'       d   K  VNK  	  p'ppV&'       d   \        R;R<PY                  V&4       24       V''       d   \        R=R<PY                  V'4       24       V ! 4       '       g+   \        R>V!! 4        R?24       \        R@4       \        RA4       \        4        VRD,          PG                  4       '       g   \        RE4       \        RF4       V'       d:   V UU(u. uF  w  pp(VNK
  	  p)pp(\        RG4       V) F  p*\        RHV* RI24       K  	  \_        V4       V'       d$   \        RJ\        V4       RK24        RRR4       ^# \        RL4       RRR4       R# u upi   \,        \.        3 d&    \        R4       \        P                  ! ^4        ELqi ; iu upi   T d0   p\        RT 24       \        P                  ! ^4        Rp?ELÐRp?ii ; iu uppi u uppi   \Z         d:    \]        TPS                  4       4      '       d   \        RB4       \        RC4        EL”i ; iu up(pi   + '       g   i     R# ; i)NzMRestore a Hermes backup; return 1 on damaged archives or incomplete restores.zError: File not found: zError: Not a valid zip file: r8  rœ  rª  zBackup contains z fileszTarget: zDetected archive prefix: z (will be stripped)úconfig.yamlú.envz;Warning: Target directory already has Hermes configuration.z=Importing will overwrite existing files with backup contents.zContinue? [y/N] z	
Aborted.zAborted.Nz
Checking archive integrity ...z"Error: backup archive is damaged (zG member(s) fail to decompress or fail their CRC); nothing was restored:r©  z
Importing r¥  Trg   )ÚOwnershipConflictz$
Import refused; no files restored: zImport r¸  r¹  r5  z files restored in rº  r»  z
  Target: z
  Restored z? memory-provider file(s) to their original location(s) outside rœ   z
  Warnings (z files skipped):r{  z
  ... and r}  u6   
  âš  Session data replaced by older backup contents:r¾  z session(s) / z message(s) -> z / z?    Anything recorded after the backup was taken is not in it. z
  Preserved z? runtime state file(s) (kept this machine's, not the backup's):z    ... and rN   )Úcreate_wrapper_scriptÚcheck_alias_collisionÚ_is_wrapper_dir_in_pathÚ_get_wrapper_dirz  Skipped alias 'z': Fz
  Profile aliases restored: ú, z  Profile aliases skipped:  z	
  Note: z is not in your PATH.z3  Add to your shell config (~/.bashrc or ~/.zshrc):z(    export PATH="$HOME/.local/bin:$PATH"z6
  Profiles detected but aliases could not be created.z5  Run: hermes profile list  (after installing hermes)r:   z?Note: The hermes-agent codebase was not included in the backup.z0  If this is a fresh install, run: hermes updatez,
To re-enable gateway services for profiles:z  hermes -p z gateway installzImport incomplete: zU file(s) were not restored (see Warnings above). Fix the cause and re-run the import.z2Done. Your Hermes configuration has been restored.>   ÚyÚyes)0r   rJ  r´   r¶   r×   r~  r�  rž  Ú
is_zipfiler   rK  r%   r   ÚnamelistrÍ   rR   r   rµ   r  ÚinputÚstriprŠ  ÚEOFErrorÚKeyboardInterruptrÖ  rá  r€  r   r�   r‚   Úgateway.runtime_ownershipræ  Ú_import_membersr9   rÆ  rÙ   Úhermes_cli.profilesrç  rè  ré  rê  Úiterdirr…   r‘  rA  ÚImportErrorrõ   Ú_revive_gateway_after_import)+r   Úzip_pathrú   rH  r9  Úreasonrß  ÚnrÏ  r«  Ú
has_configÚhas_envÚanswerÚmÚcorruptrÉ  ræ  ÚrestoredÚrestored_externalr³  Úskipped_runtimeÚ	db_shrunkr½   rË  Úer  ÚbeforeÚafterÚprofiles_dirÚrestored_profilesrç  rè  ré  rê  ÚentryÚprofile_nameÚ	collisionÚwrapperÚcreatedÚskippedrC  Úgw_profilesÚpnames+   &                                          r-   Ú
run_importr  Ü  sU  € ä�D—L‘LÓ!×,Ñ,Ó.×6Ñ6Ó8€Hà×Ñ×ÒÜÐ'¨ zÐ2Ô3Ü�Š�Œä×Ò˜h×'Ò'ÜÐ-¨h¨ZÐ8Ô9Ü�Š�Œô "Ó#€Kä	�Š˜ 3×	'Ô	'¨2ä)¨"Ó-‰
ˆßÜ�G˜F˜8Ð$Ô%Ü�HŠH�QŒKä Ó#ˆØ Ÿk™kœmÓC™m˜·:±:¸c·?—1�1™mˆÐCÜ˜“\ˆ
äÐ   ¨FÐ3Ô4Ü�Ô,Ó.Ð/Ð0Ô1çÜÐ-¨f©ZÐ7JÐKÔLð " MÕ1×9Ñ9Ó;ˆ
Ø Õ'×/Ñ/Ó1ˆçŸ'¨4¯:¯:¨:ÜŒGÜÐOÔPÜÐQÔRÜŒGðÜÐ1Ó2×8Ñ8Ó:×@Ñ@ÓB�ð ˜\Ô)Ü�jÔ!Ø÷C 
(Ñ	'ôJ 	Ð0Ô1Ü'¨¸Ó,h¹°1ÔGYÐZ[ÓGdÐef×GgÑGg¯Q¨Q¹Ñ,hÓiˆßÜÐ>¼sÀ7»|¸nð MQð RØSZÐ\`ôbà÷U 
(Ñ	'ôZ 	�˜Z˜L¨
Ð3Ô4Ø×Ñ $°ÐÔ6ä�^Š^ÓˆÝ?ð	ÜN]Ø˜V°*óO>ÑKˆHÐ'¨°À)ô
 —.’.Ó" RÕ'ˆô 	ŒÜ�¯™°JÐ?¸rÀ(ÀÐK^Ð_fÐgjÐ^kÐklÐmÔnÜ�
Ô.Ó0Ð1Ð2Ô3çÜØÐ 1Ð2ð 36Ü6IÓ6KÐ5LÈAðOô÷
 Ü�N¤3 v£; -Ð/?Ð@ÔAØ˜C—[�[�Ü�a–ñ !ä�6‹{˜RÔÜ˜
¤3 v£;°Õ#3Ð"4°EÐ:Ô;çô ÐKÔLÛ&/Ñ"��V˜UÜØ˜3˜%˜r &¨¥) ¨N¸6À!½9¸+ð FØ  �8˜* C¨¨a­ zð3öñ '0ô
 ØQÜ*Ó,Ð-ð/ô÷
 ÜØ ¤ _Ó!5Ð 6ð 7Cð Dôô ˜oÓ.¨s×3Ð3�Ü˜˜S˜E�lÖ#ñ 4ä�?Ó# bÔ(Ü˜¤S¨Ó%9¸BÕ%>Ð$?¸uÐEÔFð # ZÕ/ˆØÐØ×Ñ× Ó ð#S÷ó ô $ L×$8Ñ$8Ó$:Ö;�EØ Ÿ<™<Ÿ>š>Ù Ø#(§:¡:�Là! MÕ1×9Ñ9×;Ò;ÀUÈVÅ^×D[ÑD[×D]ÒD]Ù Ù 5°lÓ C�Iß ÜÐ 1°,°¸sÀ9À+ÐNÔOØ)×0Ñ0°,ÀÐ1FÖGá"7¸Ó"E˜Ø)×0Ñ0°,ÀÈtÐ@SÐ1TÖUñ <÷ %Ù.?ÔFÑ.?¡U QÄ2Ÿq˜qÑ.?�GÑFÙ.?ÔJÑ.?¡U QÄrŸq˜qÑ.?�GÑJßÜÐ >¸t¿y¹yÈÓ?QÐ>RÐSÔTßÜÐ <¸T¿Y¹YÀwÓ=OÐ<PÐQÔRÙ2×4Ò4Ü 
Ñ+;Ó+=Ð*>Ð>SÐTÔUÜÐSÔTÜÐHÔIô 	ŒØ˜nÕ,×4Ñ4×6Ò6ÜÐSÔTÜÐDÔEçÙ):Ô;Ñ):¡  A›1Ñ):ˆKÑ;ÜÐAÔBÛ$�Ü˜ U GÐ+;Ð<Ö=ñ %ô 	% [Ô1çÜÐ'¬¨F« }ð 59ð 9ô :à÷ 
(Ñ	'ô@ 	ÐBÔC÷A 
(Ñ	'ùò Døô( Ô/Ð0ô Ü�lÔ#Ü—’˜—ðüò -iøð !ô 	ÜÐ9¸#¸Ð?Ô@Ü�HŠH�Q�KŠKûð	üóR GùÛJøô ô Sä�|×+Ñ+Ó-×.Ò.ÜÐSÔTÜÐQÔRúð	Süó <÷k 
(×	'Ð	'úsO  ÃAaÄ,]2Å	]2ÅA?aÇaÇaÇ)*aÈ']7È;aÉaÉ,^0Ê^0ÊaÊ aË=aÌ^5ÌBaÎA)aÐA+aÑ2BaÔA(_:Õ,_:Ö	_:ÖA_:×*_:×/_.
Ø _.
Ø_:Ø_4
Ø_4
Ø%/_:Ù)_:Ù?*_:Ú)AaÛ.aÛ3a
ÜAaÝaÝ2aÝ72^-Þ)aÞ,^-Þ-aÞ5_+Þ<$_&ß aß&_+ß+aß._:ß:A `>à:aà=`>à>	aáa	c                ó|  € V ^8„  d   QhR\         P                  R\        \        ,          R\        R\        R\
        R\        \
        \
        \        \        ,          \        \        ,          \        \        \        \        \
        \
        3,          \        \
        \
        3,          3,          ,          3,          /# ©r'   rH  rÏ  rß  rú   r«  r)   ©rJ  rK  r*   r7   r   r+   rk  )r,   s   "r-   r.   r.   ’  sˆ   € ÷ Wñ WÜ�‰ðWÜ"&¤s¥)ðWÜ58ðWÜGKðWÜY\ðWä
Œ3””Tœ#•Y¤¤S¥	¬4´´c¼5ÄÄcÀ½?ÌEÔRUÔWZÐRZÍOÐ6[Õ0\Õ+]Ð]Õ^ñWr/   c           	     ór  € ^ RI Hp VP                  4       pV0pV EF\  pVP                  \        4      '       d   K!  V'       d&   VP                  V4      '       d   V\        V4      R MTp	\        V	4      P                  p
\        V
4      ^8¼  db   V
^ ,          R8X  dT   W:^ ,          ,          V
^,          ,          pVP                  4       P                  V4      '       d   VP                  V4       W9,          pVP                  R8X  g   Kñ  VP                  4       P                  V4      '       g   EK  VP                  VP                  4       P                  VP                  4       P                  .4       EK_  	  V! V4      ;_uu_ 4        \        WW#V4      uuRRR4       #   + '       g   i     R# ; i)zKReserve all affected profiles before publishing even the first config file.©Úexclusive_maintenanceNrN   r_  )rô  r  r¶   rö   r’  rR   r   rO   Úis_relative_toÚaddr`  r  Úabsoluter~   Ú_import_members_exclusive)rH  rÏ  rß  rú   r«  r  Úroot_resÚhomesrÔ  r  rO   r‰  Útargets   &&&&&        r-   rõ  rõ  ’  s9  € õ @Ø×"Ñ"Ó$€HØˆM€EÜˆØ×ÑÔ-×.Ò.Ùß&,°×1BÑ1BÀ6×1JÒ1Jˆf”S˜“[�\Ñ"ÐPVˆÜ�S“	—‘ˆÜˆu‹:˜Œ?˜u Q�x¨:Ô5Ø q¥Õ)¨E°!­HÕ4ˆDØ�|‰|‹~×,Ñ,¨X×6Ò6Ø—	‘	˜$”ØÕ"ˆØ�=‰=˜EÖ! f§n¡nÓ&6×&EÑ&EÀh×&OÕ&OØ�L‰L˜&Ÿ/™/Ó+×2Ñ2°F·N±NÓ4D×4KÑ4KÐL×Mñ ñ 
˜u×	%Õ	%Ü(¨°fÈ:ÓV÷ 
&×	%×	%Ó	%ús   ÆF%Æ%F6	c                óŠ   € V ^8„  d   QhR\         P                  R\        R\        R\        R\
        \        ,          R\        /# )r'   rH  rÔ  r”  Únew_file_moder³  r)   )rJ  rK  r7   r   r+   r*   rL   )r,   s   "r-   r.   r.   ©  sF   € ÷ ñ Ü�‰ðÜ!$ðÜ04ðÜEHðÜRVÔWZÕR[ðä	ñr/   c                ó,  € W!\        \        4      R ,          p VP                  4       P                  V4        TP                  P                  RRR7       \        YYS4       TP                  R	9   g   TP                  \        9   d    \        P                  ! TR4       R# R#   \         d    TP                  RT R24        R# i ; i  \         d     R# i ; i  \        .\        O5 d#   pTP                  RT RT 24        Rp?R# Rp?ii ; i)
z†Publish one ``_external/`` member under the user's home; False (with ``errors`` appended)
when it is a traversal or cannot be written.Nr©  ú: path traversal blockedFTrg   é€  r5  >   rå  ú.confú.json)rR   r’  r¶   r  r·   r‘  r~   r   r    r`  r…   Ú_SECRET_FILE_NAMESr„   Úchmodr�   rÒ  )rH  rÔ  r”  r"  r³  r   r½   s   &&&&&  r-   Ú_import_external_memberr*  ©  s  € ð
 œsÔ#3Ó4Ð5Ð6Õ6€FðØ�‰Ó×$Ñ$ XÔ.ðØ�‰×Ñ D°4ÐÔ8Ü" 2¨vÔEà�=‰=Ð6Ô6¸&¿+¹+ÔI[Ô:[ðÜ—’˜ Ô'ó øô ô Ø�‰˜˜6˜(Ð":Ð;Ô<Úðûô ô ØÙðûô Ð.Ô-Ñ.ô Ø�‰˜˜6˜( " S EÐ*Ô+ÝûðúsG   šB% ºAC Â
C Â% C	ÃC	ÃCÃC ÃCÃC ÃDÃ1DÄDc                ó|  € V ^8„  d   QhR\         P                  R\        \        ,          R\        R\        R\
        R\        \
        \
        \        \        ,          \        \        ,          \        \        \        \        \
        \
        3,          \        \
        \
        3,          3,          ,          3,          /# r  r  )r,   s   "r-   r.   r.   Ä  s�   € ÷ gKñ gKÜ�‰ðgKÜ"&¤s¥)ðgKÜ58ðgKÜGKðgKÜY\ðgKä
Œ3””Tœ#•Y¤¤S¥	¬4´´c¼5ÄÄcÀ½?ÌEÔRUÔWZÐRZÍOÐ6[Õ0\Õ+]Ð]Õ^ñgKr/   c                ó†  € . p^ p^ p. p. p	\         P                  ! 4       P                  4       p
\        4       pV EFx  pVP	                  \
        4      '       db   V\        \
        4      R '       g   K9  \        WW«V4      '       d   V^,          pV^,          pVR,          ^ 8X  d   \        RV RV R24       K€  V'       d'   VP	                  V4      '       d   V\        V4      R pMTpV'       g   Kº   \        \        V4      4      pTR,          \        9   d   TP                  T4       Kô  \        T4      \        9   d   TP                  T4       EK  TP!                  \"        4      '       d   TP                  T4       EKK  TP$                  ! T!  p TP                  4       P'                  TP                  4       4        TP(                  P+                  RRR7       TP,                  R	8X  d]   \/        T4      p\1        YYû4       \/        T4      pT'       d2   T'       d*   T^,          T^,          8  d   T	P                  TTT34       M\3        YYû4       TP4                  \6        9   d   \8        P:                  ! TR
4       T^,          pTR,          ^ 8X  g   EKf  \        RT RT R24       EK{  	  WgWXV	3#   \         d    TP                  RT R24        EK¦  i ; i  \         d    TP                  RT R24        EKÎ  i ; i  \<        .\>        O5 d"   pTP                  RT RT 24        Rp?L¬Rp?ii ; i)u  Publish every member; return ``(restored, restored_external, errors, skipped_runtime, db_shrunk)``.

``db_shrunk`` holds ``(rel, live_counts, imported_counts)`` for every session database the
import replaced with one holding fewer rows â€” allowed, but never silently (#100960).
Nrm  r©  rª  r¥  r$  Trg   r_  r%  r5  rÚ  ) r   r‰  r¶   r   rö   r’  rR   r*  r~  rk  r   r·   r‘  rÛ  r   r   rÍ   rÜ  Újoinpathr  r~   r   r`  r   r!   r    r…   r(  r„   r)  r�   rÒ  )rH  rÏ  rß  rú   r«  r³  r  r  r  r  r”  r"  rÔ  r  rO   r   r  r  r½   s   &&&&&              r-   r  r  Ä  sô  € ð €FØ€HØÐØ!#€OØDF€IÜ�yŠy‹{×"Ñ"Ó$€Hô +Ó,€Mäˆð ×ÑÔ-×.Ò.Øœ#Ô.Ó/Ð0×1ÙÜ& r°8ÈF×SÒSØ˜A•�Ø! QÕ&Ð!Ø˜#�~ Ô"Ü˜˜8˜* A j \°Ð<Ô=Ù÷ �f×'Ñ'¨×/Ò/Øœ˜V›˜Ð&‰CàˆCçÙð	ÜÔ1°#Ó6Ó7ˆEð ��9Ô*Ô*Ø×"Ñ" 3Ô'Ùô ˜eÓ$Ô(<Ô<Ø×"Ñ" 3Ô'Úð �<‰<Ô0×1Ò1Ø×"Ñ" 3Ô'Úà×%Ò% uÑ-ˆð	Ø�N‰NÓ×(Ñ(¨×)<Ñ)<Ó)>Ô?ð
	-Ø�M‰M×Ñ¨°tÐÔ<Ø�}‰} Ô%ô -¨VÓ4�Ü! "¨fÔDÜ+¨FÓ3�ßŸe¨¨a­°6¸!µ9Ô(<Ø×$Ñ$ c¨6°5Ð%9Ô:øä*¨2°vÔMØ�{‰{Ô0Ô0Ü—’˜ Ô'Ø˜�MˆHð �c�>˜Q×Ü�B�x�j  * ¨ZÐ8×9ñg ðj ¨ÀÐJÐJøôy ô 	Ø�M‰M˜B˜s˜eÐ#;Ð<Ô=Ûð	ûôF ô 	Ø�M‰M˜B˜s˜eÐ#;Ð<Ô=Ûð	ûô& Ð2Ô1Ñ2ô 	-Ø�M‰M˜B˜s˜e 2 c UÐ+×,Ñ,ûð	-úsD   Ã5J<Æ-K$ÇALÈ$A+LÊ< K!Ë K!Ë$ L	ÌL	ÌM ÌL;Ì;M c                ó(   € V ^8„  d   QhR\         RR/# )r'   rú   r)   Nr   )r,   s   "r-   r.   r.   .  s   € ÷ `ñ `¬dð `°tñ `r/   c                ó’  a€ \        4       oV S8w  dR   \        ;QJ d    V3R lR 4       F  '       g   K   RM	  RM! V3R lR 4       4      '       d   \        RS R24       R#  ^ RIHp ^ RIHp V! 4       '       g   \        4        V! R	R
7       R# R#   \         d'    \        P                  RRR7       \        R4        R# i ; i)a¹  Start an installed gateway service after a restore, best-effort and prompt-free.

Bot tokens and cron jobs are inert without a gateway (a platform-less gateway is supported, so
this is safe for any backup); failures print a manual fallback, never fail the import. Only
revived when the restore landed in the default home or no other install exists: a sandbox or
profile restore must not install a second gateway on the default service name.
c              3   óR   <"  € T F  pSV,          P                  4       x € K  	  R # 5ir1   )rµ   )rÏ   ÚmarkerÚnative_defaults   & €r-   rÑ   Ú/_revive_gateway_after_import.<locals>.<genexpr>7  s'   øé € ð -bÙ=`°6ˆ^˜fÕ$×,Ñ,×.Ð.Ó=`ùs   ƒ$'TFzk
Restored into a non-default home; leaving the gateway service alone to avoid clashing with the install at z<.
To start a gateway for this home, run:  hermes gateway runN)Ú_is_service_running)Úensure_gateway_serviceÚimport)Úcontextz"gateway revive after import failed)Úexc_infozL
Start the gateway to activate cron jobs and messaging:
  hermes gateway run)rä  rå  rV   )
r   rõ   r~  Úhermes_cli.gatewayr4  Ú hermes_cli.gateway_setup_servicer5  r°   r²   Údebug)rú   r4  r5  r2  s   &  @r-   rù  rù  .  sÄ   ø€ ô 7Ó8€NØ�nÔ$¯«ô -bÙ=`ó-b¯¯ªô -bÙ=`ó-b÷ *bò *bäð %Ø%3Ð$4ð 5KðKô 	Lñ 	ð
`Ý:ÝKÙ"×$Ò$ÜŒGÙ"¨8×4ñ %øô ô `ô 	�‰Ð9ÀDˆÔIÜÐ^×_ð	`ús   Á%B Á>B Â-CÃCúcron/jobs.jsonc                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r'   rb   r)   ©r   r   )r,   s   "r-   r.   r.   e  s   € ÷ 'ñ '¤h¬t¥nð 'Äñ 'r/   c                 óD   € T ;'       g    \        4       pV\        ,          # r1   )r   Ú_QUICK_SNAPSHOTS_DIR)rb   r‰  s   & r-   Ú_quick_snapshot_rootrA  e  s   € Ø×+Ð+œ/Ó+€DØÔ&Õ&Ð&r/   c                óF   € V ^8„  d   QhR\         R\        \         ,          /# )r'   Úrootr)   rÅ   )r,   s   "r-   r.   r.   j  s"   € ÷ Zñ Zœð Z¬T´$­Zñ Zr/   c                ó~   € V P                  4       '       g   . # \        \        WP                  4       4      R RR7      # )z^Entries of *root* passing ``keep_entry``, newest (by name) first; ``[]`` if *root* is missing.c                 ó   € V P                   # r1   ©r…   )rÀ   s   &r-   r1  Ú_newest_first.<locals>.<lambda>n  s   € ÀAÇFÂFr/   T©ÚkeyÚreverse)rµ   rÆ  Úfilterr÷  )rC  Ú
keep_entrys   &&r-   Ú_newest_firstrM  j  s.   € à�;‰;�=Š=Øˆ	Ü”&˜§\¡\£^Ó4Ñ:JÐTXÔYÐYr/   c                ó^   € V ^8„  d   QhR\         \        ,          R\        R\        R\        /# )r'   Únewest_firstrÂ  Úwhatr)   )r*   r   r+   r7   )r,   s   "r-   r.   r.   u  s,   € ÷ 	ñ 	¤¤T¥
ð 	´#ð 	ÄSð 	ÌSñ 	r/   c                ó¸   € ^ pWR  F  p V! V4       V^,          pK  	  V#   \          d-   p\        P                  RY5P                  T4        Rp?KM  Rp?ii ; i)zN``remove(path)`` every entry past the first *keep*; return how many succeeded.NzFailed to prune %s %s: %s)r�   r²   r³   r…   )rO  rÂ  ÚremoverP  ÚdeletedrÀ   r½   s   &&&&   r-   Ú_prune_oldestrT  u  s_   € à€GØ˜%Ó ˆð	KÙ�1ŒIØ�q�LŠGñ !ð €Nøô ô 	KÜ�N‰NÐ6¸¿f¹fÀc×JÒJûð	Kús   ‹"¢A­!AÁAzpre-update-zpre-migration-z.incomplete.zipc          
      óT   € V ^8„  d   QhR\         R\        R\        R\        R\        /# )r'   Ú
backup_dirrß  rÂ  rP  r)   ©r   r7   r+   )r,   s   "r-   r.   r.   ‹  s0   € ÷ ;ñ ;¤Tð ;´3ð ;¼cð ;Ìð ;ÔQTñ ;r/   c                óZ   a€ \        V V3R l4      p\        WB\        P                  V4      # )z®Remove oldest ``<prefix>*.zip`` in *backup_dir* beyond *keep*; return count deleted.

Only prefix-matched files are touched, so hand-made zips or other backup kinds survive.
c                 ó(  <€ V P                  4       ;'       d{    V P                  P                  S4      ;'       dX    V P                  P	                  4       R 8H  ;'       d3    V P                  P	                  4       P                  \        4      '       * # )r…  )r×   r…   rö   r`  rŠ  rÍ   Ú_INCOMPLETE_ZIP_SUFFIX©rÀ   rß  s   &€r-   r1  Ú&_prune_prefixed_zips.<locals>.<lambda>�  sv   ø€ °!·)±)³+÷ 3Tð 3TÀ!Ç&Á&×BSÑBSÐTZÓB[÷ 3Tð 3TØ !§¡§¡Ó 0°FÑ :÷3Tð 3Tà$%§F¡F§L¡L£N×$;Ñ$;Ô<RÓ$SÔ Sð3Tr/   ©rM  rT  r   r¥   )rV  rß  rÂ  rP  r=   s   &f&& r-   rÇ  rÇ  ‹  s-   ø€ ô
 ˜Jô )Tó U€Gô ˜¬¯©°TÓ:Ð:r/   c                óH   € V ^8„  d   QhR\         R\        R\        R\        /# )r'   rV  rß  rP  r)   rW  )r,   s   "r-   r.   r.   –  s.   € ÷ Hñ H¤tð H´Sð HÄð HÌñ Hr/   c                ób   a€ \        V V3R l4      p\        V^\        P                  RV 24      # )zÐKeep only the newest ``<prefix>*.incomplete.zip`` salvage archive; return count deleted.

Salvage archives never count toward normal retention, so repeated failing runs would
otherwise pile up without bound.
c                 óÔ   <€ V P                  4       ;'       dQ    V P                  P                  S4      ;'       d.    V P                  P                  4       P	                  \
        4      # r1   )r×   r…   rö   rŠ  rÍ   rZ  r[  s   &€r-   r1  Ú(_prune_incomplete_zips.<locals>.<lambda>œ  sT   ø€ °!·)±)³+÷ 3Pð 3PÀ!Ç&Á&×BSÑBSÐTZÓB[÷ 3Pð 3PØ !§¡§¡£× 7Ñ 7Ô8NÓ Oð3Pr/   zincomplete r]  )rV  rß  rP  Úsalvages   &f& r-   Ú_prune_incomplete_zipsrc  –  s4   ø€ ô ˜Jô )Pó Q€Gä˜ !¤T§[¡[°KÀ¸vÐ2FÓGÐGr/   c                óŒ   € V ^8„  d   QhR\         \        ,          R\        R\        R\        R\        R\         \        ,          /# )r'   rb   rß  rÂ  rP  Ú
prune_whatr)   )r   r   r7   r+   )r,   s   "r-   r.   r.   ¡  sF   € ÷ ñ Üœ$•ðÜ),ðÜ47ðÜ?BðÜPSðÜX`ÔaeÕXfñr/   c                ó¬  € T ;'       g    \        4       pVP                  4       '       g   R# V\        ,          p VP                  RRR7       Ya \        P                  ! 4       P                  R4       R2,          p\        Y…4      f   \        YaT4       R# \        YaY$4       T#   \         d#   p\
        P                  RY6T4        Rp?R# Rp?ii ; i)a  Write ``<HERMES_HOME>/backups/<prefix><timestamp>.zip`` and prune older same-prefix zips.
Returns the path, or ``None`` if nothing to back up, the write failed, or the archive is
incomplete (kept as ``<prefix><timestamp>.incomplete.zip``, excluded from retention).
Never raises.NTrg   z%Could not create %s backup dir %s: %sr„  r…  )r   rÙ   Ú_PRE_UPDATE_BACKUPS_DIRr   r�   r²   r³   r   r‡  rˆ  Ú_write_full_zip_backuprc  rÇ  )	rb   rß  rÂ  rP  re  rú   rV  r½   rû   s	   &&&&&    r-   Ú_create_prefixed_full_backupri  ¡  sÃ   € ð ×:Ð:Ô!8Ó!:€KØ×Ñ×ÒÙØÔ6Õ6€JðØ×Ñ °ÐÔ5ð ˜h¤x§|¢|£~×'>Ñ'>Ð?PÓ'QÐ&RÐRVÐWÕW€HÜ˜hÓ4Ò<ô 	˜z°:Ô>ÙÜ˜¨TÔ>Ø€Oøô ô Ü�‰Ð>ÀÐRUÔVÝûðús   »B& Â&CÂ1CÃCc                óh   € V ^8„  d   QhR\         \        ,          R\        R\         \        ,          /# ©r'   rb   rÂ  r)   ©r   r   r+   )r,   s   "r-   r.   r.   º  s3   € ÷ oñ oÜœ$•ðoÜ.1ðoÜQYÔZ^ÕQ_ñor/   c                ó<   € \        V \        \        V^4      RR4      # )uë   Full zip backup to ``backups/pre-update-<timestamp>.zip``, auto-pruned; ``None`` if nothing
was found, the backup failed, or it was incomplete (salvage kept as ``*.incomplete.zip``).
Never raises â€” ``hermes update`` continues anyway.ú
pre-updaterÃ  )ri  Ú_PRE_UPDATE_PREFIXrƒ   ©rb   rÂ  s   &&r-   Úcreate_pre_update_backuprq  º  s!   € ô
 (¨Ô5GÌÈTÐSTËÐWcÐemÓnÐnr/   c                óh   € V ^8„  d   QhR\         \        ,          R\        R\         \        ,          /# rk  rl  )r,   s   "r-   r.   r.   Â  s3   € ÷ cñ cÜœ$•ðcÜ.1ðcÜT\Ô]aÕTbñcr/   c                ó<   € \        V \        \        V^ 4      RR4      # )aX  Full zip backup to ``backups/pre-migration-<timestamp>.zip`` before a plugin's agent import
(``hermes import-agent openclaw``), so its name and signature are API; same dir as update backups
so ``hermes import`` finds it. ``None`` if nothing was found, the write failed, or it was
incomplete (salvage kept as ``*.incomplete.zip``). Never raises.zpre-migrationzpre-migration backup)ri  Ú_PRE_MIGRATION_PREFIXrƒ   rp  s   &&r-   Úcreate_pre_migration_backupru  Â  s&   € ô (ØÔ*¬C°°a«L¸/ÐKaócð cr/   c                óÂ   € V ^8„  d   QhR\         \        ,          R\         \        ,          R\         \        ,          R\         \        ,          R\         \        ,          /# ©r'   Úlabelrb   rÂ  Úmax_file_sizer)   ©r   r7   r   r+   )r,   s   "r-   r.   r.   Ð  sN   € ÷ 
ñ 
Ü”C�=ð
äœ$•ð
ô ”3�-ð
ô œC•=ð	
ô
 Œc…]ñ
r/   c           	     ó¬   € T;'       g    \        4       p\        V4      ;_uu_ 4        \        V VVVR7      uuRRR4       #   + '       g   i     R# ; i)zFCreate one atomic quick snapshot while holding the shared backup slot.©rx  rb   rÂ  ry  N)r   r—   Ú_create_quick_snapshot_locked)rx  rb   rÂ  ry  r‰  s   &&&& r-   Úcreate_quick_snapshotr~  Ð  sB   € ð ×+Ð+œ/Ó+€DÜ	 ×	%Õ	%Ü,ØØØØ'ô	
÷ 
&×	%×	%Ó	%ús   ¨AÁA	c                óÂ   € V ^8„  d   QhR\         \        ,          R\         \        ,          R\         \        ,          R\         \        ,          R\         \        ,          /# rw  rz  )r,   s   "r-   r.   r.   á  sU   € ÷ pñ pÜ”C�=ðpäœ$•ðpô ”3�-ðpô œC•=ð	pô
 Œc…]ñpr/   c                ó  a€ T;'       g    \        4       p\        V4      pR V3R llp\        P                  ! \        4      P                  R4      pV '       d   V RV  2MTpTp	^p
WY,          P                  4       '       d   V RV
 2p	V
^,          p
K.  WY,          pVRV	 R\        P                  ! 4        R2,          p\        P                  ! VRR7       VP                  RRR	R
7       \        P                  R8w  d   \        P                  ! VR	4       VP                  R	RR7       \        P                  RV	4       / p. p. p\          EFâ  pVV,          pVP                  4       '       g   K%  VP#                  4       '       Ed}   VP%                  R4       EFc  pVP'                  4       '       g   K  VP)                  V4      P+                  4       pRRV R29   g   RRV R29   d   KS  V! VV4      '       d%   VP,                  R8X  d   VP/                  V4       K†  VV,          pVP0                  P                  RRR7        VP,                  R8X  dr   \3        VV4      '       g_   VP/                  V4       \5        RV R24       \7        V4      '       d+   \5        RV RVP9                  4       P:                   R24       EK.  M\        P<                  ! VV4       VP9                  4       P:                  VV&   EKf  	  EK¸  VP'                  4       '       g   EKÑ  V! VV4      '       d&   VP,                  R8X  d   VP/                  V4       EK  VV,          pVP0                  P                  RRR7        VP,                  R8X  dr   \3        VV4      '       g_   VP/                  V4       \5        RV R24       \7        V4      '       d+   \5        RV RVP9                  4       P:                   R24       EK­  M\        P<                  ! VV4       VP9                  4       P:                  VV&   EKå  	  V'       d`   \5        RRPE                  V4      ,           4       \5        RV R \G        4        24       \        PI                  R!RPE                  V4      4       V'       gA   \        P                  ! VRR7       V'       d   \5        R"RPE                  V4       R#24       R# R$V	R%VR&V R'\K        V4      R(\M        VPO                  4       4      R)VR*VR+V/p\Q        VR,,          R-R.R/7      ;_uu_ 4       p\R        PT                  ! VV^R07       RRR4       \        P                  R8w  d¥   \        P                  ! VR	4       \        P                  ! VR	4       VP%                  R4       Fa  pVP#                  4       '       d   \        P                  ! VR	4       K2  VP'                  4       '       g   KJ  \        P                  ! VR14       Kc  	  \        PV                  ! WË4       T;'       g    TpV'       g   \Y        YRf   \Z        MTR27       MwV'       dG   \5        R3RPE                  V4      ,           4       \        PC                  R4RPE                  V4      4       \        PC                  R5\K        V4      \K        V4      4       \        P                  R6V	\K        V4      \M        VPO                  4       4      4       V	#   \>        \@        3 d$   p\        PC                  RTT4        Rp?EK”  Rp?ii ; i  \>        \@        3 d$   p\        PC                  RTT4        Rp?EK  Rp?ii ; i  + '       g   i     EL*; i)7uú  Create a quick state snapshot of critical files.

Copies STATE_FILES to a timestamped directory under state-snapshots/.
Auto-prunes old snapshots beyond the keep limit.

Args:
    max_file_size: When set, individual files larger than this many bytes
        are skipped (with a printed warning) instead of copied. Used by
        the pre-update safety snapshot so a multi-GB ``state.db`` can
        never stall ``hermes update`` or silently eat disk â€” the small
        pairing/cron/config files the snapshot exists to protect are
        always captured. ``None`` (default) copies everything, which
        preserves manual ``/snapshot`` and ``hermes backup --quick``
        behavior.

Returns:
    Snapshot ID (timestamp-based), or None if no files found.
c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r'   rä   Úrel_namer)   )r   r7   rL   )r,   s   "r-   r.   Ú3_create_quick_snapshot_locked.<locals>.__annotate__ü  s!   € ÷ ñ œð ¬ð ´ñ r/   c           
     óþ   <€ Sf   R#  V P                  4       P                  pTS8:  d   R# \        RT R\	        T4       R\	        S4       R24       \
        P                  RTTS4       R#   \         d     R# i ; i)z<True (and warn) when ``path`` exceeds the max_file_size cap.Fu     âš  Snapshot: skipping z (z	 exceeds z limit)z9Quick snapshot skipped %s: %d bytes exceeds %d byte limitT)r†   r‡   r�   r~  rÅ  r²   r³   )rä   r‚  r&  ry  s   && €r-   Ú
_too_largeÚ1_create_quick_snapshot_locked.<locals>._too_largeü  s•   ø€ àÒ Ùð	Ø—9‘9“;×&Ñ&ˆDð �=Ô ÙÜØ'¨ zð 2Ü˜TÓ"Ð# 9¬\¸-Ó-HÐ,IÈðRô	
ô 	�‰ØGØØØô		
ñ øô ô 	Úð	ús   ‰A- Á-A<Á;A<z%Y%m%d-%H%M%Sr�   rœ   rž   T)Úignore_errorsiÀ  )rh   ri   Úmoderj   F)rˆ  ri   z.quick snapshot phase=copy status=started id=%sÚ*z/workspaces/rª  z/attachments/r_  rg   u,     âš  Snapshot: SQLite safe copy FAILED for u$    â€” file may be locked or corruptedu     âš  Snapshot: z! looks ZEROED (no SQLite header; z bytes of NULs?)zCould not snapshot %s: %sNz bytes)u/     âš  CRITICAL: could not snapshot DB file(s): rë  u4     âš  If sessions disappear after the update, check z. z/Quick snapshot failed to capture DB file(s): %su7     âš  Snapshot aborted: no files captured (failed DBs: r,  ÚidÚ	timestamprx  r«  Ú
total_sizerÝ   Ú
failed_dbsÚoversized_skippedúmanifest.jsonr®  zutf-8©Úencoding)ry  r%  ©rÂ  u<     âš  Skipping snapshot prune: DB file(s) skipped for size: z/Quick snapshot skipped oversized DB file(s): %su…   Skipping snapshot prune because %d DB(s) failed to capture and/or %d were oversized â€” preserving older snapshots as recovery sourcezAquick snapshot phase=copy status=complete id=%s files=%d bytes=%d).r   rA  r   r‡  r   rˆ  rµ   r„   r¢   ÚshutilÚrmtreer   r…   r)  r²   rï   Ú_QUICK_STATE_FILESrÙ   Úrglobr×   r  r“  r`  r‘  r~   r   r~  r  r†   r‡   Úcopy2r�   ro  r³   rA  r9   r4  rR   Úsumr¹   r€   ÚjsonÚdumpr¦   Ú_prune_quick_snapshotsÚ_QUICK_DEFAULT_KEEP)rx  rb   rÂ  ry  r‰  rC  r…  ÚtsÚbase_snap_idÚsnap_idr`  Úsnap_dirÚstaging_dirÚmanifestr�  rŽ  r  rÕ  ÚsubÚsub_relÚdstr½   ÚmetarÔ   rä   r¸  s   &&&f                      r-   r}  r}  á  sk  ø€ ð0 ×+Ð+œ/Ó+€DÜ Ó%€D÷ð ô, 
�Š”cÓ	×	#Ñ	# OÓ	4€Bß&+�b�T˜˜5˜'‘?°€LØ€GØ€FØ�>×
!Ñ
!×
#Ò
#Ø!�N ! F 8Ð,ˆØ�!�ŠØ�~€HØ˜1˜W˜I Q¤r§y¢y£{ m°8Ð<Õ<€KÜ
‡M‚M�+¨TÕ2Ø‡J�J�t d°€JÔ7Ü	‡w�w�$„Ü
�Š��uÔØ×Ñ˜5¨5ÐÔ1Ü
‡K�KÐ@À'ÔJà!€HØ€Jð
 $&Ðç!Ð!ˆØ�S�jˆØ�z‰z�|Š|Ùà�:‰:�<‹<ð —y‘y —~�Ø—{‘{—}’}ÙØŸ/™/¨$Ó/×8Ñ8Ó:�ð " q¨¨	° ^Ô3°ÈAÈgÈYÐVWÈ.Ô7XÙÙ˜c 7×+Ò+Ø—z‘z UÔ*Ø)×0Ñ0°Ô9ÙØ! GÕ+�Ø—
‘
× Ñ ¨¸Ð Ô=ðNð —z‘z UÔ*Ü,¨S°#×6Ò6Ø&×-Ñ-¨gÔ6Ü!Ø"NÈwÈið XFð !Gôô  5°S×9Ò9Ü %Ø&6°w°ið @:Ø:=¿(¹(»*×:LÑ:LÐ9MÐM]ð%_ô!"ò %ð  7ô Ÿš S¨#Ô.Ø(+¯©«
×(:Ñ(:�H˜WÔ%ñE &òJ à�{‰{�}Š}Úá�c˜3×ÒØ�z‰z˜UÔ"Ø!×(Ñ(¨Ô-Úà˜CÕˆØ�
‰
×Ñ °ÐÔ5ð	BØ�z‰z˜UÔ"Ü$ S¨#×.Ò.Ø×%Ñ% cÔ*ÜØFÀsÀeð L>ð ?ôô -¨S×1Ò1ÜØ.¨s¨eð 42Ø25·(±(³*×2DÑ2DÐ1EÀWðNôò ð /ô —’˜S #Ô&ØŸH™H›J×.Ñ.ˆH�SŒMñW "÷^ ô 	Ø=Ø�i‰i˜
Ó#õ$ô	
ô 	ØBÀ4À&ÈÔKbÓKdÐJeÐfô	
ô 	�‰Ø=Ø�I‰I�jÓ!ô	
÷
 Ü�Š�k°Õ6ßäð Ø $§	¡	¨*Ó 5Ð6°að9ôñ ð 	ˆgØ�RØ�Ø”c˜(“mØ”c˜(Ÿ/™/Ó+Ó,Ø�Ø�jØÐ.ð	€Dô 
ˆk˜OÕ+¨S¸7×	CÕ	CÀqÜ�	Š	�$˜ !Õ$÷ 
Dô 
‡w�w�$„Ü
�Š��uÔÜ
�Š�˜eÔ$Ø×%Ñ% cÖ*ˆDØ�{‰{�}Š}Ü—’˜˜uÖ%Ø—‘—”Ü—’˜˜uÖ%ñ	 +ô ‡J‚Jˆ{Ô%ð ×0Ð0Ð0€JßÜ˜tÂÕ*=ÐSWÖXçÜØNØ—)‘)Ð-Ó.õ/ôô �N‰NØAØ—	‘	Ð+Ó,ôô 	�‰ðô �
‹OœSÐ!2Ó3ô		
ô ‡K�KØKØÜˆH‹ÜˆH�O‰OÓÓô	ð €Nøôw  ¤Ð1ô NÜ—N‘NÐ#>ÀÈ×MÓMûðNûô@ œÐ)ô 	BÜ�N‰NÐ6¸¸S×AÓAûð	Bú÷P 
D×	CÐ	CúsJ   ÉA>\ Ë	5\ Í:A>\7Ï;5\7Ô3].Ü \4Ü\/Ü/\4Ü7]+Ý]&Ý&]+Ý.]?	c          	      óŠ   € V ^8„  d   QhR\         R\        \        ,          R\        \        \
        \        3,          ,          /# )r'   Úlimitrb   r)   )r+   r   r   r*   r!  r7   r	   )r,   s   "r-   r.   r.   Ô  s7   € ÷ ñ Üðäœ$•ðô 
Œ$Œs”Cˆx�.Õñr/   c           
     óÞ  € \        V4      pVP                  4       '       g   . # . p\        VP                  4       RR7       FÓ  pVP	                  4       '       dC   VP
                  P                  R4      '       g"   VP
                  P                  R4      '       d   K]  VR,          pVP                  4       '       dE    \        VRR7      ;_uu_ 4       pVP                  \        P                  ! V4      4       RRR4       \        V4      V 8¼  g   KÒ   V# 	  V#   + '       g   i     L); i  \        P                  \        3 d%    TP                  R	TP
                  R
^ R^ /4        Lji ; i)z7List existing quick state snapshots, most recent first.T)rJ  rœ   rž   r�  ú	utf-8-sigr�  NrŠ  r«  rŒ  )rA  rµ   rÆ  r÷  rÙ   r…   rö   rÍ   r€   r‘  r™  ÚloadÚJSONDecodeErrorr�   rR   )r¨  rb   rC  Úresultsrà   Úmanifest_pathrÔ   s   &&     r-   Úlist_quick_snapshotsr¯  Ô  s  € ô
   Ó,€DØ�;‰;�=Š=Øˆ	à€GÜ�D—L‘L“N¨D×1ˆØ�x‰x�zŠz˜QŸV™V×.Ñ.¨s×3Ò3°q·v±v·±Àz×7RÒ7RÙØ˜OÕ+ˆØ×Ñ×!Ò!ðQÜ˜-°+×>Õ>À!Ø—N‘N¤4§9¢9¨Q£<Ô0÷ ?ô ˆw‹<˜5Ö Øà€Nñ 2ð €N÷ ?×>ûä×(Ñ(¬'Ð2ô QØ—‘  a§f¡f¨l¸A¸|ÈQÐOÖPðQús0   Â>D-Ã&DÃ9D-ÄD*Ä%D-Ä*D-Ä-<E,Å+E,c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r'   rä   r‰  r)   rK   )r,   s   "r-   r.   r.   î  s!   € ÷ ñ ¤dð ´$ð ¼4ñ r/   c                óV  € V P                  4       '       g   R#  \        VR7      P                  RR7      pVP                  RR7      V8X  d   R# VR,          P                  RR7      pVP                  V4       V P                  RR7      V8H  #   \        \
        \        3 d     R# i ; i)zVTrue only for a file symlink resolving to this restore home's default-root auth store.F)r‰  )Ústrictú	auth.json)rØ   r   r¶   r  r�   ÚRuntimeErrorr·   )rä   r‰  rC  Útrusteds   &&  r-   Ú_is_trusted_root_auth_aliasr¶  î  sš   € à�?‰?×ÒÙðÜ&¨DÔ1×9Ñ9ÀÐ9ÓGˆØ�<‰<˜uˆ<Ó%¨Ô-ÙØ˜+Õ%×.Ñ.°eÐ.Ó<ˆØ×Ñ˜DÔ!Ø�|‰| 5ˆ|Ó)¨WÑ4Ð4øÜ”\¤:Ð.ô Úðús   š3B Á>B ÂB(Â'B(c                óR   € V ^8„  d   QhR\         R\        \        ,          R\        /# ©r'   Úsnapshot_idrb   r)   )r7   r   r   rL   )r,   s   "r-   r.   r.   ý  s*   € ÷ ñ Üðäœ$•ðô 
ñr/   c                ó  € ^ RI HpHp T;'       g    \        4       p V! V.4      ;_uu_ 4        \	        W4      uuRRR4       #   + '       g   i     R# ; i  T d"   p\
        P                  RT4        Rp?R# Rp?ii ; i)zèRestore the whole snapshot offline, or refuse before changing any file.

Overwrites current state files with the snapshot's copies.
Returns True if at least one file was restored and the listed auth.json
was not refused or skipped.
)ræ  r  Nú%sF)rô  ræ  r  r   Ú!_restore_quick_snapshot_exclusiver²   r4  )r¹  rb   ræ  r  r‰  r½   s   &&    r-   Úrestore_quick_snapshotr½  ý  sa   € ÷ SØ×+Ð+œ/Ó+€DðÙ" D 6×*Õ*Ü4°[ÓG÷ +×*×*Ó*ûàô Ü�‰�T˜3ÔÝûðús3   žA ¯Aº
A ÁA	ÁA ÁA ÁBÁ A<Á<Bc                ó$   € V ^8„  d   QhR\         /# r5   rš  )r,   s   "r-   r.   r.     s   € ÷ 
ñ 
´tñ 
r/   c                óv  € V  F‚  pV! V4      pV'       g   K  V^ ,          P                  4       '       g   K4  RV^,          P                  V^,          P                  4       P                  39   g   Ko   \        V^,          4       K„  	  R#   \         d#   p\
        P                  RT4        Rp? R# Rp?ii ; i)zWFalse (logged) when any listed ``state.db`` destination cannot prove its runtime epoch.rV   r»  NFT)rµ   r…   r¶   r#   r�   r²   r4  )rÝ   Úentry_pathsr  r  r½   s   &&   r-   Ú_snapshot_epochs_restorablerÁ    s‹   € ãˆÙ˜CÓ ˆß‰5�U˜1•X—_‘_×&Ô&¨:¸%À½(¿-¹-ÈÈqÍ×IYÑIYÓI[×I`ÑI`Ð9aÖ+aðÜ*¨5°­8Ö4ñ	 ñ øô ô Ü—‘˜T 3Ô'Þûðús   Á3BÂB8ÂB3Â3B8c                óH   € V ^8„  d   QhR\         R\        R\        R\        /# )r'   r  rÕ  r¥  r)   ©r7   r   rL   )r,   s   "r-   r.   r.     s(   € ÷ ñ ¤ð ¬4ð ´dð ¼tñ r/   c                ó~  €  VP                   R8X  d-   \        W4      '       g   \        P                  RV 4       R#  R# V R8X  d-   \	        W4      '       g   \        P                  RV 4       R#  R# \
        P                  ! W4       R#   \        \        3 d"   p\        P                  RY4        Rp?R# Rp?ii ; i)	zTPublish one quick-snapshot file over ``dst``; False (logged) when refused or failed.r_  zQFailed to restore %s: refused or source integrity check failed (see previous log)Fr³  zFailed to restore %s safelyTzFailed to restore %s: %sN)	r`  r$   r²   r4  r"   r“  r—  r�   ro  )r  rÕ  r¥  r½   s   &&& r-   Ú_restore_snapshot_entryrÅ    sª   € ðØ�:‰:˜Ôô
 $ C×-Ò-ô —‘ÐpÐruÔvÙð	 .ñ ð �KÔô
 & c×/Ò/Ü—‘Ð:¸CÔ@Ùð 0ñ
 ô �LŠL˜Ô"ÙøÜ”_Ð%ô Ü�‰Ð/°Ô:Ýûðús-   ‚8B
 ¼B
 ¿.B
 Á/B
 Á2B
 Â
B<ÂB7Â7B<c                óh   € V ^8„  d   QhR\         R\        \        ,          R\        \        ,          /# r¸  )r7   r   r   )r,   s   "r-   r.   r.   ;  s,   € ÷ ñ ¤Cð ´h¼tµnð ÔPXÔY]ÕP^ñ r/   c                ó¬  € \        V4      pV '       d   RV 9   g   RV 9   g   V R9   d   \        P                  RV 4       R# W ,          p VP                  4       P	                  VP                  4       4       TP                  4       '       d   TR,          P                  4       '       g   R# T#   \
         d    \        P                  RT 4        R# i ; i)zSThe directory of a restorable quick snapshot, or None for an invalid or missing id.rª  Ú\zInvalid snapshot_id: %sNz*Snapshot path traversal blocked for id: %sr�  )rœ   z..)rA  r²   r4  r¶   r  r·   rÙ   rµ   )r¹  rb   rC  r   s   &&  r-   Úquick_snapshot_dirrÉ  ;  s°   € ä Ó,€D÷ ˜# Ô,°¸Ô0CÀ{ÐVaÔGaÜ�‰Ð.°Ô<ÙØÕ!€HðØ×ÑÓ×&Ñ& t§|¡|£~Ô6ð �?‰?×Ò X°Õ%?×$GÑ$G×$IÒ$IÙØ€Oøô ô Ü�‰ÐAÀ;ÔOÚðús   Á
-B. Â.!CÃCc                ó<   € V ^8„  d   QhR\         R\        R\        /# )r'   r¹  r‰  r)   rÃ  )r,   s   "r-   r.   r.   O  s!   € ÷ :4ñ :4´3ð :4¼dð :4Ätñ :4r/   c                ó   aaaa€ ^ RI Hp \        V S4      oSf   R# \        SR,          RR7      ;_uu_ 4       p\        P
                  ! V4      pRRR4       SP                  4       SP                  4       uooR VVVV3R llpS0pXP                  R	/ 4       F€  pV! V4      pV'       g   K  V^,          P                  R
8X  g   K/  VP                  V^,          P                  4       P                  V^,          P                  4       P                  .4       K‚  	  V! V4      ;_uu_ 4        \        VP                  R	/ 4      V4      '       g    RRR4       R# ^ p	Rp
VP                  R	/ 4       F°  pV! V4      pVf"   \        P                  RV4       VR8X  d   Rp
K0  Vw  r¼VP                  4       '       g"   VR8X  d   \        P                  RV4       Rp
Kk  VP                  P!                  RRR7       \#        W{V4      '       d   V	^,          p	K¥  VR8X  g   K®  Rp
K²  	  RRR4       \        P%                  RX	V 4       V	^ 8„  ;'       d    X
'       * #   + '       g   i     EL; i  + '       g   i     LO; i)z?Restore state from a quick snapshot while ``home`` is reserved.r  NFr�  rª  r�  c                óh   € V ^8„  d   QhR\         R\        \        \        \        3,          ,          /# rØ  )r7   r   rk  r   )r,   s   "r-   r.   Ú7_restore_quick_snapshot_exclusive.<locals>.__annotate__Z  s(   € ÷ ñ œ#ð ¤(¬5´´t°Õ+<Õ"=ñ r/   c                 óú   <€ SV ,          SV ,          r!VP                  4       P                  S4      '       g   R # VP                  4       P                  S4      '       g   V R8w  g   \        VS4      '       g   R # W3# )Nr³  )r¶   r  r¶  )r  rÕ  r¥  r‰  Úhome_resr   Úsnap_ress   &  €€€€r-   Ú_entry_pathsÚ7_restore_quick_snapshot_exclusive.<locals>._entry_pathsZ  sd   ø€ à˜c•> 4¨#¥:ˆSØ�{‰{‹}×+Ñ+¨H×5Ò5ÙØ�{‰{‹}×+Ñ+¨H×5Ò5ð �kÔ!Ô)DÀSÈ$×)OÒ)OÙØˆxˆr/   rÝ   r_  z#Manifest path traversal blocked: %sr³  Tz4Snapshot auth.json listed in manifest is missing: %srg   z"Restored %d files from snapshot %s)rô  r  rÉ  r€   r™  r«  r¶   Úgetr`  r  r  r~   rÁ  r²   r4  rµ   r   rÅ  rï   )r¹  r‰  r  rÔ   r¦  rÑ  r  r  r  r  Úauth_restore_failedrÕ  r¥  rÏ  r   rÐ  s   &f           @@@r-   r¼  r¼  O  s  û€ å?Ü! +¨tÓ4€HØÒÙÜ	ˆh˜Õ(°;×	?Õ	?À1Ü�yŠy˜‹|ˆ÷ 
@ð "×)Ñ)Ó+¨T¯\©\«^Ð€Hˆh÷ó ð ˆF€EØ�x‰x˜ Ö$ˆÙ˜SÓ!ˆß‰5�U˜1•X—_‘_¨Ö-Ø�L‰L˜% �(×+Ñ+Ó-×4Ñ4°e¸Aµh×6FÑ6FÓ6H×6OÑ6OÐPÖQñ %ñ 
˜u×	%Õ	%ô +¨4¯8©8°G¸RÓ+@À,×OÒOØ÷	 
&Ñ	%ð ˆØ#ÐØ—8‘8˜G RÖ(ˆCÙ  Ó%ˆEØŠ}Ü—‘ÐBÀCÔHØ˜+Ô%Ø*.Ð'ÙØ‰HˆCØ—:‘:—<’<Ø˜+Ô%Ü—L‘LÐ!WÐY\Ô]Ø*.Ð'Ùà�J‰J×Ñ T°DÐÔ9Ü& s°×5Ò5Ø˜A•’Ø˜Ö#Ø&*Ò#ñ% )÷ 
&ô8 ‡K�KÐ4°hÀÔLØ�a‰<×3Ð3Ð 3Ô3Ð3÷i 
@×	?Ð	?ú÷. 
&×	%ús$   ¹IÄ.$I-ÅB?I-È I-ÉI*	É-I=	c                óF   € V ^8„  d   QhR\         R\        \        ,          /# rã   )r   r   r+   )r,   s   "r-   r.   r.   Œ  s   € ÷ ñ œ4ð ¤H¬S¥Mñ r/   c                óä  € V P                  4       '       g   R#  \        V RRR7      ;_uu_ 4       p\        P                  ! V4      pRRR4       \        X\        4      '       d6   TP                  R. 4      p\        T\        4      '       d   \        T4      # R# \        T\        4      '       d   \        T4      # R#   + '       g   i     L~; i  \        \        P
                  3 d     R# i ; i)uß  Return the number of cron jobs stored in ``path``.

The canonical on-disk shape is ``{"jobs": [...]}`` (see ``cron/jobs.py``).
A legacy bare-list shape (``[...]``) is also honoured.

Returns:
    The job count for any *valid, readable* JSON document, or ``None`` if
    the file is missing or cannot be parsed. ``None`` means "unknown" â€”
    callers must not treat it as "zero jobs", because acting on an
    unreadable file could mask a real corruption the user needs to see.
Nr8  rª  r�  Újobs)r×   r€   r™  r«  r�   r¬  r?  r!  rÓ  r*   rR   )rä   rÔ   Údatar×  s   &   r-   Ú_count_cron_jobsrÙ  Œ  sµ   € ð �<‰<�>Š>Ùðô
 �$˜ k×2Õ2°aÜ—9’9˜Q“<ˆD÷ 3ô �$œ×ÒØ�x‰x˜ Ó#ˆÜ& t¬T×2Ò2Œs�4‹yÐ<¸Ð<Ü�$œ×ÒÜ�4‹yÐÙ÷ 3×2ûä”T×)Ñ)Ð*ô Úðús.   šC °B=ÁC Â=C	ÃC ÃC ÃC/Ã.C/c          	      óŠ   € V ^8„  d   QhR\         R\        \        ,          R\        \        \         \        3,          ,          /# r¸  ©r7   r   r   r!  r	   )r,   s   "r-   r.   r.   «  sA   € ÷ ISñ ISÜðISäœ$•ðISô Œd”3œ�8�nÕñISr/   c                ó  € V '       g   R# T;'       g    \        4       pV\        ,          p\        V4      pVf   R# \        V4      V ,          \        ,          p\        V4      pV'       g   R# WF8¼  d   R#  VP                  P                  RRR7       \        P                  ! WS4       \        P                  RTT TT4       RRRTRT /#   \        \        3 d"   p\        P                  RT4        Rp?R# Rp?ii ; i)	uñ  Safety net for silent cron-job loss across ``hermes update``.

Config-version migrations have been observed to leave ``cron/jobs.json``
valid-but-empty after an update, silently dropping every scheduled job
(issue #34600). The desktop scheduler can also overwrite the file with its
own small set of internally-tracked crons, causing partial loss (issue
#52144).

This compares the *current* job count against the pre-update snapshot. If
the live file now has **fewer** jobs than the snapshot, the snapshot copy
of ``cron/jobs.json`` is restored in place.

The check is deliberately conservative â€” it only ever restores when there
is unambiguous evidence of loss (snapshot had more jobs than live file),
so a user who genuinely deleted jobs during/after the update is never
second-guessed, and an unreadable live file (count ``None``) is left
untouched so real corruption still surfaces.

Args:
    snapshot_id: The pre-update quick-snapshot id (from
        :func:`create_quick_snapshot`).
    hermes_home: Override for the Hermes home directory (tests).

Returns:
    ``None`` when no action was taken (the common, healthy path). On a
    successful restore, a dict ``{"restored": True, "job_count": N,
    "snapshot_id": ...}`` so the caller can warn the user.
NTrg   z@Cron jobs were emptied during update but auto-restore failed: %su‚   Restored %d cron job(s) from pre-update snapshot %s (live file had %d job(s), snapshot had %d â€” jobs were lost during migration)r  Ú	job_countr¹  )r   Ú_CRON_JOBS_RELrÙ  rA  r~   r   r“  r—  r�   ro  r²   r4  r³   )r¹  rb   r‰  Ú	live_pathÚ
live_countÚ	snap_pathÚ
snap_countr½   s   &&      r-   Úrestore_cron_jobs_if_emptiedrã  «  sö   € ÷@ Ùà×+Ð+œ/Ó+€DØ”~Õ%€Iä! )Ó,€Jð ÒÙä$ TÓ*¨[Õ8¼>ÕI€IÜ! )Ó,€JßÙð ÔÙðØ×Ñ×Ñ t°dÐÔ;Ü�Š�YÔ*ô ‡N�Nð	YàØØØôð ˜˜k¨:°}ÀkÐRÐRøô ”_Ð%ô Ü�‰ØNÐPSô	
õ ûð	ús   Á83C ÃC>ÃC9Ã9C>c                óh   € V ^8„  d   QhR\         R\        \        \        \         3,          ,          /# )r'   Úinvoking_homer)   )r   r*   rk  r7   )r,   s   "r-   r.   r.   ÷  s(   € ÷ ñ ¬$ð ´4¼¼cÄ4¸iÕ8HÕ3Iñ r/   c                ó¦  € . p ^ RI HpHpHp V P	                  4       pV! 4       pVP                  4       '       d)   VP	                  4       V8w  d   VP                  RV34       V! 4       pVP                  4       '       d£   \        VP                  4       4       F…  pVP                  4       '       g   K  VP                  R8w  g   K.  VP                  VP                  4      '       g   KQ  VP	                  4       V8w  g   Kh  VP                  VP                  V34       K‡  	  V#   \         d"   p	\        P                  RT	4        Rp	?	T# Rp	?	ii ; i)u
  (name, home) for every OTHER profile on this install. Never raises.

The update's code swap and gateway fleet restart touch every profile,
so the pre-update snapshot must too (#66140). The invoking profile is
excluded â€” its snapshot is taken by the existing call.
)Ú_get_default_hermes_homeÚ_get_profiles_rootÚ_PROFILE_ID_REÚdefaultz&Sibling profile enumeration failed: %sN)rö  rç  rè  ré  r¶   rÙ   r‘  rÆ  r÷  r…   Úmatchr°   r²   r;  )
rå  r  rç  rè  ré  ÚinvokingÚdefault_homerC  r  r½   s
   &         r-   Ú_sibling_profile_homesrî  ÷  s
  € ð %'€EðD÷	
ñ 	
ð !×(Ñ(Ó*ˆÙ/Ó1ˆØ×Ñ× Ò  \×%9Ñ%9Ó%;¸xÔ%GØ�L‰L˜) \Ð2Ô3Ù!Ó#ˆØ�;‰;�=Š=Ü §¡£Ö/�à—L‘L—N”NØŸ
™
 iÖ/Ø&×,Ñ,¨U¯Z©Z×8Ô8ØŸ™›¨8Ö3à—L‘L %§*¡*¨eÐ!4Ö5ñ 0ð €Løô ô DÜ�‰Ð=¸s×CÐCØ€LûðDús;   „6D$ »AD$ Â /D$ Â4D$ ÃD$ Ã*D$ Ä!D$ Ä$EÄ/EÅEc          
      ó¬   € V ^8„  d   QhR\         \        ,          R\         \        ,          R\         \        ,          R\        \        \        3,          /# )r'   rå  rÂ  ry  r)   )r   r   r+   r!  r7   )r,   s   "r-   r.   r.     sD   € ÷ ñ ÜœD•>ðä
”3�-ðô œC•=ðô 
Œ#Œsˆ(…^ñ	r/   c                óô   € / pT ;'       g    \        4       p\        V4       F#  w  rV \        RVVVR7      pV'       d   WsV&   K#  K%  	  V#   \         d"   p\        P                  RYX4        Rp?KP  Rp?ii ; i)uÍ  Pre-update quick snapshots for every SIBLING profile (#66140).

Same snapshot set, same per-file size cap, same keep policy as the
invoking profile's snapshot â€” identical semantics per profile, no
partial-tier coherence class. Each sibling's snapshot lands under its
OWN ``<home>/state-snapshots/`` so per-profile restore tooling finds
it where it expects. Returns ``{profile_name: snapshot_id}`` for the
siblings that snapshotted successfully. Never raises.
rn  r|  z-Pre-update snapshot for profile %s failed: %sN)r   rî  r~  r°   r²   r;  )	rå  rÂ  ry  r­  r‰  r…   Úprofile_homerŸ  r½   s	   &&&      r-   Ú(create_pre_update_snapshots_all_profilesrò    s…   € ð !€GØ×-Ð-œOÓ-€DÜ4°TÖ:Ñˆð
	UÜ+Ø"Ø(ØØ+ô	ˆG÷ Ø '˜“ñ ñ ;ð €Nøô ô 	UÜ�L‰LÐHÈ$×TÒTûð	Uús   ¨AÁA7ÁA2Á2A7c                óh   € V ^8„  d   QhR\         R\        \        \        \        3,          ,          /# rã   )r   r   r!  r7   r	   )r,   s   "r-   r.   r.   F  s'   € ÷ 4ñ 4œdð 4¤x´´S¼#°XµÕ'?ñ 4r/   c                ó  € V P                  4       '       g   R#  ^ RIp\        V RRR7      ;_uu_ 4       pVP                  V4      pRRR4       \        X\        4      '       d   T# R#   + '       g   i     L*; i  \         d     R# i ; i)zIParse ``path`` as a YAML mapping. ``None`` = missing/unreadable/non-dict.Nr8  rª  r�  )r×   Úhermes_yamlr€   Ú	safe_loadr°   r?  r!  )rä   ÚyamlrÔ   rØ  s   &   r-   Ú_read_raw_yaml_dictrø  F  so   € à�<‰<�>Š>ÙðÛ"ä�$˜ k×2Õ2°aØ—>‘> !Ó$ˆD÷ 3ô ˜d¤D×)Ò)ˆ4Ð3¨tÐ3÷	 3×2ûäô Úðús.   šA; ´A(ÁA; Á(A8	Á3A; Á8A; Á;B
Â	B
c                óx   € V ^8„  d   QhR\         \        \        3,          R\        \        R3,          R\        /# )r'   rØ  Údotted.r)   ©r!  r7   r	   rk  )r,   s   "r-   r.   r.   T  s1   € ÷ ñ ¤¤c¬3 h¥ð ¼¼sÀC¸x½ð ÌSñ r/   c                 óp   € T pV F-  p\        V\        4      '       g    R # VP                  V4      pK/  	  V# r1   )r?  r!  rÓ  )rØ  rú  ÚnoderI  s   &&  r-   Ú_get_config_path_valuerþ  T  s5   € Ø€DÛˆÜ˜$¤×%Ò%ÚØ�x‰x˜‹}Šñ ð €Kr/   c                ó|   € V ^8„  d   QhR\         \        \        3,          R\        \        R3,          R\        RR/# )r'   rØ  rú  .Úvaluer)   Nrû  )r,   s   "r-   r.   r.   ]  s:   € ÷ ñ ¤¤c¬3 h¥ð ¼¼sÀC¸x½ð ÔQTð ÐY]ñ r/   c                 ó–   € T pVR R  F2  pVP                  V4      p\        V\        4      '       g   / pWSV&   TpK4  	  W#VR,          &   R # )NrÚ  )rÓ  r?  r!  )rØ  rú  r   rý  rI  Úchilds   &&&   r-   Ú_set_config_path_valuer  ]  sP   € Ø€DØ�c�r‹{ˆØ—‘˜“ˆÜ˜%¤×&Ò&ØˆEØ�‰IØŠñ ð ˆ��Ór/   c          	      óŠ   € V ^8„  d   QhR\         R\        \        ,          R\        \        \         \        3,          ,          /# r¸  rÛ  )r,   s   "r-   r.   r.   h  sA   € ÷ NQñ NQÜðNQäœ$•ðNQô Œd”3œ�8�nÕñNQr/   c                ó’  € V '       g   R# T;'       g    \        4       pVR,          p\        V4      V ,          R,          p\        V4      pV'       g   R# \        V4      pVf   R# . p\         FZ  p\	        WX4      p	V	RR/ . 39   d   K  \	        Wh4      p
W©8X  d   K.  \        WhV	4       VP                  RP                  V4      4       K\  	  V'       g   R#  ^ RIH	p V! W64       \        P                  RRP                  T4      T 4       R	R
RTRT /#   \        \        3 d"   p\        P                  RT4        Rp?R# Rp?ii ; i)u½  Safety net for silent config.yaml model/MoA loss across ``hermes update``.

Desktop update/repair cycles have been observed to rewrite user-set
``model.provider``/``model.default`` and drop the ``moa:`` section
entirely (issue #64160; the macOS repair/relaunch variant rewrote a
pinned ``model.default`` to a transient composer pick). These keys are
consumed by the gateway and unattended cron jobs too, so a rewrite
silently changes paid inference behavior machine-wide.

Mirrors :func:`restore_cron_jobs_if_emptied`: compare the *current*
config against the pre-update snapshot taken minutes earlier by this
same update run, and restore only the protected keys â€” never the whole
file â€” when a value the user had set was changed or dropped. Everything
the update legitimately wrote (version stamps, new sections) is left in
place.

Args:
    snapshot_id: The pre-update quick-snapshot id (from
        :func:`create_quick_snapshot`).
    hermes_home: Override for the Hermes home directory (tests/siblings).

Returns:
    ``None`` when no action was taken (the common, healthy path). On a
    successful restore, ``{"restored": True, "keys": [...],
    "snapshot_id": ...}`` so the caller can warn the user.
Nrä  Ú rœ   )Úatomic_config_writezSconfig.yaml model settings were rewritten during update but auto-restore failed: %suf   Restored user config value(s) %s from pre-update snapshot %s â€” the update flow rewrote them (#64160)rë  r  TÚkeysr¹  )r   rA  rø  Ú_PROTECTED_CONFIG_PATHSrþ  r  r‘  rA  Úhermes_cli.configr  r�   ro  r²   r4  r³   )r¹  rb   r‰  rß  rá  ÚsnapÚliveÚrestored_keysrú  Úsnap_valÚlive_valr  r½   s   &&           r-   Ú*restore_config_model_settings_if_rewrittenr  h  s<  € ÷< Ùà×+Ð+œ/Ó+€DØ�}Õ$€IÜ$ TÓ*¨[Õ8¸=ÕH€Iä˜yÓ)€DßÙÜ˜yÓ)€DØ‚|ñ à!€Mß)ˆÜ)¨$Ó7ˆØ˜˜b " bÐ)Ô)ÙÜ)¨$Ó7ˆØÔÙÜ˜t¨XÔ6Ø×Ñ˜SŸX™X fÓ-Ö.ñ *÷ Ùð
Ý9á˜IÔ,ô ‡N�Nð	0à�	‰	�-Ó Øô	ð ˜˜f m°]ÀKÐPÐPøô ”_Ð%ô Ü�‰ð&àô	
õ
 ûðús   ÃD ÄEÄ%EÅEc          	      ó¬   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          R\        \         \        \
        3,          ,          /# ©r'   Úprofile_snapshotsrå  r)   ©r!  r7   r   r   r*   r	   )r,   s   "r-   r.   r.   ¹  s?   € ÷ "ñ "ÜœC¤˜H•~ð"äœD•>ð"ô 
Œ$Œs”Cˆx�.Õñ"r/   c                ó†  € . pV '       g   V# T;'       g    \        4       p\        \        V4      4      pV P                  4        FH  w  rVVP	                  V4      pVf   K   \        WgR7      pT'       g   K3  YXR&   TP                  T4       KJ  	  V#   \         d#   p	\        P                  RTT	4        Rp	?	Kv  Rp	?	ii ; i)aB  Run the config model-settings safety net for every sibling profile.

Same contract as :func:`restore_cron_jobs_all_profiles`: each profile's
live ``config.yaml`` is compared against ITS OWN same-generation
pre-update snapshot. Returns one result dict per restored profile, each
with a ``profile`` key added. Never raises.
N©rb   z=Config model-settings restore check for profile %s failed: %sÚprofile)
r   r!  rî  ÚitemsrÓ  r  r°   r²   r;  r‘  ©
r  rå  r  r‰  Úby_namer…   rŸ  rñ  Úresultr½   s
   &&        r-   Ú*restore_config_model_settings_all_profilesr  ¹  s½   € ð &(€HßØˆØ×-Ð-œOÓ-€DÜÔ)¨$Ó/Ó0€GØ*×0Ñ0Ö2‰ˆØ—{‘{ 4Ó(ˆØÒÙð
	Ü?ØôˆF÷ ‰6Ø $�9ÑØ�O‰O˜FÖ#ñ# 3ð$ €Oøô ô 	Ü�L‰LØOØØôõ
 ûð	ús   Á"BÂC ÂB;Â;C c          	      ó¬   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          R\        \         \        \
        3,          ,          /# r  r  )r,   s   "r-   r.   r.   Þ  s?   € ÷ ñ ÜœC¤˜H•~ðäœD•>ðô 
Œ$Œs”Cˆx�.Õñr/   c                ó„  € . pV '       g   V# T;'       g    \        4       p\        \        V4      4      pV P                  4        FH  w  rVVP	                  V4      pVf   K   \        WgR7      pT'       g   K3  YXR&   TP                  T4       KJ  	  V#   \         d"   p	\        P                  RYY4        Rp	?	Ku  Rp	?	ii ; i)u¶  Run the cron-jobs safety net for every sibling profile (#66140).

``profile_snapshots`` is the map returned by
:func:`create_pre_update_snapshots_all_profiles`. Each profile's live
``cron/jobs.json`` is compared against ITS OWN snapshot â€” restores are
same-generation by construction (the snapshot was taken minutes ago by
this update run). Returns one result dict per restored profile, each
with a ``profile`` key added. Never raises.
Nr  z,Cron restore check for profile %s failed: %sr  )
r   r!  rî  r  rÓ  rã  r°   r²   r;  r‘  r  s
   &&        r-   Úrestore_cron_jobs_all_profilesr  Þ  s²   € ð &(€HßØˆØ×-Ð-œOÓ-€DÜÔ)¨$Ó/Ó0€GØ*×0Ñ0Ö2‰ˆØ—{‘{ 4Ó(ˆØÒÙð	Ü1°'ÔTˆF÷ ‰6Ø $�9ÑØ�O‰O˜FÖ#ñ 3ð €Oøô ô 	Ü�L‰LÐGÈÔSÝûð	ús   Á"BÂB?ÂB:Â:B?c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r'   rC  rÂ  r)   )r   r+   )r,   s   "r-   r.   r.   ÿ  s!   € ÷ ñ ¤ð ¬Sð Ì3ñ r/   c                óL  € V P                  4       '       g   ^ # \        R V P                  4        4       R RR7      p^ pW!R  F#  p \        P                  ! V4       V^,          pK%  	  V#   \
         d-   p\        P                  RTP                  T4        Rp?K[  Rp?ii ; i)zKRemove oldest quick snapshots beyond the keep limit. Returns count deleted.c              3   óâ   "  € T Fe  pVP                  4       '       g   K  VP                  P                  R 4      '       d   K>  VP                  P                  R4      '       d   Ka  Vx € Kg  	  R# 5i)rœ   rž   N)rÙ   r…   rö   rÍ   rÁ  s   & r-   rÑ   Ú)_prune_quick_snapshots.<locals>.<genexpr>  sO   é € ð 	
á#�Ø�x‰x�zô à"#§&¡&×"3Ñ"3°C×"8ô àABÇÁÇÁÐQ[×A\÷ ŠAÛ#ùs   ‚A/ŸA/ÁA/Á%
A/c                 ó   € V P                   # r1   rF  )rà   s   &r-   r1  Ú(_prune_quick_snapshots.<locals>.<lambda>
  s   € �a—f’fr/   TrH  NzFailed to prune snapshot %s: %s)	rµ   rÆ  r÷  r“  r”  r�   r²   r³   r…   )rC  rÂ  ÚdirsrS  rà   r½   s   &&    r-   r›  r›  ÿ  s˜   € à�;‰;�=Š=Ùäñ	
à—\‘\”^ó	
ñ
 Øô€Dð €GØ�%‹[ˆð	KÜ�MŠM˜!ÔØ�q�LŠGñ ð €Nøô ô 	KÜ�N‰NÐ<¸a¿f¹fÀc×JÒJûð	Kús   ÁA,Á,B#Á7!BÂB#c                óR   € V ^8„  d   QhR\         R\        \        ,          R\         /# )r'   rÂ  rb   r)   )r+   r   r   )r,   s   "r-   r.   r.     s/   € ÷ Pñ PÜ
ðPäœ$•ðPô 	ñPr/   c                ó.   € \        \        V4      V R7      # )z6Manually prune quick snapshots. Returns count deleted.r’  )r›  rA  )rÂ  rb   s   &&r-   Úprune_quick_snapshotsr)    s   € ô
 "Ô"6°{Ó"CÈ$ÔOÐOr/   c                ó   € V ^8„  d   QhRR/# )r'   r)   Nr2   )r,   s   "r-   r.   r.   !  s   € ÷ 
3ñ 
3˜dñ 
3r/   c                óô   € \        V RR4      p\        VR7      pV'       dL   \        RV 24       \        4       p\        R\	        V4       R\        4        R24       \        RV 24       R# \        R	4       R# )
z*CLI entry point for hermes backup --quick.rx  N)rx  zState snapshot created: r©  z snapshot(s) stored in z/state-snapshots/z"  Restore with: /snapshot restore z!No state files found to snapshot.)rí   r~  r~  r¯  rR   r   )r   rx  rŸ  Úsnapss   &   r-   Úrun_quick_backupr-  !  sp   € ä�D˜' 4Ó(€EÜ#¨%Ô0€GßÜÐ(¨¨	Ð2Ô3Ü$Ó&ˆÜ�”3�u“:�,Ð5Ô6IÓ6KÐ5LÐL]Ð^Ô_ÜÐ2°7°)Ð<Ö=äÐ1Ö2r/   c                óR   € V ^8„  d   QhR\         R\         R\        \         ,          /# ©r'   rû   rú   r)   ©r   r   )r,   s   "r-   r.   r.   2  s%   € ÷ ñ ¤Tð ¼ð ÄÌ$Åñ r/   c                óÜ   €  \        V4      ;_uu_ 4        \        W4      uuRRR4       #   + '       g   i     R# ; i  \         d"   p\        P	                  RT4        Rp?R# Rp?ii ; i)z5Single-flight wrapper for automatic full zip backups.NzFull-zip backup skipped: %s)r—   Ú_write_full_zip_backup_lockedrX   r²   r³   )rû   rú   r½   s   && r-   rh  rh  2  sJ   € ðÜ# K×0Õ0Ü0°ÓG÷ 1×0×0Ó0ûä ô Ü�‰Ð4°cÔ:Ýûðús)   ‚? •+ 
? «<	¶? ¼? ¿A+Á
A&Á&A+c                óR   € V ^8„  d   QhR\         R\         R\        \         ,          /# r/  r0  )r,   s   "r-   r.   r.   <  s+   € ÷ Eñ E¬Dð E¼tð EÌÔQUÍñ Er/   c                 óˆ  a aaaa€ \         P                  ! 4       p\        P                  R 4        \	        \        VS 4      4      oS'       g   R# \        P                  R\         P                  ! 4       T,
          R,          \        S4      4       R R lp. oR T3R llpS P                  S P                  \        ,           4      oRoR	 TTT TT3R
 llp\         P                  ! 4       p \        S T4      ;_uu_ 4       p\        P                  ! TR\        P                  ^R7      ;_uu_ 4       p	\!        T	SS TRT3R lT3R lR7       RRR4       RRR4       Sf   \        P                  RT! 4       4       R# SP%                  4       P&                  p
SS 8w  dV   \        P                  R\         P                  ! 4       T,
          R,          \        S4      \        S4      T
ST! 4       4       R# \        P                  R\         P                  ! 4       T,
          R,          \        S4      T
4       S #   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i  + '       g   i     EL#; i  + '       g   i     EL/; i  \        \"        3 d"   p\        P                  RT4        Rp?R# Rp?ii ; i)z*automatic backup phase=scan status=startedz Full-zip backup: walk failed: %sNzEautomatic backup phase=scan status=complete duration_ms=%.1f files=%dr¤  c                ó(   € V ^8„  d   QhR\         RR/# )r'   rJ   r)   Nr   )r,   s   "r-   r.   Ú3_write_full_zip_backup_locked.<locals>.__annotate__I  s   € ÷ 2ñ 2œdð 2 tñ 2r/   c                 óV   € \         P                  R V 4       \        \        V 4      4      h)z6Full-zip backup aborted: SQLite snapshot failed for %s)r²   r³   r`   r7   )rJ   s   &r-   Ú_db_failureÚ2_write_full_zip_backup_locked.<locals>._db_failureI  s!   € Ü�‰ÐOÐQYÔZÜ"¤3 x£=Ó1Ð1r/   c                ó$   € V ^8„  d   QhR\         /# r5   r6   )r,   s   "r-   r.   r6  O  s   € ÷ Tñ TœCñ Tr/   c                  óˆ   <€ R P                  SR,          4      p \        S4      ^
8”  d   V  R\        S4      ^
,
           R2# T # )r:  r{  z (+z more))rA  rR   )Úshownr³  s    €r-   Ú_capped_errorsÚ5_write_full_zip_backup_locked.<locals>._capped_errorsO  sB   ø€ à—	‘	˜& �+Ó&ˆÜ8;¸F»ÀbÔ8H�%�˜œC ›K¨"Õ,Ð-¨VÐ4ÐSÈeÐSr/   c                ó:   € V ^8„  d   QhR\         \        ,          /# r5   r>  )r,   s   "r-   r.   r6  \  s   € ÷ ñ œ8¤D�>ñ r/   c                  óV   <€ S '       g   SoS# \        S 4      \        S4      8  d   SoS# r1   )rR   )r³  ri  rû   Ú	publishedÚsalvage_paths   €€€€€r-   Ú_publish_pathÚ4_write_full_zip_backup_locked.<locals>._publish_path\  s3   ø€ ÷ Ø ˆIð Ðô �‹[œ3˜|Ó,Ô,Ø$ˆIØÐr/   r®  r¯  Fc                 ó0   <€ SP                  V  R V 24      # r¶  r²  r·  s   &&€r-   r1  Ú/_write_full_zip_backup_locked.<locals>.<lambda>k  s   ø€ ¨&¯-©-¸3¸%¸rÀ#À¸Ô*Hr/   c                 óD   <€ \         P                  R V \        S4      4      # )zDautomatic backup phase=archive status=progress completed=%d total=%d)r²   rï   rR   )rt  ri  s   &€r-   r1  rF  l  s   ø€ ¤f§k¡kØZÐ\]Ô_bÐcoÓ_pô'rr/   )rp  rj  rq  rr  z%Full-zip backup: zip write failed: %sz9Full-zip backup: every entry failed, nothing salvaged: %szsautomatic backup phase=archive status=incomplete duration_ms=%.1f files=%d errors=%d bytes=%d salvage=%s skipped=%szQautomatic backup phase=archive status=complete duration_ms=%.1f files=%d bytes=%d)r�   r‚   r²   rï   r*   r	  r�   r³   rR   r¡   ÚstemrZ  rª   rJ  rK  rÄ  ru  r`   r†   r‡   )rû   rú   rÈ  r½   r8  r=  rC  Úarchive_startedrÊ  rH  rÌ  r³  ri  rA  rB  s   f&         @@@@r-   r2  r2  <  s6  ü€ Ü—>’>Ó#€LÜ
‡K�KÐ<Ô=ðÜÔ.¨{¸HÓEÓFˆ÷ ÙÜ
‡K�KÐWÜ—’Ó! LÕ0°DÕ8¼#¸lÓ:KôMõ2ð €F÷Tð Tð ×%Ñ% h§m¡mÔ6LÕ&LÓM€Là $€I÷ô ô —n’nÓ&€OðÜ  ¨=×9Ô9¸\Ì7Ï?Ê?Ø˜c¤7×#7Ñ#7Àq÷LJõ LJØMOÜØ�L (¸+ÐSXÜHôrõs÷LJ×9ð ÒÜ�‰ÐRÑTbÓTdÔeÙØ�~‰~Ó×'Ñ'€HØ�HÔÜ�‰ð-ä�^Š^Ó Õ/°4Õ7¼¸\Ó9JÌCÐPVËKÐYaØ™.Ó*ô		,ñ
 ä
‡K�KÐcÜ—’Ó! OÕ3°tÕ;¼SÀÓ=NÐPXôZà€OøôA ô Ü�‰Ð9¸3Ô?Ýûðú÷LLJ÷ LJð LJú×9×9Ð9ûô Ô)Ð*ô ä�‰Ð>ÀÔDÝûðúse   ±H8 Ã-J Ä1I;Ä2I'	ÅI;ÅJ È8I$ÉIÉI$É'I8É2	I;É;J	ÊJ ÊJ ÊKÊ J<Ê<Kc                ó$  € V ^8„  d   Qh/ ^ \         9   d"   \        \        \        ,          R3,          ;R&   ^\         9   d"   \        \        \        ,          R3,          ;R&   ^\         9   d$   \        \        \        R3,          R3,          ;R&   # )r'   .Ú_LZMA_ERRORSrÒ  r	  )Ú__conditional_annotations__rk  Útyper§   r7   )r,   s   "r-   r.   r.      s}   € × 0Ñ 0÷n FÒE”%œœ]Õ+¨SÐ0Õ1ÑEño 1÷z=ò =œœt¤MÕ2°CÐ7Õ8ñ =ñ{ 1÷x9ò œœu¤S¨# X�°Ð3Õ4ñ òy9 1r/   )z.db-walz.db-shmz.db-journal>   úcron.pidúgateway.pidrf   >   rN  rO  úgateway.lockúprocesses.jsonúgateway_state.jsonr2   >   rå  rV   r³  ú	vault.keyúvault.json.enc)g      Ð?r1   l        )rV   rä  rå  r³  r<  zcron/executions.dbrR  zchannel_directory.jsonzchannel_aliases.jsonrQ  z#gateway/discord_message_recovery.dbzprojects.dbzresponse_store.dbzmemory_store.dbzverification_evidence.dbz	kanban.dbzkanban/boardsÚpairingzplatforms/pairingzfeishu_comment_pairing.json)NNNN)é   N)NNN))Úmodelr»   )rW  rê  )rW  Úbase_url)rW  Úapi_key)Úmoa)¦rL  r]   r™  Úloggingr„   r“  r  r†   r�  rc  r£   r�   rJ  ÚzlibÚ
contextlibr   r   r   r   r   Úpathlibr   Útypingr	   r
   r   r   r   r   Úhermes_constantsr   r   r   r   r   Úhermes_state_dbfiler   Úhermes_state_holdersr   Úagent.provider_mediar   Úhermes_cli.archive_safer   Úhermes_cli.backup_sqliter   r   Úhermes_cli.home_data_layoutr   r   Úhermes_cli.sizefmtr   rÅ  Úhermes_cli.backup_restorer   r   r   r    r!   r"   r#   r$   r%   Ú	getLoggerrY   r²   r3   r@  r9   rÛ   rP   Ú	frozensetrQ   rS   rU   rÜ  rÎ   rÌ   r÷   rÛ  ÚlzmaÚ	LZMAErrorrK  rø  Ú
BadZipFiler4  rò  rÒ  r(  r’  r´  rX   r`   r—   rª   rÂ   rá   rË   rð   rø   r	  r  r  r=  Ú!DEFAULT_INTEGRITY_CHECK_MAX_BYTESrF  rW  r[  rg  ru  r€  r†  rŽ  r˜  r¡  rŸ  rÖ  rÝ  rá  r  rõ  r*  r  rù  r•  rœ  rA  rM  rÞ  rT  rg  ro  Ú_PRE_UPDATE_DEFAULT_KEEPrt  Ú_PRE_MIGRATION_DEFAULT_KEEPrZ  rÇ  rc  ri  rq  ru  r~  r}  r¯  r¶  r½  rÁ  rÅ  rÉ  r¼  rÙ  rã  rî  rò  r	  rø  rþ  r  r  r  r  r›  r)  r-  rh  r2  r.   )rL  s   @r-   Ú<module>rq     sñ  øðÞ 0ã Û Û 	Û Û Û Û 
Û Û Û Û Û ß /ß ,Ñ ,Ý ß =× =÷õ õ >Ý 1å 1Ý ;ß Bß PÝ ;÷
÷ 
õ 
ð 
×	Ò	˜8Ó	$€õð )Ð õ4ð ØØ
ØØØØð ð àˆV�_àˆf�f˜o¨}¸mð#€ð, .Ð1EÈÈ	Õ1QÕRÐ ñ
 'Ð(:Ð';Ó<Ð ð ˆg�x ¨m¸[ÐJZð\Ð õ[ð AÐ Ø˜fÐ@Ð'?Ñ@Ð ò >€ð %ØÐ,Ð-Ð.ðÐ ò iÐ ðÛØ59·^±^Ð4E€LÓEð ×Ñ˜Ÿ
™
 Hð<=Ø/;ñ<=Ð ó =ò VÐ ð
  Ð ôK˜Lô Kô	˜<ô 	ð ö#ó ð#ðL öó ðõ*õ@õ	õ
põ	o÷õF	ðZ¸Cð ZÈu÷ Zð2 &€ð %,Ð !ð/?Ø(,ð/?ØAEð/?à6÷/?õdHõ,õ'õ õ<9ð &Ð õõ*-õ&%õ,CõPõ,4õ	%õsDõlWõ.õ6gKõT`ðDÐ ð$ Ð ÷'õ
Zð "€õ	ð $Ð Ø"Ð ØÐ Ø(Ð ØÐ Ø*Ð õ;õHõð4 #'Ð4L÷oð #'Ð4O÷c÷
÷"p÷fõ4÷õ(
õ÷:õ(:4õz÷>ISõX÷DðH8Ð ó õ4õõ÷NQ÷b"÷JðB 4G÷ ð6 $Ø"&÷Põ
3õ"÷EøðG= ô ØƒLðús   Ä)M Í	MÍM