+
    #jo%                        R t ^ RIt^ RIHt ^ RIt^ RItR R ltR R ltR R lt	R	 R
 lt
R R ltR R ltR R ltR R ltR R lt]R8X  d   ]! ]P$                  4      ^8w  d;   ]! R]P(                  R7       ]! R]P(                  R7       ]P*                  ! ^4       ]! ]P$                  ^,          4      t]P/                  4       '       g+   ]! R] R2]P(                  R7       ]P*                  ! ^4       ]! ]4      t]'       d)   ]! R]! ]4       R24       ] F  t]! R] 24       K  	  R# ]! R4       R# R# )a  Remove unreferenced files from an unpacked PPTX directory.

Usage: python clean.py <unpacked_dir>

Example:
    python clean.py unpacked/

This script removes:
- Orphaned slides (not in sldIdLst) and their relationships
- [trash] directory (unreferenced files)
- Orphaned .rels files for deleted resources
- Unreferenced media, embeddings, charts, diagrams, drawings, ink files
- Unreferenced theme files
- Unreferenced notes slides
- Content-Type overrides for deleted files
N)Pathc                F    V ^8  d   QhR\         R\        \        ,          /#    unpacked_dirreturn)r   setstr)formats   "f/opt/hermes-venv/lib/python3.14/site-packages/../../../skills/productivity/powerpoint/scripts/clean.py__annotate__r      s"     Q Q Q#c( Q    c                    V R ,          R,          pV R ,          R,          R,          pVP                  4       '       d   VP                  4       '       g   \        4       # \        P                  P	                  \        V4      4      p/ pVP                  R4       Fl  pVP                  R4      pVP                  R4      pVP                  R4      pRV9   g   K?  VP                  R	4      '       g   KX  VP                  R	R
4      WF&   Kn  	  VP                  RR7      p	\        \        P                  ! RV	4      4      p
V
 Uu0 uF  qfV9   g   K  WF,          kK  	  up# u upi )pptzpresentation.xml_relspresentation.xml.relsRelationshipIdTargetTypeslideslides/ utf-8encodingz<p:sldId[^>]*r:id="([^"]+)")existsr   
defusedxmlminidomparser	   getElementsByTagNamegetAttribute
startswithreplace	read_textrefindall)r   	pres_pathpres_rels_pathrels_domrid_to_sliderelridtargetrel_typepres_contentreferenced_ridss   &          r   get_slides_in_sldidlstr1      s,   u$'99I!E)G36MMN^%:%:%<%<u!!''N(;<HL,,^<t$!!(+##F+h6#4#4Y#?#? &y" =L = &&&8L"**%C\RSO)8P#<<OLPPPs   ?EEc                F    V ^8  d   QhR\         R\        \        ,          /# r   r   listr	   )r
   s   "r   r   r   1   s     ' ' '$s) 'r   c                    V R ,          R,          pVR,          pV R ,          R,          R,          pVP                  4       '       g   . # \        V 4      p. pVP                  R4       F  pVP                  V9  g   K  VP	                  V 4      pVP                  4        VP                  \        V4      4       W&P                   R2,          pVP                  4       '       g   K~  VP                  4        VP                  \        VP	                  V 4      4      4       K  	  V'       Ed    VP                  4       '       Ed	   \        P                  P                  \        V4      4      p	Rp
\        V	P                  R4      4       Fx  pVP                  R4      pVP                  R	4      '       g   K-  VP                  R	R
4      pW9  g   KG  VP                   '       g   K[  VP                   P#                  V4       Rp
Kz  	  V
'       dA   \%        VR4      ;_uu_ 4       pVP'                  V	P)                  RR7      4       RRR4       V# V#   + '       g   i     T# ; i)r   slidesr   r   z
slide*.xml.relsFr   r   r   r   Twbr   r   N)r   r1   globnamerelative_tounlinkappendr	   r   r   r   r4   r    r!   r"   r#   
parentNoderemoveChildopenwritetoxml)r   
slides_dirslides_rels_dirr(   referenced_slidesremoved
slide_filerel_path	rels_filer)   changedr+   r-   
slide_namefs   &              r   remove_orphaned_slidesrM   1   s   %0J 7*O!E)G36MMN	.|<G ool3
??"33!--l;HNN3x=)'__,=U*CCI!!  "s9#8#8#FGH 4 w>((**%%++C,?@55nEFC%%h/F  ++#^^Ir:
6~~~2237"& G nd++q89 , N7N ,+ Ns   "II	c                F    V ^8  d   QhR\         R\        \        ,          /# r   r3   )r
   s   "r   r   r   [   s       $s) r   c                 h   V R ,          p. pVP                  4       '       d   VP                  4       '       d{   VP                  4        FV  pVP                  4       '       g   K  VP	                  V 4      pVP                  \        V4      4       VP                  4        KX  	  VP                  4        V# )z[trash])	r   is_diriterdiris_filer;   r=   r	   r<   rmdir)r   	trash_dirrF   	file_pathrH   s   &    r   remove_trash_directoryrV   [   s    y(IGi..00"**,I  ""$00>s8}-  "	 -
 	Nr   c                0    V ^8  d   QhR\         R\        /# r   r   r   )r
   s   "r   r   r   j   s      T c r   c                 6   \        4       pV R ,          R,          R,          pVP                  4       '       g   V# VP                  R4       F  p\        P                  P                  \        V4      4      pVP                  R4       Fx  pVP                  R4      pV'       g   K  VP                  P                  V,          P                  4       p VP                  VP                  V P                  4       4      4       Kz  	  K  	  V#   \         d     K  i ; i)r   r6   r   *.relsr   r   )r   r   r9   r   r   r   r	   r    r!   parentresolveaddr;   
ValueError)r   
referencedrD   rI   domr+   r-   target_paths   &       r   get_slide_referenced_filesrb   j   s    J"U*X5?O!!##$))(3	  &&s9~6++N;C%%h/F$++22V;DDFK{66|7K7K7MNO < 4   s   .D		DDc                F    V ^8  d   QhR\         R\        \        ,          /# r   r3   )r
   s   "r   r   r      s      T d3i r   c                 V   . ROp. p\        V 4      pV F  pV R,          V,          R,          pVP                  4       '       g   K2  VP                  R4       F  pVP                  VP                  P                  RR4      ,          p VP                  4       P                  V P                  4       4      pTP                  4       '       d	   Y9  g   K|  TP                  4        TP                  T 4      p	TP                  \        T	4      4       K  	  EK  	  V#   \         d     K  i ; i)chartsr   r   rZ   r7   r   )re   diagramsdrawings)rb   r   r9   r[   r:   r#   r\   r;   r^   r<   r=   r	   )
r   resource_dirsrF   slide_referenceddir_namerels_dirrI   resource_fileresource_rel_pathrH   s
   &         r   remove_orphaned_rels_filesrn      s    6MG1,?!%'(2W<  !x0I$OOinn.D.DWb.QQM$1$9$9$;$G$GH\H\H^$_! !''))->-V  "$00>s8}- 1 "" N  s   -DD('D(c                0    V ^8  d   QhR\         R\        /# r   rX   )r
   s   "r   r   r      s      t  r   c                    \        4       pV P                  R 4       F  p\        P                  P	                  \        V4      4      pVP                  R4       Fx  pVP                  R4      pV'       g   K  VP                  P                  V,          P                  4       p VP                  VP                  V P                  4       4      4       Kz  	  K  	  V#   \         d     K  i ; i)rZ   r   r   )r   rglobr   r   r   r	   r    r!   r[   r\   r]   r;   r^   )r   r_   rI   r`   r+   r-   ra   s   &      r   get_referenced_filesrr      s    J!''1	  &&s9~6++N;C%%h/F$++22V;DDFK{66|7K7K7MNO < 2   s   ".CC)(C)c                R    V ^8  d   QhR\         R\        R\        \        ,          /# )r   r   r_   r   )r   r   r4   r	   )r
   s   "r   r   r      s%     / / /# /$s) /r   c                    . ROp. pV F  pV R,          V,          pVP                  4       '       g   K+  VP                  R4       F^  pVP                  4       '       g   K  VP                  V 4      pWq9  g   K4  VP	                  4        VP                  \        V4      4       K`  	  K  	  V R,          R,          pVP                  4       '       d   VP                  R4       F  pVP                  V 4      pWq9  g   K  VP	                  4        VP                  \        V4      4       VR,          VP                   R2,          p	V	P                  4       '       g   K{  V	P	                  4        VP                  \        V	P                  V 4      4      4       K  	  V R,          R,          p
V
P                  4       '       Ed   V
P                  R4       F^  pVP                  4       '       g   K  VP                  V 4      pWq9  g   K4  VP	                  4        VP                  \        V4      4       K`  	  V
R,          pVP                  4       '       d   VP                  R	4       Fv  pWP                  P                  RR
4      ,          pVP                  4       '       d   K=  VP	                  4        VP                  \        VP                  V 4      4      4       Kx  	  V# )mediar   *themez
theme*.xmlr   r7   notesSlidesz*.xmlrZ   r   )ru   
embeddingsre   rf   tagsrg   ink)	r   r9   rR   r;   r<   r=   r	   r:   r#   )r   r_   rh   rF   rj   dir_pathrU   rH   	theme_dir
theme_rels	notes_dirnotes_rels_dir
notes_files   &&           r   remove_orphaned_filesr      sA   \MG!%'(2  !s+I$$&& ,,\:H)  "s8}- , " u$w.I"5I ,,\:H)  "s8}-&0inn5EU3KK
$$&&%%'NN3z'='=l'K#LM 6 u$}4I"0I$$&& ,,\:H)  "s8}- 1 #W,  ""+00:	&)?)?)LL
!((**$$&NN3y'<'<\'J#KL	 ; Nr   c                J    V ^8  d   QhR\         R\        \        ,          RR/# )r   r   removed_filesr   Nr3   )r
   s   "r   r   r      s%     1 1t 1DI 1$ 1r   c                 H   V R ,          pVP                  4       '       g   R# \        P                  P                  \	        V4      4      pRp\        VP                  R4      4       F\  pVP                  R4      P                  R4      pWa9   g   K+  VP                  '       g   K?  VP                  P                  V4       RpK^  	  V'       dA   \        VR4      ;_uu_ 4       pVP                  VP                  RR	7      4       RRR4       R# R#   + '       g   i     R# ; i)
z[Content_Types].xmlNFOverridePartName/Tr8   r   r   )r   r   r   r   r	   r4   r    r!   lstripr>   r?   r@   rA   rB   )r   r   ct_pathr`   rJ   override	part_namerL   s   &&      r   update_content_typesr      s    22G>>



"
"3w<
0CG11*=>))*5<<SA	%"""##//9 ? '4  AGGCIIwI/0 !     s   ""DD!	c                F    V ^8  d   QhR\         R\        \        ,          /# r   r3   )r
   s   "r   r   r      s      T d3i r   c                 ,   . p\        V 4      pVP                  V4       \        V 4      pVP                  V4        \        V 4      p\	        V 4      p\        W4      pWF,           pV'       g   MVP                  V4       KF  V'       d   \        W4       V# )T)rM   extendrV   rn   rr   r   r   )r   all_removedslides_removedtrash_removedremoved_relsr_   r   total_removeds   &       r   clean_unused_filesr      s    K+L9N~&*<8M}%
1,?),7
-lG$4=)\7r   __main__z%Usage: python clean.py <unpacked_dir>)filez"Example: python clean.py unpacked/zError: z
 not foundzRemoved z unreferenced files:z  zNo unreferenced files found)__doc__syspathlibr   defusedxml.minidomr   r%   r1   rM   rV   rb   rn   rr   r   r   r   __name__lenargvprintstderrexitr   r   rF   rL    r   r   <module>r      s  "    
Q,'T,2$/d1(4 z
388}5CJJG2D$L  ~Z0szzB .GW&:;<ABqc(O  	+,' r   