ó
    ò¡Ëj™M  ã                   ó>  • S r SSKrSSKrSSKrSSK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  \R                  R                  S\" \" \5      R%                  5       R&                  5      5        SSKr SSKrSSKJrJr  SSKJr  Sr\" \5      R%                  5       R&                  r\R&                  S
-  S-  S-  r\R&                  S
-  S-  S-  r \S-  r!Sr"Sr#Sr$Sr%Sr&Sr'Sr(Sr)Sr*Sr+Sr,Sr-Sr.Sr/Sr0S	r1Su  r2r3r4 SSK5r5Sr6 SSK7J8r8  Sr9Sr:Sr;Sr<Sr=S r>S r?SSSSSSSS .r@S! rAS" rBS# rCS$ rDS% rES& rFS' rGS( rHS) rIS* rJS+ rKS, rLS- rMS. rNS/ rOS0 rPS1 rQS2 rRS3 rSS4 rTS5 rU\VS6:X  a  \U" 5         gg! \ a    S	r Nõf = f! \ a    S	r6 N‡f = f! \ a    S	r9 NŒf = f)7a}  
Search Pinterest (via pinch.py), download images, make clean transparent cutouts.

Pipeline per image:
  pinch download -> birefnet cutout -> (scene-fail? retry heavier model)
  -> defringe edges -> clean alpha -> trim margins -> resize for web -> save

Reuses the search/download functions from pinch.py (same folder).

Usage:
    pip install requests rembg pillow onnxruntime numpy scipy
    python scripts/fetch_qts.py            # fetch & append to the library
    python scripts/fetch_qts.py --recut    # re-clean images already in the folder

It asks:
    image to find:       (e.g. "hyuuga_hinata")
    how many to find:
    search hint:         (optional; blank = search exactly what you type)

Output: transparent PNGs with random names in  public/assets/qts/ .
New runs APPEND (never overwrite), skip duplicates, and it rewrites the
QTS array in public/assets/app.js automatically.
é    N)Úunescape)ÚPath)ÚBytesIO)ÚremoveÚnew_session)ÚImageTFÚpublicÚassetsÚqtszapp.jsz.hashes.txtiÐ  Úautozbirefnet-generalgš™™™™™©?gÍÌÌÌÌÌì?é   zrender transparent pngi°  )éð   é   é   )Úndimage)z.jpgz.jpegú.pngz.webpzhttps://safebooru.org/index.phpz&https://safebooru.org/autocomplete.phpéd   c           	      ó’  •  U R                  [        SU0[        R                  S9R	                  5       n/ nU Hx  nUR                  SS5      n[        R                  " SUR                  SS5      5      nU(       d  ME  UR                  XV(       a  [        UR                  S5      5      OS45        Mz     U$ ! [
         a    / s $ f = f)	zAAutocomplete real booru tags for `q` -> [(tag, post_count), ...].Úq©ÚparamsÚtimeoutÚvalueÚ z	\((\d+)\)Úlabelé   r   )ÚgetÚBOORU_ACÚpinchÚTIMEOUTÚjsonÚ	ExceptionÚreÚsearchÚappendÚintÚgroup)Úsessionr   ÚitemsÚoutÚitÚtagÚms          Ú.C:\Users\rot\Desktop\main\scripts\fetch_qts.pyÚbooru_suggestr/   ~   s«   € ðØ—‘œH¨c°1¨X¼u¿}¹}�ÐM×RÑRÓTˆð €CÛˆØ�f‰f�W˜bÓ!ˆÜ�IŠI�l B§F¡F¨7°BÓ$7Ó8ˆßˆ3Ø�J‰J˜µœS §¡¨£œ_°qÐ9Ö:ñ	 ð
 €Jøô ó ØŠ	ðús   ‚3B7 Â7CÃCc                 ód  • / SpC[        U5      U:  Ga   U R                  [        SSSSU[        US.[        R
                  S9R                  5       nU(       d   U$ U H¦  nUR                  S5      nU(       d6  UR                  S	5      b$  UR                  S
5      (       a  SUS	    SUS
    3nU(       d  MZ  UR                  5       R                  [        5      (       d  M„  UR                  U5        [        U5      U:¼  d  M¦    O   US-  n[        U5      U:  a  GM  U$ ! [         a     U$ f = f)z;Collect up to `count` image URLs for `tags` from Safebooru.r   ÚdapiÚpostÚindexÚ1)ÚpageÚsr   r!   ÚtagsÚlimitÚpidr   Úfile_urlÚ	directoryÚimagezhttps://safebooru.org/images/Ú/r   )Úlenr   Ú	BOORU_APIÚ	BOORU_PERr   r    r!   r"   ÚlowerÚendswithÚ
IMG_SUFFIXr%   )r(   r7   ÚcountÚurlsr9   ÚpostsÚpÚus           r.   Úbooru_searchrI   �   s*  € à�Aˆ#Ü
ˆd‹)�eÔ
ð	Ø—K‘K¤	Ø V°'À3Ø¤y¸ñ3ô —}‘}ð  ð &÷ '+¡d£fð ö Øð €Kó ˆAØ—‘�jÓ!ˆAÞ˜Ÿ™˜{Ó+Ñ7¸A¿E¹EÀ'¿N¹NØ3°A°k±NÐ3CÀ1ÀQÀwÁZÀLÐQ�ßˆq�Q—W‘W“Y×'Ñ'¬
×3Ó3Ø—‘˜A”Ü�t“9 Õ%Ùñ ð 	ˆq‰ˆô% ˆd‹)�eÖ
ð& €Køô ó 	Øð €Kð	ús   •=D! Ä!
D/Ä.D/z
1girl solo)ÚwaifuÚwaifusz
anime girlzanime girlsÚanimeÚgirlÚgirlsc           
      ó¢  ^• UR                  5       [        ;   a  [        UR                  5          $ [        XS5      (       a  U$ UR                  SS5      nX!:w  a  [        XS5      (       a  U$ [	        5       / pCU/UR                  5       -    HA  n[        X5       H/  u  pgXc;  d  M  UR                  U5        UR                  Xg45        M1     MC     UR                  5       R                  5        Vs/ s H  oˆ(       d  M  UPM     snmUR                  U4S jSS9  USS nU(       d  g[        S	U S
35        [        US5       H  u  n	u  pg[        SU	S SU SU S35        M      [        S5      R                  5       n
U
R                  5       (       a"  S[        U
5      s=::  a  [!        U5      ::  d   g  gU[        U
5      S-
     S   $ s  snf )zOMap whatever the user typed to a real booru tag (with a 'did you mean' picker).r   Ú Ú_c                 ó:   >^ • [        U 4S jT 5       5      T S   4$ )Nc              3   óX   >#   • U  H  oTS    R                  5       ;   d  M  Sv •  M!     g7f)r   r   N)rA   )Ú.0Úwr+   s     €r.   Ú	<genexpr>Ú2booru_resolve.<locals>.<lambda>.<locals>.<genexpr>¾   s"   øé € Ð"Jªe¨¸B¸q¹E¿K¹K»MÑ7I§1¡1ªeùs   ƒ*¡	*r   )Úsum)r+   Úwordss   `€r.   Ú<lambda>Úbooru_resolve.<locals>.<lambda>¾   s   ù€ œsÔ"J©eÓ"JÓJÈBÈqÉEÑRó    T)ÚkeyÚreverseNr   z
no exact booru tag for 'z'. did you mean:z  Ú2z. z  (Ú)z%pick a number (enter to skip booru): r   )rA   ÚBOORU_GENERICrI   ÚreplaceÚsetÚsplitr/   Úaddr%   ÚsortÚprintÚ	enumerateÚinputÚstripÚisdigitr&   r>   )r(   ÚrawÚjoinedÚseenÚcandsr   r,   ÚcrU   ÚiÚchoicerY   s              @r.   Úbooru_resolvers   ®   sœ  ø€ à
‡y�yƒ{”mÓ#Ü˜SŸY™Y›[Ñ)Ð)Ü�G !×$Ñ$Øˆ
Ø�[‰[˜˜cÓ"€FØƒ}œ g°q×9Ñ9ØˆÜ“%˜ˆ%ØˆX˜Ÿ	™	›Ô#ˆÜ# GÖ/‰FˆCØ�Ø—‘˜”Ø—‘˜c˜XÖ&ó 0ñ $ð
 Ÿ	™	›×)Ñ)Ô+Ó1Ò+�1«q�QÑ+Ñ1€EØ	‡J�JÔRÐ\`€JÑaØ�#�2ˆJ€EÞØÜ	Ð& s eÐ+;Ð
<Ô=Ü  ¨Ö*‰ˆ‰8ˆCÜ��1�Q�%�r˜#˜˜c !  AÐ&Ö'ñ +äÐ:Ó;×AÑAÓC€FØ�>‰>×Ñ A¬¨V«Õ$B¼¸E»
Ô$BØð %CØØ”�V“˜q‘Ñ! !Ñ$Ð$ùò 2s   Ã2
GÄ Gc                 ó‚  •  U R                  [        R                  X[        R                  S.[        R                  S9nUR
                  S:w  a  / $  / n[        R                  " SUR                  5       H¢  n [        R                  " [        U5      5      nUR                  S5      =(       d    SR                  S5      S   nUR                  S	5      (       d  Mg  UR                  5       R!                  ["        5      (       d  M‘  UR%                  U5        M¤     U$ ! [         a    / s $ f = f! [         a     MÇ  f = f)
uD   Bing image results for `query` â€” ANY image host (not just pinimg).)r   ÚfirstrD   r   éÈ   zm="(\{[^"]+\})"Úmurlr   Ú?r   Úhttp)r   r   ÚBING_IMAGESÚ	BING_PAGEr    Ústatus_coder"   r#   ÚfindallÚtextr!   Úloadsr   rd   Ú
startswithrA   rB   rC   r%   )r(   Úqueryru   Úrr*   rl   ÚitemrH   s           r.   Úbing_anyr„   Ë   s  € ð	Ø�K‰KÜ×ÑØ¼¿¹ÑIÜ—M‘Mð ð 
ˆð
 �=‰=˜CÓØˆIð  ð €CÜ�zŠzÐ,¨a¯f©fÖ5ˆð	Ü—:’:œh s›mÓ,ˆDð �X‰X�fÓ×# ×*Ñ*¨3Ó/°Ñ2ˆØ�<‰<˜×Ó A§G¡G£I×$6Ñ$6´z×$BÓ$BØ�J‰J�qŽMñ 6ð €Jøô ó ØŠ	ðûô ó 	Úð	ús$   ‚AD Á:D0ÄD-Ä,D-Ä0
D>Ä=D>c                 ó>  • [         S;   aQ  [        X5      nU(       a3  [        XU5      nU(       a   [        SU S[	        U5       S35        USU $ [         S:X  a  / $ / n [
        R                  " XUSS9n[	        U5      U:¼  a  USU $ [        S	5        [        U5      nS
u  pg[	        U5      U:  aÒ  US:  aÌ  [        XU5       Vs/ s H  oˆU;  d  M
  UPM     n	nU	(       a%  SnUR                  U	5        UR                  U	5        OUS-  n[        SU S[	        U5       SU 3[        R                  S9  U[
        R                  -  n[        R                   " [
        R"                  5        [	        U5      U:  a  US:  a  MÌ  USU $ ! [         a     GN!f = fs  snf )zMBooru first (reliable), then Pinterest native, then a permissive Bing search.)r   Úbooruz  booru tag 'u   ' â€” z
 result(s)Nr†   F)Úquietu:     (pinterest short/blocked â€” using general image search))r   r   é   r   r   z  [search] 'z' r=   )Úfile)ÚSOURCErs   rI   rg   r>   r   Úcollect_nativer"   rc   r„   ÚupdateÚextendÚsysÚstderrr{   ÚtimeÚsleepÚSLEEP)
r(   r�   rD   r,   rE   rn   ru   ÚstallrH   Úfreshs
             r.   Úcollect_imagesr•   ã   sŠ  € ô Ð"Ó"Ü˜GÓ+ˆÞÜ ¨eÓ4ˆDÞÜ˜ c U¨&´°T³°¸:ÐFÔGØ˜F˜U�|Ð#Ü�WÓØˆIð €DðÜ×#Ò# G°EÀÑGˆô ˆ4ƒy�EÓØ�F�Uˆ|Ðä	Ð
FÔGÜˆt‹9€Dà�L€EÜ
ˆd‹)�eÓ
 ¨£	Ü$ W°UÔ;ÓMÒ;�qÈ¹}—Ñ;ˆÐMÞØˆEØ�K‰K˜ÔØ�K‰K˜Õà�Q‰JˆEÜ�˜U˜G 2¤c¨$£i [°°%°Ð9ÄÇ
Á
ÒKØ”—‘Ñ ˆÜ�
Š
”5—;‘;Ôô ˆd‹)�eÓ
 ¨¥	ð ��ˆ<Ðøô) ó Úðüò Ns   ÁF	 Ã	FÃFÆ	
FÆFc                 ó¬   • [         R                  " U5       H(  n [         R                  " X5      nU(       d  M#  US   s  $    g! [         a    Sn N!f = f)z5Download one image, trying pinch's url size variants.Nr   )r   Úurl_variantsÚfetch_bytesr"   )r(   ÚurlÚvariantÚgots       r.   Úget_image_bytesrœ     sW   € ä×%Ò% cÖ*ˆð	Ü×#Ò# GÓ5ˆC÷ ˆ3Ø�q‘6ŠMñ +ð øô	 ó 	ØŠCð	ús   ›AÁAÁAc                 óz   • [         R                  " U 5      SS2SS2S4   n[        US:„  R                  5       5      $ )uQ   Fraction of pixels that are mostly opaque â€” a cheap 'did the cut work?' signal.Nr   é€   )ÚnpÚasarrayÚfloatÚmean)ÚimgÚas     r.   Úopaque_ratior¥     s0   € ä
�
Š
�3‹šš1˜a˜Ñ €AÜ�!�c‘'—‘Ó!Ó"Ð"r\   c                 ó¶  • U R                  5       n[        R                  " USS2SS24   U SS2SS24   5      USS2SS24'   [        R                  " USS2SS24   U SS2SS24   5      USS2SS24'   [        R                  " USS2SS24   U SS2SS24   5      USS2SS24'   [        R                  " USS2SS24   U SS2SS24   5      USS2SS24'   U$ )zGShrink the alpha mask by ~1px (4-neighbour min) to drop the fringe rim.r   Néÿÿÿÿ)ÚcopyrŸ   Úminimum)r¤   r*   s     r.   Úerode_alpharª     sÖ   € à
�&‰&‹(€CÜ—’˜C ¡¢A ™J¨¨#¨2¨#ªq¨&©	Ó2€Cˆ‰ŠAˆ�JÜ—*’*˜S  " ¢a ™[¨!¨A©B²¨E©(Ó3€CˆˆˆŠQˆ�KÜ—’˜C¢ 1¡2 ™J¨ª!¨S¨b¨S¨&©	Ó2€CŠˆ1‰2ˆ�JÜ—*’*˜S¢ C R C ™[¨!ªA¨q©r¨E©(Ó3€CŠˆ3ˆBˆ3ˆ�KØ€Jr\   c                 ó¬  • [         R                  " U 5      R                  [         R                  5      nUSS2SS2S4   n[        (       a  [        U5      n[        (       aS  [         R                  " US:  SU5      n[         R                  " US:„  SU5      R                  [         R                  5      nX!SS2SS2S4'   [        R                  " US5      $ )z?Defringe + clean the alpha channel for a crisp, halo-free edge.Nr   r   r   éó   éÿ   ÚRGBA)
rŸ   ÚarrayÚastypeÚuint8ÚDEFRINGErª   ÚCLEAN_ALPHAÚwherer   Ú	fromarray)r£   Úarrr¤   s      r.   Úrefiner·   '  s™   € ä
�(Š(�3‹-×
Ñ
œrŸx™xÓ
(€CØŠAŠq�!ˆG‰€Aß‚xÜ˜‹Nˆß‚{Ü�HŠH�Q˜‘V˜Q Ó"ˆÜ�HŠH�Q˜‘W˜c 1Ó%×,Ñ,¬R¯X©XÓ6ˆØŠŠ1ˆaˆ�LÜ�?Š?˜3 Ó'Ð'r\   c                 óâ  • [         (       a  [        (       d  U $ [        R                  " U 5      nUSS2SS2S4   nUS:„  n[        R
                  " U5      u  pEUS::  a  U $ [        R                  " UR                  5       5      nSUS'   UR                  5       n[        R                  " XG:H  US5      R                  [        R                  5      USS2SS2S4'   [        R                  " US5      $ )zGKeep only the biggest connected subject; drop smaller floating objects.Nr   é
   r   r   r®   )ÚKEEP_LARGESTÚ
HAVE_SCIPYrŸ   r¯   r   r   ÚbincountÚravelÚargmaxr´   r°   r±   r   rµ   )r£   r¶   r¤   ÚmaskÚlabelsÚnÚcountsÚkeeps           r.   Úkeep_largestrÄ   4  s·   € çŠLŸZšZØˆ
Ü
�(Š(�3‹-€CØŠAŠq�!ˆG‰€AØˆr‰6€DÜ—’˜dÓ#�I€FØˆAƒvØˆ
Ü�[Š[˜Ÿ™›Ó(€FØ€Fˆ1�IØ�=‰=‹?€DÜ—8’8˜F™N¨A¨qÓ1×8Ñ8¼¿¹ÓB€CŠŠ1ˆaˆ�LÜ�?Š?˜3 Ó'Ð'r\   c                 óV   • U R                  5       nU(       a  U R                  U5      $ U $ )z$Crop away fully transparent borders.)ÚgetbboxÚcrop)r£   Úbboxs     r.   ÚtrimrÉ   E  s"   € à�;‰;‹=€DÞ!ˆ3�8‰8�D‹>Ð* sÐ*r\   c                  óv   •  [         R                  " S5      S-   n [        U -  R                  5       (       d  U $ M9  )z*A unique random filename for a new cutout.é   r   )ÚsecretsÚ	token_hexÚOUT_DIRÚexists)Únames    r.   Úrandom_namerÑ   K  s7   € à
Ü× Ò  Ó# fÑ,ˆÜ˜$‘×&Ñ&×(Ñ(ØˆKñ r\   c                 óö   • [         (       d  U $ U R                  u  p[        X5      [         ::  a  U $ [         [        X5      -  nU R                  [	        X-  5      [	        X#-  5      4[
        R                  5      $ )z,Downscale so the longest side is <= MAX_DIM.)ÚMAX_DIMÚsizeÚmaxÚresizeÚroundr   ÚLANCZOS)r£   rU   ÚhÚscales       r.   ÚcaprÛ   S  s^   € çŠ7Øˆ
Ø�8‰8�D€AÜ
ˆ1ƒy”GÓØˆ
Ü”c˜!“iÑ€EØ�:‰:”u˜Q™YÓ'¬¨q©yÓ)9Ð:¼E¿M¹MÓJÐJr\   c                 ó2  • [        S[        =(       a    [        [        [        [
        S9n[        U 4SU0UD6n[        U5      nUbO  U[        :”  aE  [        U 4SU0UD6n[        U5      n[        Us=:  a  U:  a  O  XE4$ [        SUS SUS S35        XgpTXE4$ )zKCut the background, retrying with the heavier model if the first cut fails.T)Úpost_process_maskÚalpha_mattingÚ"alpha_matting_foreground_thresholdÚ"alpha_matting_background_thresholdÚalpha_matting_erode_sizer(   z    fallback kept ú.0%z (was r`   )ÚdictÚALPHA_MATTINGÚHAVE_PYMATTINGÚAM_FGÚAM_BGÚAM_ERODEr   r¥   ÚSCENE_FAIL_RATIOÚFALLBACK_MIN_KEEPrg   )r£   ÚprimaryÚfallbackÚkwargsÚcutr‚   ÚaltÚras           r.   Úcut_outrñ   ^  s¬   € äØÜ$×7¬Ü+0Ü+0Ü!)ñ€Fô �Ñ
0˜gÐ
0¨Ñ
0€CÜ�SÓ€AØÑ Ô$4Ó 4Ü�SÑ5 (Ð5¨fÑ5ˆÜ˜#Óˆä˜rÕ% AÕ%ð ˆ6€Mô Ð& r¨# h¨f°Q°s°G¸1Ð=Ô>Ø�Øˆ6€Mr\   c                  ó>   • [        [        R                  S5      S S9$ )z=All cutouts in the folder, oldest first (stable cycle order).z*.pngc                 ó6   • U R                  5       R                  $ )N)ÚstatÚst_mtime)rG   s    r.   rZ   Úlibrary_pngs.<locals>.<lambda>u  s   € °q·v±v³x×7HÒ7Hr\   )r]   )ÚsortedrÎ   Úglob© r\   r.   Úlibrary_pngsrú   s  s   € ä”'—,‘,˜wÓ'Ñ-HÑIÐIr\   c                  óŒ   •  [        [        R                  SS9R                  5       5      $ ! [         a    [        5       s $ f = f)Núutf-8©Úencoding)rc   ÚHASHES_FILEÚ	read_textrd   r"   rù   r\   r.   Úload_hashesr  x  s?   € ðÜ”;×(Ñ(°'Ð(Ð:×@Ñ@ÓBÓCÐCøÜó Ü‹uŠðús   ‚), ¬AÁAc                 óª   •  [         R                  SSS9 nUR                  U S-   5        S S S 5        g ! , (       d  f       g = f! [         a     g f = f)Nr¤   rü   rý   Ú
)rÿ   ÚopenÚwriter"   )rÙ   Úfhs     r.   Úremember_hashr    sI   € ðÜ×Ñ˜c¨GÐÑ4¸Ø�H‰H�Q˜‘XÔ÷ 5×4Ö4ûäó Ùðús*   ‚A –4«A ´
A¾A ÁA Á
AÁAc                  ó¢  • [        5        V s/ s H  o R                  PM     nn SR                  S U 5       5      nSU-   S-   n [        R	                  SS9n[
        R                  " SX4S[
        R                  S	9u  pVU(       a  [        R                  USS9  [        U5      $  gs  sn f ! [         a  n[        S
U 35         SnAgSnAff = f)zHRewrite the QTS = [...] array in app.js with EVERY cutout in the folder.r   c              3   ó.   #   • U  H  nS U S3v •  M     g7f)z  'assets/qts/z',
Nrù   )rT   rÁ   s     r.   rV   Úwrite_app_js.<locals>.<genexpr>Š  s   é € Ð;²U°�^ A 3 dÕ+²Uùs   ‚zconst QTS = [
z];rü   rý   zconst QTS = \[.*?\];r   )rD   Úflagsz)! could not update app.js automatically: N)rú   rÐ   ÚjoinÚAPP_JSr   r#   ÚsubnÚSÚ
write_textr>   r"   rg   )rG   ÚnamesÚbodyÚblockr~   ÚnewrD   Úes           r.   Úwrite_app_jsr  ‡  sÊ   € ä)œ^Ó,š^˜�VŒV™^€EÐ,Ø�7‰7Ñ;±UÓ;Ó;€DØ Ñ$ tÑ+€Eð?Ü×Ñ¨ÐÐ1ˆÜ—W’WÐ4°eÈÔRT×RVÑRVÑW‰
ˆÞÜ×Ñ˜c¨GÐÑ4Ü�u“:Ðð ð
 ùò -øô ó ?ÜÐ9¸!¸Ð=×>Ð>Øûð?ús   �B'ÁAB, Â,
CÂ6C	Ã	Cc                  óª   • [        [        5      n [        (       a  [        [        5      OSn[        S[         3U(       a
  S[         S3OS-   5        X4$ )z!Load the cutout model session(s).Nzcutout model: z (fallback: r`   r   )r   ÚMODELÚFALLBACK_MODELrg   )rë   rì   s     r.   Úmake_modelsr  —  sH   € äœ%Ó €Gß.<ªnŒ{œ>Ô*À$€HÜ	ˆNœ5˜'Ð
"Î(¨´^Ð4DÀAÑ&FÐXZÑ
[Ô\ØÐÐr\   c                 óV  • [         R                  " U5      R                  S5      n[        U5      [        :”  a)  [        X0U5      u  pE[        Us=::  a  [        ::  d   g  gUn[        U5      n[        U5      n[        (       a  [        U5      n[        U5      nUR                  U5        g)zMRe-clean one library image in place. Returns True if it's a clean cutout now.r®   FT)r   r  Úconvertr¥   ÚGOOD_MAXrñ   ÚGOOD_MINrÄ   r·   ÚTRIMrÉ   rÛ   Úsave)rë   rì   Úpathr£   rî   Úkepts         r.   Úclean_existingr#  Ÿ  s‹   € ä
�*Š*�TÓ
×
"Ñ
" 6Ó
*€CÜ�CÓœ8Ó#ä˜C¨(Ó3‰	ˆÜ˜DÕ,¤HÔ,Øð -ØØˆä
�sÓ
€CÜ
�‹+€Cß‚tÜ�3‹iˆÜ
ˆc‹(€CØ‡H�HˆT„NØr\   c            	      óð  • [        S5        [        (       d  [        R                  " S5        [	        5       n U (       d  [        R                  " S5        [        5       u  p[        5         / n[        U SS9 Hf  u  pE[        SU S[        U 5       SUR                   35         [        XU5      (       d(  UR                  UR                  5        [        S	5        Mf  Mh     [        5       n[        S[        U 5       S[        U 5      [        U5      -
   S35        U(       a  [        SSR                  U5      -   5        Ub  [        SU S35        gg! [         a  n[        S
U 35         SnAMú  SnAff = f)zMRe-run the cleanup pipeline over images already in the folder (no downloads).z*== qts recut (cleaning existing folder) ==z(rembg/numpy/Pillow required for --recut.z!No images in the folder to recut.r   ©ÚstartÚ[r=   z] u*       not cleanly transparent â€” left as-isz    ! failed: Nz
Recut done. z processed, z clean.z'Couldn't cut (still has a background): z, zapp.js updated with all z. Hard-refresh the page.)rg   Ú
HAVE_REMBGrŽ   Úexitrú   r  rh   r>   rÐ   r#  r%   r"   r  r  )Úpngsrë   rì   Úbadrq   rG   r  Útotals           r.   Ú	run_recutr-  ²  s;  € ä	Ð
6Ô7ßŠ:Ü�ŠÐ;Ô<Ü‹>€DÞÜ�ŠÐ4Ô5Ü#›Ñ€GÜ	„GØ
€CÜ˜$ aÔ(‰ˆÜ��!��A”c˜$“i�[  1§6¡6 (Ð+Ô,ð	(Ü! '°Q×7Ñ7Ø—
‘
˜1Ÿ6™6Ô"ÜÐBÖCñ 8ñ )ô ‹N€EÜ	ˆNœ3˜t›9˜+ \´#°d³)¼cÀ#»hÑ2FÐ1GÀwÐ
OÔPÞ
ÜÐ7¸$¿)¹)ÀC».ÑHÔIØÑÜÐ(¨¨Ð/GÐHÕIð øô ó 	(Ü�N 1 #Ð&×'Ò'ûð	(ús   Â#7EÅ
E5ÅE0Å0E5c                  óú  • [        S5        [        S5      R                  5       R                  S5      n U (       d  [        R
                  " S5         [        [        S5      R                  5       5      n[        S[        W[        5      5      n[        S[         S	35      R                  5       R                  S5      n[        R                  S
S
S9  [        R                  " 5       n UR!                  [        R"                  [        R$                  S9  U(       a  U  SU 3R                  5       OU n[(        (       d  UO [        [        [        U[*        -  S5      5      n[        SU S35        [-        X4U5      nU(       d  [        R
                  " S5        [        S[/        U5       S35        S =px[(        (       a  [1        5       u  px[        5         O[        S5        [        S5        [/        [3        5       5      n	U	S:X  a  [4        R7                  S
S9  [9        5       n
S=p¼[;        USS9 GH  u  pÞX±:¼  a    GOv[=        X>5      nU(       d  M"  [>        R@                  " U5      RC                  5       nUU
;   a  US-  nMS  [        SU SU SX›-    SU SU 3
5        [        [E        5       -  n [(        (       aÁ  [F        RH                  " [K        U5      5      RM                  S5      n[O        UXx5      u  nn[P        Us=::  a
  [R        ::  d&  O  U[R        :”  a  SOS n[        S!U S"US# S$35        GM  [U        U5      n[W        U5      n[X        (       a  [[        U5      n[]        U5      nUR_                  U5        OURa                  U5        U
Rc                  U5        [e        U5        US-  nGM‚     [g        5       n[        S&U S'U S([/        [3        5       5       S)[         35        X±:  a  [        S*U SU S+35        Ub  [        S,U S-35        g [        S.5        g ! [         a    [        R
                  " S5         GNÍf = f! [&         a     GN>f = f! [&         a  n[        S%U 35         S nAGMG  S nAff = f)/Nz== qts fetcher (pinterest) ==zimage to find: u   ï»¿zNo search entered.zhow many to find: zThat wasn't a number.r   z'search hint (optional, blank = exact) [z]: T©ÚparentsÚexist_ok)r   rP   i,  z
searching for 'z' ...zNo results found.zfound z candidate(s).
uC   ! rembg/numpy/Pillow not installed â€” saving WITHOUT transparency.z-  pip install rembg pillow onnxruntime numpy
r   )Ú
missing_okr%  r'  r=   z new | library z] (z) r®   zfailed to cutzover-cutz    skipped bad cutout (z, kept râ   r`   z    ! processing failed: z
Done. Added z new (z& duplicates skipped), library now has z in zOnly found ue    new â€” this search is mostly exhausted. Try a different or more specific query to get more variety.z"app.js QTS array updated with all z. Just hard-refresh the page.uO   
(couldn't auto-update app.js â€” the QTS array lists the folder's *.png files))4rg   ri   rj   ÚlstriprŽ   r)  r&   Ú
ValueErrorrÕ   ÚminÚ	MAX_COUNTÚHINT_SUGGESTIONrÎ   Úmkdirr   Úmake_sessionr   ÚHOME_URLr    r"   r(  Ú	OVERFETCHr•   r>   r  rú   rÿ   Úunlinkr  rh   rœ   ÚhashlibÚmd5Ú	hexdigestrÑ   r   r  r   r  rñ   r  r  rÄ   r·   r  rÉ   rÛ   r   Úwrite_bytesre   r  r  )r�   ÚwantÚhintr(   r$   Úwant_candidatesrE   rë   rì   Ústart_countrn   ÚaddedÚdupsrq   r™   rl   rÙ   r*   r£   rî   r"  Úreasonr  r,  s                           r.   Ú	run_fetchrH  Í  sñ  € Ü	Ð
)Ô*ÜÐ#Ó$×*Ñ*Ó,×3Ñ3°EÓ:€EÞÜ�ŠÐ%Ô&ð*Ü”5Ð-Ó.×4Ñ4Ó6Ó7ˆô ˆq”#�dœIÓ&Ó'€DäÐ:¼?Ð:KÈ3ÐOÓP×VÑVÓX×_Ñ_Ð`eÓf€Dä‡M�M˜$¨€MÑ.ô × Ò Ó"€GðØ�‰”E—N‘N¬E¯M©MˆÑ:ö +/�ˆw�a˜�vÐ×$Ñ$Ô&°E€F÷ #-¢*‘d´#´iÄÀTÌIÑEUÐWZÓA[Ó2\€OÜ	Ð˜f˜X UÐ
+Ô,Ü˜'¨?Ó;€DÞÜ�ŠÐ$Ô%Ü	ˆF”3�t“9�+Ð-Ð
.Ô/ð Ð€Gß‚zÜ'›MÑˆÜ�äÐSÔTÜÐ>Ô?ô ”l“nÓ%€KØ�aÓä×Ñ dÐÑ+Ü‹=€DØÐ€EÜ˜D¨Õ*‰ˆØ‹=ÚÜ˜gÓ+ˆÞÙÜ�KŠK˜Ó×&Ñ&Ó(ˆØ�‹9Ø�A‰IˆDÙÜ��%�˜˜$˜˜¨{Ñ/BÐ.CÀ3ÀqÀcÈÈCÈ5ÐQÔRÜœ›Ñ%ˆð	3ßŠzÜ—j’j¤¨£Ó.×6Ñ6°vÓ>�Ü# C¨Ó;‘	��TÜ  DÕ4¬HÕ4Ø04´x³™_ÀZ�FÜÐ4°V°H¸GÀDÈÀ:ÈQÐOÔPÚÜ" 3Ó'�Ü˜S“k�ß’4Ü˜s›)�CÜ˜#“h�Ø—‘˜•à—‘ Ô$Ø�H‰H�QŒKÜ˜!ÔØ�Q‰J‹Eñ= +ôD ‹N€EÜ	ˆN˜5˜' ¨ vð .Ü ¤£Ó0Ð1°´g°Yð@ô Aàƒ|Ü�˜E˜7 ! D 6ð *Lð Mô 	NàÑÜÐ2°5°'Ð9VÐWÕXäÐ`Õaøôk ó *Ü�ŠÐ(×)ð*ûô ó Úðûôz ó 	3ÜÐ-¨a¨SÐ1×2Ó2ûð	3úsD   Á"P Ã(,Q Ê/B QÌ2A;QÐ QÑQÑ
QÑQÑ
Q:Ñ Q5Ñ5Q:c                  óâ   • [         R                  " SS9n U R                  SSSS9  U R                  5       n[        R                  SSS9  UR                  (       a  [        5         g [        5         g )	Nzfetch/clean transparent qts)Údescriptionz--recutÚ
store_truez4re-clean images already in the folder (no downloads))ÚactionÚhelpTr/  )	ÚargparseÚArgumentParserÚadd_argumentÚ
parse_argsrÎ   r8  Úrecutr-  rH  )ÚapÚargss     r.   ÚmainrU  ,  sX   € Ü	×	 Ò	 Ð-JÑ	K€BØ‡O�O�I lØOð ñ Qà�=‰=‹?€DÜ‡M�M˜$¨€MÑ.Ø‡z‡zÜ�ä�r\   Ú__main__)WÚ__doc__rN  r=  r!   r#   rÌ   rŽ   r�   Úhtmlr   Úpathlibr   Úior   r!  ÚinsertÚstrÚ__file__ÚresolveÚparentr   ÚnumpyrŸ   Úrembgr   r   ÚPILr   r(  ÚImportErrorÚHERErÎ   r  rÿ   r6  rŠ   r  r  r  r;  r  ré   rê   r7  rº   r²   r³   r  rÓ   rä   ræ   rç   rè   Ú	pymattingrå   Úscipyr   r»   rC   r?   r   r@   r/   rI   ra   rs   r„   r•   rœ   r¥   rª   r·   rÄ   rÉ   rÑ   rÛ   rñ   rú   r  r  r  r  r#  r-  rH  rU  Ú__name__rù   r\   r.   Ú<module>rh     sJ  ðñó0 Û Û Û 	Û Û 
Û Ý Ý Ý ð ‡�‡��‘3‘t˜H“~×-Ñ-Ó/×6Ñ6Ó7Ô 8Û ðÛß)ÝØ€Jñ ˆHƒ~×ÑÓ×&Ñ&€Ø
�+‰+˜Ñ
  8Ñ
+¨eÑ
3€Ø	�‰�xÑ	 (Ñ	*¨XÑ	5€Ø˜Ñ%€Ø€	ð 
€ð 	€ð €Ø€à€	ð €ØÐ ØÐ ð +€ð €ð €Ø€Ø€Ø
€ð €Ø$Ñ €€uˆhðÛØ€NðÝØ€Jð 0€
ð .€	Ø3€Ø€	òòð6  \Ø¨|Ø <¸,ñ€ò%ò:ò0%òP	ò#òò
(ò(ò"+òòKòò*Jò
òòò òò&Jò6\bò~	ð ˆzÓÙ…Fð øðU ó Ø‚Jðûðx ó Ø‚Nðûð ó Ø‚Jðús6   Á6E5 Ä F ÄF Å5F Å?F ÆFÆFÆFÆF