+
    #j                         R t ^ RIH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 tR R ltR tR tR tR R ltR R ltR tR tR# )an  Merge adjacent runs with identical formatting in DOCX.

Merges adjacent <w:r> elements that have identical <w:rPr> properties.
Works on runs in paragraphs and inside tracked changes (<w:ins>, <w:del>).

Also:
- Removes rsid attributes from runs (revision metadata that doesn't affect rendering)
- Removes proofErr elements (spell/grammar markers that block merging)
)PathNc                R    V ^8  d   QhR\         R\        \        \         3,          /# )   	input_dirreturn)strtupleint)formats   "z/opt/hermes-venv/lib/python3.14/site-packages/../../../skills/productivity/powerpoint/scripts/office/helpers/merge_runs.py__annotate__r      s"        #  %S/      c                 2   \        V 4      R ,          R,          pVP                  4       '       g	   ^ RV R23#  \        P                  P	                  VP                  RR7      4      pVP                  p\        VR4       \        V4       \        VR4       Uu0 uF  qDP                  kK  	  pp^ pV F  pV\        V4      ,          pK  	  VP                  VP                  RR7      4       VR	V R
23# u upi   \         d   p^ RT 23u Rp?# Rp?ii ; i)wordzdocument.xmlzError: z
 not foundzutf-8)encodingproofErrrzUTF-8zMerged z runsN)r   exists
defusedxmlminidomparseString	read_textdocumentElement_remove_elements_strip_run_rsid_attrs_find_elements
parentNode_merge_runs_inwrite_bytestoxml	Exception)	r   doc_xmldomrootrun
containersmerge_count	containeres	   &        r   
merge_runsr)      s   9o&7G>>GG9J///   ,,W->->->-PQ""z*d#0>tS0IJ0Inn0I
J#I>)44K $ 	CIIwI78gk]%888 K   GA3- s1   A C: C5-AC: 5C: :DDDDc                0    V ^8  d   QhR\         R\        /# r   tagr   r   list)r
   s   "r   r   r   ,   s      c d r   c                 0   aaa . oVVV3R  loS! V 4       S# )c                   < V P                   V P                  8X  dp   V P                  ;'       g    V P                  pVS8X  g   VP	                  R S 24      '       d   SP                  V 4       V P                   F  pS! V4       K  	  R# R# :N)nodeTypeELEMENT_NODE	localNametagNameendswithappend
childNodes)nodenamechildresultsr,   traverses   &  r   r>    _find_elements.<locals>.traverse/   sk    ==D--->>11T\\Ds{dmmauI66t$ )	 .r    )r#   r,   r=   r>   s   &f@@r   r   r   ,   s    G  TNNr   c                $    V ^8  d   QhR\         /# r   r,   r   )r
   s   "r   r   r   ;   s      C r   c                     V P                    Fd  pVP                  VP                  8X  g   K   VP                  ;'       g    VP                  pW18X  g   VP                  R V 24      '       g   Kb  Vu # 	  R# r1   )r9   r3   r4   r5   r6   r7   )parentr,   r<   r;   s   &&  r   
_get_childrF   ;   s\    "">>U///??33emmD{dmmauI66	 #
 r   c                0    V ^8  d   QhR\         R\        /# r+   r-   )r
   s   "r   r   r   D   s      s t r   c                    . pV P                    Fs  pVP                  VP                  8X  g   K   VP                  ;'       g    VP                  pWA8X  g   VP                  R V 24      '       g   Kb  VP                  V4       Ku  	  V# )r2   )r9   r3   r4   r5   r6   r7   r8   )rE   r,   r=   r<   r;   s   &&   r   _get_childrenrI   D   sj    G"">>U///??33emmD{dmmauI66u%	 #
 Nr   c                $    V ^8  d   QhR\         /# r   r   bool)r
   s   "r   r   r   N   s     
 
$ 
r   c                    V P                   pV'       dq   W!8X  d   R # VP                  VP                  8X  d   R# VP                  VP                  8X  d#   VP                  P                  4       '       d   R# VP                   pKx  R# )TF)nextSiblingr3   r4   	TEXT_NODEdatastrip)elem1elem2r:   s   && r   _is_adjacentrU   N   s^    D
===D---==DNN*tyy/@/@r   c                $    V ^8  d   QhR\         /# rB   rC   )r
   s   "r   r   r   ]   s     . . .r   c                     \        W4       F2  pVP                  '       g   K  VP                  P                  V4       K4  	  R # N)r   r   removeChild)r#   r,   elems   && r   r   r   ]   s,    t)???OO''- *r   c                     \        V R 4       Fi  p\        VP                  P                  4       4       F?  pRVP                  P                  4       9   g   K$  VP                  VP                  4       KA  	  Kk  	  R# )r   rsidN)r   r.   
attributesvaluesr;   lowerremoveAttribute)r#   r$   attrs   &  r   r   r   c   sT    dC(..01D**##DII. 2 )r   c                $    V ^8  d   QhR\         /# rK   )r	   )r
   s   "r   r   r   l   s       r   c                    ^ p\        V 4      pV'       dw    \        V4      pV'       dJ   \        V4      '       d9   \        W#4      '       d(   \	        W#4       V P                  V4       V^,          pK]   \        T4       \        T4      pK~  V# )    )_first_child_run_next_element_sibling_is_run
_can_merge_merge_run_contentrY   _consolidate_text_next_sibling_run)r'   r&   r$   	next_elems   &   r   r   r   l   ss    K
9
%C
-c2IWY//Js4N4N"32%%i0q #$r   c                     V P                    F5  pVP                  VP                  8X  g   K   \        V4      '       g   K3  Vu # 	  R # rX   )r9   r3   r4   rg   )r'   r<   s   & r   re   re      s6    %%>>U///GENNL & r   c                     V P                   pV'       d,   VP                  VP                  8X  d   V# VP                   pK3  R # rX   )rO   r3   r4   r:   siblings   & r   rf   rf      s7    G
w333N%%r   c                     V P                   pV'       d=   VP                  VP                  8X  d   \        V4      '       d   V# VP                   pKD  R # rX   )rO   r3   r4   rg   ro   s   & r   rk   rk      sB    G
w333w%%r   c                $    V ^8  d   QhR\         /# rK   rL   )r
   s   "r   r   r      s     . .T .r   c                 ~    V P                   ;'       g    V P                  pVR 8H  ;'       g    VP                  R4      # )r   z:r)r5   r6   r7   )r:   r;   s   & r   rg   rg      s2    >>))T\\D3;--$----r   c                $    V ^8  d   QhR\         /# rK   rL   )r
   s   "r   r   r      s     ( (d (r   c                     \        V R 4      p\        VR 4      pVRJ VRJ 8w  d   R# Vf   R# VP                  4       VP                  4       8H  # )rPrNFT)rF   r   )run1run2rpr1rpr2s   &&  r   rh   rh      sL    dE"DdE"D$$,'|::<4::<''r   c                    \        VP                  4       Fs  pVP                  VP                  8X  g   K   VP                  ;'       g    VP
                  pVR 8w  g   KI  VP                  R4      '       d   Kb  V P                  V4       Ku  	  R# )rv   z:rPrN)r.   r9   r3   r4   r5   r6   r7   appendChild)targetsourcer<   r;   s   &&  r   ri   ri      sa    f''(>>U///??33emmDu}T]]6%:%:""5)	 )r   c                    \        V R 4      p\        \        V4      ^,
          ^ R4       EFP  pW,          W^,
          ,          rC\        WC4      '       g   K-  VP                  '       d   VP                  P
                  MRpVP                  '       d   VP                  P
                  MRpWV,           pVP                  '       d   WtP                  n        M*VP                  V P                  P                  V4      4       VP                  R4      '       g   VP                  R4      '       d   VP                  RR4       M(VP                  R4      '       d   VP                  R4       V P                  V4       EKS  	  R# )t  z	xml:spacepreserveN)rI   rangelenrU   
firstChildrQ   r|   ownerDocumentcreateTextNode
startswithr7   setAttributehasAttributer`   rY   )r$   
t_elementsicurrprev	prev_text	curr_textmergeds   &       r   rj   rj      s   sC(J3z?Q&2.]J1u$5d##04,,RI04,,RI*F'-$  !2!2!A!A&!IJ  %%)=)=!!+z:"";//$$[1OOD!% /r   )__doc__pathlibr   defusedxml.minidomr   r)   r   rF   rI   rU   r   r   r   re   rf   rk   rg   rh   ri   rj   r@   r   r   <module>r      s]      8
./(.
(*"r   