
    +jlR                       d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlmZ ddlmZ ddlmZmZmZ ddlZddlZddlZddlmZmZmZmZ  ee                                          j        Z e dz  Z!e!d	z  Z"e d
z  dz  Z# ed          Z$ ed          Z% ej&        dd          Z' ej&        d          p1 ej&        d          p! ej&        d          p ej&        d          pdZ( ej&        dd          Z) ed           ed           ed          gZ*	 ddl+m,Z, n# e-$ r dZ,Y nw xY w ed           G d d                      Z.dnd!Z/dod%Z0dpd)Z1dqd*Z2drdsd2Z3dtd7Z4dudvd>Z5dwdxdBZ6dydzdEZ7d{d|dHZ8d}dJZ9dK Z:d~dMZ;ddOZ<ddQZ=dddSZ>dddWZ?dddXZ@	 	 ddd\ZAdd_ZBdd`ZCdddbZDdndcZEdddhZFddkZGddlZHddmZIdS )a  Core utilities for the Nano Banana 2 declination app.

Focus of this version:
- understand visible text in an image
- generate a clean plate from that understanding
- fall back to the local ComfyUI inpaint workflow if the Gemini image backend
  is unavailable
    )annotationsN)	dataclass)Path)AnyIterableSequence)Image	ImageDraw	ImageFontImageOpsoutputsruns	workflowszsdxl_inpaint.jsonzF/home/wildlama/.hermes/skills/creative/comfyui/scripts/run_workflow.pyz/home/wildlama/comfy/ComfyUINANO_BANANA_MODELzgemini-3.1-flash-imageNANO_BANANA_API_KEYGOOGLE_API_KEYGEMINI_API_KEYGOOGLE_GENAI_API_KEY NANO_BANANA_API_BASEz0https://generativelanguage.googleapis.com/v1beta//usr/share/fonts/truetype/dejavu/DejaVuSans.ttfz@/usr/share/fonts/truetype/liberation2/LiberationSans-Regular.ttfz//usr/share/fonts/truetype/freefont/FreeSans.ttf)genaiT)frozenc                      e Zd ZU ded<   ded<   ded<   ded<   dZded<   edd
            Zedd            Zedd            ZddZ	ddZ
dS )Boxintx1y1x2y2g        floatscorereturnc                <    t          d| j        | j        z
            S Nr   )maxr   r   selfs    
decline.pywidthz	Box.widthC       1dg'(((    c                <    t          d| j        | j        z
            S r%   )r&   r    r   r'   s    r)   heightz
Box.heightG   r+   r,   c                     | j         | j        z  S N)r*   r.   r'   s    r)   areazBox.areaK   s    zDK''r,   padlimit_wlimit_h'Box'c           
         t          t          d| j        |z
            t          d| j        |z
            t	          || j        |z             t	          || j        |z             | j                  S r%   )r   r&   r   r   minr   r    r"   )r(   r2   r3   r4   s       r)   paddedz
Box.paddedO   se    47S=!!47S=!!3''3''J
 
 	
r,   tuple[int, int, int, int]c                6    | j         | j        | j        | j        fS r0   )r   r   r   r    r'   s    r)   to_tuplezBox.to_tupleX   s    w$'11r,   N)r#   r   )r2   r   r3   r   r4   r   r#   r5   )r#   r9   )__name__
__module____qualname____annotations__r"   propertyr*   r.   r1   r8   r;    r,   r)   r   r   ;   s         GGGGGGGGGGGGE) ) ) X) ) ) ) X) ( ( ( X(
 
 
 
2 2 2 2 2 2r,   r   r#   Nonec                 v    t                               dd           t                              dd           d S NTparentsexist_ok)OUTPUT_ROOTmkdirRUN_ROOTrA   r,   r)   ensure_dirsrK   a   s7    dT222NN4$N/////r,   
image_path
str | PathImage.Imagec                P    t          j        |                               d          S NRGB)r	   openconvert)rL   s    r)   
load_imagerT   g   s     :j!!))%000r,   imagepathr   c                    t          |          }|j                            dd           |                     |           |S rD   )r   parentrI   save)rU   rV   s     r)   
save_imagerZ   l   s?    ::DKdT222	JJtKr,   c                 d    t           D ]} |                                 r| c S t          d          S )Nr   )DEFAULT_FONT_CANDIDATESexistsr   )	candidates    r)   
_font_pathr_   t   sE    ,  	 		ABBBr,      ra   imagesSequence[Image.Image]titlesSequence[str]
thumb_sizetuple[int, int]c                   | st          j        d|d          S g }| D ]}t          j        |                    d          |          }t          j        d|d          }|d         |j        z
  dz  }|d         |j        z
  dz  }|                    |||f           |                    |           t          |          dk    rdnd}	t          j        t          |          |	z            }
t          j        d|	|d         z  |
|d         dz   z  fd          }t          j        |          }t          j        t!          t#                                d	          }t%          t'          ||                    D ]g\  }\  }}||	z  }||	z  }||d         z  }||d         dz   z  }|                    |||d
z   f           |                    |dz   |dz   f|d|           h|S )NrQ   whitez#111111r         (   z#0d0d0d            )fillfont)r	   newr   containrS   r*   r.   pasteappendlenmathceilr
   Drawr   truetypestrr_   	enumerateziptext)rb   rd   rf   thumbsimgthumbcanvasxycolsrowssheetdrawrr   ititlercs                     r)   make_contact_sheetr   |   s    5y
G444F   U!3!3Z@@5*i88]U[(Q.]U\)a/UQF###fFa11QD9S[[4'((DIedZ]2DJqMB<N4OPR[\\E>%  Dc*,,//44D$S%8%899 C C<CIH
1A#$C!QV%%%		1r61q5/5wT	BBBBLr,   pathsSequence[str | Path]bundle_namer|   c                2   t                       t          |z  }t          j        |dt          j                  5 }| D ]A}t          |          }|                                r|                    ||j                   B	 d d d            n# 1 swxY w Y   |S )Nw)compression)arcname)	rK   rH   zipfileZipFileZIP_DEFLATEDr   r]   writename)r   r   bundle_pathzfrV   ps         r)   bundle_outputsr      s    MMM+K	cw7K	L	L	L ,PR 	, 	,DT

Axxzz ,AF+++	,, , , , , , , , , , , , , , ,
 s   ABBB   boxesSequence[Box]gapr   	list[Box]c                d   | sg S t          | d           }g }|D ]}|s|                    |           |d         }|j        |j        |z   k    r|j        |j        |z
  k    r|j        |j        |z   k    r|j        |j        |z
  k    rt          t          |j        |j                  t          |j        |j                  t          |j        |j                  t          |j        |j                  t          |j	        |j	                            |d<   |                    |           |S )Nc                    | j         | j        fS r0   )r   r   bs    r)   <lambda>z$_merge_overlapping.<locals>.<lambda>   s    14, r,   )key)
sortedrv   r   r   r   r    r   r7   r&   r"   )r   r   orderedmergedboxcurs         r)   _merge_overlappingr      s1    	U 6 6777GF   	MM#RjFcfsl""#&3,&&#&3,&&#&3,&&CFCF##CFCF##CFCF##CFCF##CIsy)) F2JJ MM#Mr,   ~jtX?min_area_ratior!   c                   t          j        |           }t          j        |t          j                  j        \  dfd}dfd}t          j        t          j        d          }t          j        t          j	        |          }t          j        t          j
        |          }t          j        |t          j        dd	          }t          j        |          }d
||                                dz   z  z                      d          }t          j        |t          j        dd	          }	t          j        |	          }	d
|	|	                                dz   z  z                      d          }	 ||           ||	          z    |          z   }
|
                    d d           t#          |
          }fd|D             }|d d         S )Nsrc
np.ndarrayr#   r   c           
        t          j        | dd          }t          j        |ddt           j        t           j        z            \  }}t          j        t           j        d          }t          j        |t           j        |d          }t          j	        |d d          }t          j
        |t           j        t           j                  \  }}g }t          z  z            }|D ]}	t          j        |	          \  }
}}}||z  }||k     r(|t          d|          z  }|dk     rB|d	k     s|d
k     rOt          d|          t!          ||z             t          d|
          t!          |
|z             f         }t#          |                                          dz  }t!          d|t#          z            z  dz  |z             }|                    t)          |
||
|z   ||z   |                     |S )N)   r   r      )      rj   
iterationsrk         ?   r        o@g      (@)cv2GaussianBlur	thresholdTHRESH_BINARYTHRESH_OTSUgetStructuringElement
MORPH_RECTmorphologyExMORPH_CLOSEdilatefindContoursRETR_EXTERNALCHAIN_APPROX_SIMPLEr   boundingRectr&   r7   r!   stdrv   r   )r   blur_threshmorph_kernelclosedcontoursfoundmin_areacntr   r   bwbhr1   aspectlocalcontrastr"   grayhr   r   s                      r)   _find_from_mapz+detect_text_regions.<locals>._find_from_map   s   VQ//M$30ACO0STT	60II!&#/<TUVVVFDQ777&vs/@#BYZZ!q1u~-.. 	; 	;C+C00LAq"b7Dh#a**_F||Bww"q&&Q3q!b&>>13q!99SAF^^3KKLEUYY[[))E1HdU1q5\\1T9HDEEELLQ1r61r6599::::r,   c           
        t          j        | dd          }t          j        t           j        d          }t          j        |t           j        |d          }t          j        |d d          }t          j        |t           j        t           j	                  \  }}g }t          z  dz  z            }|D ]}t          j        |          \  }	}
}}||z  }||k     r(|t          d|          z  }|dk     rB|d	k     s|d
k     rOt          d|
          t          |
|z             t          d|	          t          |	|z             f         }t          |                                          dz  }t          d|t          z            z  dz  |z             }|                    t#          |	|
|	|z   |
|z   |                     |S )N2      )      rj   r   rk   gffffff?r      r   r   r   g      $@)r   Cannyr   r   r   r   r   r   r   r   r   r   r&   r7   r!   r   rv   r   )r   edgesr   r   r   r   r   r   r   r   r   r   r   r1   r   r   r   r"   r   r   r   r   s                     r)   _find_from_edgesz-detect_text_regions.<locals>._find_from_edges   s   	#r3''0II!%,STUUUFDQ777&vs/@#BYZZ!q1u 5677 	; 	;C+C00LAq"b7Dh#a**_F||Bww"q&&Q3q!b&>>13q!99SAF^^3KKLEUYY[[))E1HdU1q5\\1T9HDEEELLQ1r61r6599::::r,   )   r   rk   r   r   gư>uint8c                    | j         S r0   )r"   r   s    r)   r   z%detect_text_regions.<locals>.<lambda>
  s    !' r,   Tr   reversec                >    g | ]}|                     d           S )ro   )r8   ).0r   r   r   s     r)   
<listcomp>z'detect_text_regions.<locals>.<listcomp>  s)    ///AQXXb!Q///r,   
   )r   r   r#   r   )nparrayr   cvtColorCOLOR_RGB2GRAYshaper   r   r   MORPH_BLACKHATMORPH_TOPHATScharrCV_32Fabsoluter&   astypesortr   )rU   r   arrr   r   blackhat_kernelblackhattophat
grad_black
grad_white
candidatesr   r   r   r   s    `          @@@r)   detect_text_regionsr     s   
(5//C<S/00D:DAq        2        0 /HHOc&8/JJHdC$4oFFFHcj!Q77JZ((Jz~~'7'7$'>?@HHQQJFCJ155JZ((Jz~~'7'7$'>?@HHQQJ
++nnZ.H.HHK[K[\`KaKaaJOO))4O888z**E////////E":r,   r   r2   c                   | j         \  }}t          j        d||fd          }t          j        |          }|D ]H}|                    |||          }|                    |j        |j        |j	        |j
        gd           I|S )NLr   r   rq   )sizer	   rs   r
   rz   r8   	rectangler   r   r   r    )	rU   r   r2   r   r   maskr   r   r   s	            r)   boxes_to_maskr    s    :DAq9S1a&!$$D>$D ; ;JJsAq!!adAD!$/c::::Kr,   #ff3366colorc                v   |                                                      d          }t          j        |          }t	          |d          D ]l\  }}|                    |j        |j        |j        |j	        g|d           |
                    |j        dz   |j        dz   ft          |          |           m|S )NrQ   rk   rp   )outliner*   r  )copyrS   r
   rz   r}   r
  r   r   r   r    r   r|   )rU   r   r  outr   idxr   s          r)   draw_boxes_previewr    s    
**,,

u
%
%C>#DeQ'' B BS7aPPP		36A:svz*CHH5	AAAAJr,   tuple[bool, str]c                 @    t           dS t          sdS ddt           dfS )N)Fu    google-genai n'est pas installé)Fu   clé API manquanteTzok ())r   DEFAULT_API_KEYDEFAULT_MODELrA   r,   r)   nano_banana_readyr  *  s2    }88 +**((((((r,   c                     t           t          d          t          st          d          t          j        t                    S )Nu+   Le package google-genai n'est pas installéz,NANO_BANANA_API_KEY ou GOOGLE_API_KEY manque)api_key)r   RuntimeErrorr  ClientrA   r,   r)   _clientr  3  sA    }HIII KIJJJ<0000r,   dict[str, str]c                    t          j                    }|                     |d           |                    d           t	          j        |                                                              d          }d|ddS )NPNG)formatr   utf-8rU   z	image/png)typedata	mime_type)tempfileSpooledTemporaryFilerY   seekbase64	b64encodereaddecode)rU   bufr&  s      r)   _image_partr0  <  sk    

'
)
)C	JJs5J!!!HHQKKKCHHJJ''..w77DTDDDr,   r   c                    d| dS )Nr   )r%  r   rA   )r   s    r)   
_text_partr2  E  s    D)))r,   r   c                   |                                  } 	 t          j        |           S # t          $ rM t	          j        d| t          j                  }|r)t          j        |                    d                    cY S  w xY w)Nz\{.*\}r   )stripjsonloads	ExceptionresearchSgroup)r   matchs     r)   _extract_jsonr=  J  s    ::<<Dz$   	)T2400 	.:ekk!nn-----	s   * AB?Buser_requestc                F    |                                  } | rd|  nd}d| S )Nz
Context utilisateur: r   uw  Analyse l'image pour comprendre tout le texte visible et la structure éditoriale. Réponds uniquement en JSON strict, sans markdown, avec les clés suivantes: language, visible_text, blocks, reading_order, clean_plate_notes, recommended_clean_prompt, confidence. blocks doit être un tableau d'objets avec: text, role, position_hint, confidence. position_hint doit être une description courte, par exemple top-left, center, banner, footer. Si un texte est incertain, mets-le dans visible_text avec un préfixe [uncertain]. N'invente pas de texte. clean_plate_notes doit expliquer quoi préserver pour faire un clean plate propre.)r4  )r>  	user_notes     r)   build_analysis_promptrA  V  sD    %%''L<HP8,888bI	 	 	
r,   analysisdict[str, Any]extra_instructionc                x    t          j        | dd          }|                                }|rd| nd}d| | S )NFrj   ensure_asciiindentz
Consigne additionnelle: r   u  Tu reçois une image avec du texte à retirer. Crée un clean plate propre. Supprime tous les textes, lettres, logos typographiques, chiffres et artefacts de composition liés au texte. Préserve la composition, l'éclairage, les ombres, la perspective, les textures, les contours des objets et le fond. Ne rajoute aucun texte. Si une zone doit être reconstruite, invente un arrière-plan plausible et neutre. Utilise ce résumé d'analyse comme vérité de référence pour comprendre ce qu'il faut enlever: )r5  dumpsr4  )rB  rD  text_summaryextras       r)   build_clean_promptrL  g  sg    :hU1EEEL)//11@QY<):<<<WYE	!
 	!
 	! 	!r,   c                d   t                      \  }}t          |           }d|dg d |D             g dgdd |D             d d
}|s|S t                      }t          |          }|j                            t          t          |          t          |           g          }t          |d	d
          pd
}		 t          |	          }
t          |
t                    st          d          n## t          $ r d|d<   d|d<   |	pd |d<   |cY S w xY w|
                    dd           |
                    dg            |
                    dg            |
                    dg            |
                    dg            |
                    dd           d|
d<   d|
d<   d |D             |
d<   |	pd |
d<   |
S )Nzlocal-heuristicunknownc                    g | ];}d d|j          d|j         d|j         d|j         t	          |j        d          d<S )r   
text_block,r   )r   roleposition_hint
confidence)r   r   r   r    roundr"   r   r   s     r)   r   z,analyze_with_nano_banana.<locals>.<listcomp>~  so     
 
 
  $$%D!?!?14!?!?!$!?!?!?!?#AGQ//	 
 
 
r,   zNFallback local heuristics used because the Nano Banana backend is unavailable.HRemove all visible text while preserving the background and composition.c                6    g | ]}|                                 S rA   r;   rV  s     r)   r   z,analyze_with_nano_banana.<locals>.<listcomp>  s     @@@A1::<<@@@r,   )
backendstatuslanguagevisible_textblocksreading_orderclean_plate_notesrecommended_clean_promptdetected_boxesraw_model_outputmodelinputoutput_textr   u#   La réponse n'est pas un objet JSONznano-banana-2rZ  u?   Réponse modèle non JSON, fallback local des zones détectéesr[  rc  r\  r]  r^  r_  r`  ra  okc                6    g | ]}|                                 S rA   rY  rV  s     r)   r   z,analyze_with_nano_banana.<locals>.<listcomp>  s     CCCqajjllCCCr,   rb  )r  r  r  rA  interactionscreater  r2  r0  getattrr=  
isinstancedict
ValueErrorr7  
setdefault)rU   r>  readyreasonfallback_boxesfallbackclientpromptinteractionraw_textr&  s              r)   analyze_with_nano_bananary  v  s-   %''ME6(//N$
 
 $
 
 
 no$n@@@@@ % H*  YYF"<00F%,,v
 -  K {M266<"HX&&$%% 	DBCCC	D   -^'/'74#$	 	OOJ	***OONB'''OOHb!!!OOOR(((OO',,,OO.0z{{{%DODNCCNCCCD	'/4D	Ks   53C) )D	D	seed
int | Nonetuple[Image.Image, str]c                   t                      \  }}|st          | |          d| fS t                      }t          ||          }||d| z  }|j                            t          t          |          t          |           g          }t          |dd           }	|	t          |	dd           st          d          t          j        |	j                  }
t          |
          dfS )	Nu   Fallback local activé: )rD  u   
Seed de référence: rd  output_imager&  u.   Nano Banana n'a pas renvoyé d'image de sortierh  )r  _fallback_clean_plater  rL  rj  rk  r  r2  r0  rl  r  r+  	b64decoder&  _image_from_bytes)rU   rB  rD  rz  rq  rr  ru  rv  rw  outputr&  s              r)   %generate_clean_plate_with_nano_bananar    s    &''ME6 [$UH557ZRX7Z7ZZZYYF<MNNNF2D222%,,v
 -  K [.$77F~WVVT::~KLLLFK((DT""D((r,   r&  bytesc                   t          j        dd          5 }|                    |            t          |j                  }d d d            n# 1 swxY w Y   	 t          j        |                              d          	 |                    d           S # t          $ r Y S w xY w# 	 |                    d           w # t          $ r Y w w xY wxY w)Nz.pngF)suffixdeleterQ   T)
missing_ok)
r(  NamedTemporaryFiler   r   r   r	   rR   rS   unlinkr7  )r&  tmptmp_paths      r)   r  r    s"   		$F5	A	A	A "S		$>>" " " " " " " " " " " " " " "z(##++E22	OOtO,,,, 	 	 	D		OOtO,,,, 	 	 	D	sS   *AAA&B'  B
B$#B$'C)C ?C 
C
CCCc                   d |                     dg           D             }|st          |           }|s'|                                                     d          S t                                          s'|                                                     d          S t                                          s'|                                                     d          S t                       t          | |          }t          j
                    5 }t          |          }|dz  }|dz  }|                     |           |                    |           t          |                     dd                    }t          t          |          t          |          |          }	t          j        |	                              d          cd d d            S # 1 swxY w Y   d S )Nc                F    g | ]}t          |          d k    t          | S rp   rw   r   r   coordss     r)   r   z)_fallback_clean_plate.<locals>.<listcomp>  .    ___fcRXkk]^N^N^S&\N^N^N^r,   rb  rQ   z	input.pngzmask.pngra  rW  )getr  r  rS   COMFY_SCRIPTr]   COMFY_WORKFLOWensure_comfy_runningr  r(  TemporaryDirectoryr   rY   r|   run_comfy_inpaintr	   rR   )
rU   rB  r   r  r  tmpdir
input_path	mask_pathrv  
clean_paths
             r)   r  r    s   __5Er(J(J___E +#E** +zz||##E***   +zz||##E***  "" +zz||##E***&&D		$	&	& 5#ck)
Z'	

:		)X\\"<  ?I  J  J  K  K&s:IOO
z*%%--e445 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5s   B8GGG'tuple[dict[str, Any], Image.Image, str]c                    t          | |          }	 t          | |||          }t          |t                    r|\  }}n|}d}n,# t          $ r}t          | |          }d| }Y d }~nd }~ww xY w||d<   |||fS )N)r>  )rD  rz  rh  zFallback clean plate: clean_status)ry  r  rm  tupler7  r  )	rU   r>  rD  rz  rB  clean	clean_imgr  excs	            r)   run_nano_banana_cleanr    s    'LIIIH	65eXYjquvvveU## 	 &+#I||IL 6 6 6)%::	5556  ,H^Y,,s   2A 
A/A**A/c                    	 t          j        dd          } | j        rd S n# t          $ r Y nw xY wt	          j        d          }|st          d          t          j        |dt          t                    ddgd	
           t          d          D ]3}	 t          j        dd          } | j        r d S $# t          $ r Y 0w xY wt          d          )Nz"http://127.0.0.1:8188/system_statsr   )timeoutcomfyz"comfy-cli is not available on PATHz--workspacelaunchz--backgroundTcheck<   z.ComfyUI did not become ready on 127.0.0.1:8188)requestsr  rh  r7  shutilwhichr  
subprocessrunr|   COMFY_WORKSPACErange)r   r  r   s      r)   r  r    s   L=qIII4 	F	   L!!E A?@@@NE=#o*>*>.Yaeffff2YY  	A1MMMAt  	 	 	D	
G
H
HHs   " 
//B77
CC*   r  rv  negative_promptc                   t                       t                       t                                          st	          dt                     t
                                          st	          dt
                     t          j        d          pdt          t                    dt          t
                    dd|  dd| dt          j
        ||d	|d
          dt          t                    ddg}t          j        |d           t          t                              d          d d          }|st!          d          |d         S )NzMissing Comfy workflow runner: zMissing workflow: python3z
--workflowz--input-imagezimage=zmask_image=z--args   )rv  r  stepsrz  z--output-dirz	--timeout900Tr  z*.pngc                4    |                                  j        S r0   )statst_mtime)r   s    r)   r   z#run_comfy_inpaint.<locals>.<lambda>C  s    16688;L r,   r   z1ComfyUI run completed but no PNG output was foundr   )rK   r  r  r]   FileNotFoundErrorr  r  r  r|   r5  rI  rJ   r  r  r   globr  )rL   r  rv  r  rz  cmdr   s          r)   r  r  $  sW   MMM   R P, P PQQQ  "" G E^ E EFFFY,9LN!i!!
 #2	 	
 	
 	H+C. N3d####X]]7++1L1LVZ[[[G PNOOO1:r,   valueImage.Image | Nonec                    | d S t          | t          j                  r|                     d          S 	 t          |           S # t          $ r Y d S w xY wrP   )rm  r	   rS   rT   r7  )r  s    r)   image_from_uploadr  N  sg    }t%%% $}}U###%      tts   A 
AAc                    t          |           } | j                            dd           |                     t	          j        |dd          d           | S )NTrE   Frj   rF  r$  )encoding)r   rX   rI   
write_textr5  rI  )rV   r&  s     r)   
write_jsonr  Z  sT    ::DKdT222OODJt%BBBWOUUUKr,   c                b    d |                     dg           D             }t          | |          S )Nc                F    g | ]}t          |          d k    t          | S r  r  r  s     r)   r   zto_overlay.<locals>.<listcomp>c  r  r,   rb  )r  r  )rU   rB  r   s      r)   
to_overlayr  b  s4    __5Er(J(J___EeU+++r,   )r#   rB   )rL   rM   r#   rN   )rU   rN   rV   rM   r#   r   )r#   r   )r`   )rb   rc   rd   re   rf   rg   r#   rN   )r   r   r   r|   r#   r   )r   )r   r   r   r   r#   r   )r   )rU   rN   r   r!   r#   r   )r   )rU   rN   r   r   r2   r   r#   rN   )r  )rU   rN   r   r   r  r|   r#   rN   )r#   r  )rU   rN   r#   r   )r   r|   r#   r   )r   r|   r#   r   )r   )r>  r|   r#   r|   )rB  rC  rD  r|   r#   r|   )rU   rN   r>  r|   r#   rC  )r   N)
rU   rN   rB  rC  rD  r|   rz  r{  r#   r|  )r&  r  r#   rN   )rU   rN   rB  rC  r#   rN   )r   r   N)
rU   rN   r>  r|   rD  r|   rz  r{  r#   r  )r   r  )rL   r|   r  r|   rv  r|   r  r|   rz  r   r#   r   )r  r   r#   r  )rV   rM   r&  r   r#   r   )J__doc__
__future__r   r+  r5  rx   osr8  r  r  r(  r   dataclassesr   pathlibr   typingr   r   r   r   numpyr   r  PILr	   r
   r   r   __file__resolverX   ROOTrH   rJ   r  r  r  getenvr  r  DEFAULT_API_BASEr\   googler   r7  r   rK   rT   rZ   r_   r   r   r   r  r  r  r  r  r0  r2  r=  rA  rL  ry  r  r  r  r  r  r  r  r  r  rA   r,   r)   <module>r     s    # " " " " "    				 				        ! ! ! ! ! !       * * * * * * * * * * 



      5 5 5 5 5 5 5 5 5 5 5 5tH~~&Y#&99t\]]$566	-/GHHBI#$$ 
ry!""
ry!""
 ry'((
 
  2935ghh  	D	:;;D	KLLD	:;;    EEE $2 2 2 2 2 2 2 2J0 0 0 01 1 1 1
   C C C C    <        :F F F F FT        ) ) ) )1 1 1E E E E* * * *
       "    9 9 9 9 9@  	) ) ) ) )<
 
 
 
5 5 5 54- - - - -*I I I I," " " " "T      , , , , , ,s   *D1 1D;:D;