ó
    �®žj*"  ã                  ó2  • % S SK Jr  S SKrS SKrS SKrS SKJr  S SKJr  S SK	J
r
  S SKJr  S SKJr  S SKJrJrJrJr  S SKrS S	KJrJr  \(       a  S S
KJr  SrS\S'    SSS jjr\SS j5       r S         SS jjrSS jrSSS jjr       SS jr!g)é    )ÚannotationsN)ÚIterator)Úcontextmanager)ÚBytesIO)ÚPath)Úmkdtemp)ÚTYPE_CHECKINGÚCallableÚFinalÚOptional)ÚImageÚ
ImageChops)ÚDocumenté<   z
Final[int]ÚLIBREOFFICE_TIMEOUT_Sc                ó^  • [         R                  " S5      =(       dE    [         R                  " S5      =(       d(    [        R                  R	                  S5      (       a  SOSnU (       aC  Uc  [        S5      e[        R                  " US/[        R                  [        R                  SS9  U$ )	z2Return the libreoffice cmd and optionally test it.ÚlibreofficeÚsofficez4/Applications/LibreOffice.app/Contents/MacOS/sofficeNzLibreoffice not foundz-hT)ÚstdoutÚstderrÚcheck)	ÚshutilÚwhichÚosÚpathÚisfileÚRuntimeErrorÚ
subprocessÚrunÚDEVNULL)Úraise_if_unavailableÚlibreoffice_cmds     Úa/home/mande/repo/quber/.venv/lib/python3.13/site-packages/docling/backend/docx/drawingml/utils.pyÚget_libreoffice_cmdr$      s™   € ô 	�Š�]Ó#÷ 	
Ü�<Š<˜	Ó"÷	
ô �w‰w�~‰~ÐT×UÑUñ Càð ö ØÑ"ÜÐ6Ó7Ð7ô 	�ŠàØðô ×%Ñ%Ü×%Ñ%Øò	
ð Ðó    c               #  óº   #   • [        [        SS95      n  SU R                  5        3v •  [        R                  " U SS9  g! [        R                  " U SS9  f = f7f)a  Yield a ``-env:UserInstallation`` argument backed by a throwaway profile.

LibreOffice takes an exclusive lock on its user profile directory.
Without this, concurrent conversions (parallel workers, docling-serve
handling simultaneous requests) share the default profile and collide
on that lock, causing conversions to fail intermittently and silently.

Yields:
    A ``-env:UserInstallation=<uri>`` CLI argument pointing at a freshly
    created, empty profile directory. The directory is removed again
    once the ``with`` block exits.
Údocling_lo_profile_)Úprefixz-env:UserInstallation=T©Úignore_errorsN)r   r   Úas_urir   Úrmtree)Úprofile_dirs    r#   Ú_isolated_libreoffice_profiler.   =   sO   é € ô ”wÐ&;Ñ<Ó=€Kð7Ø& {×'9Ñ'9Ó';Ð&<Ð=Ò=ä�Š�k°Ó6øŒ�Š�k°Ó6üs   ‚A–A «AÁAÁAc                óê  • [        5       nUc  [        SU SU S35      e[        [        5       5      n [	        U [
        5      (       a9  U R                  S5        USU 3-  nUR                  U R                  5       5        OU n[        5        n[        R                  " UUSSUS	[        U5      [        U5      /[        R                  [        R                  S
US9  SSS5        XVR                  S-   U-   -  nUR                  5       (       d  [        SU 35      e[        UR!                  5       5      ["        R$                  " US
S9  $ ! , (       d  f       Ns= f! ["        R$                  " US
S9  f = f)a|  Convert a legacy binary Office file to modern Open XML format via LibreOffice.

Both file paths and in-memory streams are accepted.  When a ``BytesIO`` is
supplied the bytes are written to a temporary file (named with
``source_suffix`` so LibreOffice can detect the format) before invoking the
CLI; the temporary file is removed together with the rest of the temp
directory once the conversion finishes.

Args:
    source: Path to the source file, or a ``BytesIO`` with its contents.
    source_suffix: File extension of the source format without leading dot
        (e.g. ``"doc"``, ``"xls"``, ``"ppt"``).  Required when *source* is
        a ``BytesIO`` so the temp file gets the right name; ignored for
        ``Path`` inputs (the path's own suffix is used instead).
    target_suffix: Target extension without leading dot (``"docx"``,
        ``"xlsx"``, or ``"pptx"``).
    timeout_s: Timeout in seconds for the LibreOffice subprocess.

Returns:
    A ``BytesIO`` buffer with the converted file contents.

Raises:
    RuntimeError: When LibreOffice is not installed, the subprocess fails,
        or the expected output file is not produced.
Nz&LibreOffice is required to convert a .z
 file to .z2. Install LibreOffice and make sure it is on PATH.r   zinput.ú
--headlessú--convert-toú--outdirT©r   r   r   ÚtimeoutÚ.z1LibreOffice did not produce the expected output: r)   )r$   r   r   r   Ú
isinstancer   ÚseekÚwrite_bytesÚreadr.   r   r   Ústrr    ÚstemÚexistsÚ
read_bytesr   r,   )	ÚsourceÚsource_suffixÚtarget_suffixÚ	timeout_sr"   Útmp_dirÚ
input_pathÚprofile_argÚconverted_paths	            r#   Úconvert_to_modern_formatrF   R   s`  € ô> *Ó+€OØÑÜØ4°]°Oð DØˆÐPðRó
ð 	
ô
 ”7“9‹o€Gð"3Ü�fœg×&Ñ&Ø�K‰K˜ŒNØ  V¨M¨?Ð#;Ñ;ˆJØ×"Ñ" 6§;¡;£=Õ1àˆJä*Ô,°Ü�NŠNà#ØØ Ø"Ø!ØÜ˜“LÜ˜
“Oð	ô "×)Ñ)Ü!×)Ñ)ØØ!ò÷ -ð$ !§O¡O°cÑ$9¸MÑ$IÑJˆØ×$Ñ$×&Ñ&ÜØCÀNÐCSÐTóð ô �~×0Ñ0Ó2Ó3ä�Š�g¨TÓ2÷5 -Õ,ûô4 	�Š�g¨TÓ2ús&   ´AE ÂAE
ÃAE Å

EÅE ÅE2c                 óH   ^• [        5       mT(       a        SU4S jjn U $ g)z¯
Detects the best available DOCX to PDF tool and returns a conversion function.
The returned function accepts (input_path, output_path).
Returns None if no tool is available.
c                ó:  >• [        5        n[        R                  " TUSSSS[        R                  R                  U5      U /[        R                  [        R                  S[        S9  SSS5        [        R                  R                  [        R                  R                  U5      [        R                  R                  [        R                  R                  U 5      5      S   S	-   5      nX1:w  a  [        R                  " X15        gg! , (       d  f       N¨= f)
a¬  Convert a DOCX/PPTX file to PDF via LibreOffice.

Runs the conversion in its own throwaway LibreOffice profile
(see ``_isolated_libreoffice_profile``) with a bounded timeout,
so a hung ``soffice`` process cannot block the calling thread
forever and concurrent conversions cannot collide on the
default profile lock.

Args:
    input_path: Path to the source file to convert.
    output_path: Desired path for the converted PDF.
r0   r1   Úpdfr2   Tr3   Nr   z.pdf)r.   r   r   r   r   Údirnamer    r   ÚjoinÚsplitextÚbasenameÚrename)rC   Úoutput_pathrD   Úexpected_outputr"   s       €r#   Úconvert_with_libreofficeÚ;get_docx_to_pdf_converter.<locals>.convert_with_libreofficeª   sÓ   ø€ ô /Ô0°KÜ—’à'Ø#Ø$Ø&ØØ"ÜŸ™Ÿ™¨Ó4Ø"ð	ô &×-Ñ-Ü%×-Ñ-ØÜ1ò÷ 1ô$ !Ÿg™gŸl™lÜ—‘—‘ Ó,Ü—‘× Ñ ¤§¡×!1Ñ!1°*Ó!=Ó>¸qÑAÀFÑJóˆOð Ó-Ü—	’	˜/Õ7ð .÷- 1Õ0ús   ŒADÄ
DN)rC   ú
str | PathrO   rS   ÚreturnÚNone)r$   )rQ   r"   s    @r#   Úget_docx_to_pdf_converterrV   ž   s;   ø€ ô *Ó+€Oæð&	8Ø"ð&	8Ø1;ð&	8à÷&	8ðP (Ð'ð
 r%   c                ó¨  • Uc  U R                  S5      n[        R                  " U R                  U R                  U5      n[
        R                  " X5      nUR                  5       nU(       ad  Uu  pgp‰[        SXb-
  5      n[        SXr-
  5      n[        U R                  X‚-   5      n[        U R                  X’-   5      n	U R                  XgX‰45      $ U $ )N)r   r   r   )Úgetpixelr   ÚnewÚmodeÚsizer   Ú
differenceÚgetbboxÚmaxÚminÚwidthÚheightÚcrop)
ÚimageÚbg_colorÚpaddingÚbgÚdiffÚbboxÚleftÚupperÚrightÚlowers
             r#   Úcrop_whitespacerm   Ú   s±   € ØÑØ—>‘> &Ó)ˆä	�Š�5—:‘:˜uŸz™z¨8Ó	4€BÜ× Ò  Ó+€DØ�<‰<‹>€DæØ$(Ñ!ˆ�UÜ�1�d‘nÓ%ˆÜ�A�u‘Ó'ˆÜ�E—K‘K ¡Ó1ˆÜ�E—L‘L %¡/Ó2ˆØ�z‰z˜4¨Ð5Ó6Ð6àˆr%   c                óÒ  • Uc  g [        [        5       5      n [        US-  5      n[        US-  5      nU R                  [        U5      5        U" X45        [        R
                  " U5      nUS   n[        UR                  SS9R                  5       5      nUR                  5         UR                  5         [        R                  " USS9  U$ ! [        R                  " USS9  f = f)Nzdrawing_only.docxzdrawing_only.pdfr   é   )ÚscaleTr)   )r   r   Úsaver:   Ú	pypdfium2ÚPdfDocumentrm   ÚrenderÚto_pilÚcloser   r,   )ÚdocxÚ	converterÚtemp_dirÚ	temp_docxÚtemp_pdfrI   Úpagerc   s           r#   Úget_pil_from_dml_docxr}   í   sÉ   € ð ÑØä”G“I‹€Hð4Ü˜Ð$7Ñ7Ó8ˆ	Ü˜Ð#5Ñ5Ó6ˆð 	�	‰	”#�i“.Ô!ñ 	�)Ô&ô ×#Ò# HÓ-ˆØ�1‰vˆÜ §¡°! Ð 4× ;Ñ ;Ó =Ó>ˆØ�
‰
ŒØ�	‰	Œä�Š�h¨dÒ3à€Løô 	�Š�h¨dÓ3ús   ™BC ÃC&)F)r!   ÚboolrT   zOptional[str])rT   zIterator[str])éx   )
r>   zBytesIO | Pathr?   r:   r@   r:   rA   ÚintrT   r   )rT   úOptional[Callable])Nr   )rc   úImage.ImagerT   r‚   )rw   r   rx   r�   rT   zOptional[Image.Image])"Ú
__future__r   r   r   r   Úcollections.abcr   Ú
contextlibr   Úior   Úpathlibr   Útempfiler   Útypingr	   r
   r   r   rr   ÚPILr   r   Údocx.documentr   r   Ú__annotations__r$   r.   rF   rV   rm   r}   © r%   r#   Ú<module>rŽ      sÄ   ðö #ã 	Û Û Ý $Ý %Ý Ý Ý ß ;Ó ;ã ß !æÝ&à$&Ð �zÓ &ðöð> ó7ó ð7ð0 ð	I3ØðI3àðI3ð ðI3ð ð	I3ð
 õI3ôX9öxð&Ø
ðØ1ðàõr%   