Ë
    ”óãjb>  ã                   ó�  — d 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 ej                  j                  dd¬«        ee«      j#                  «       j$                  j$                  Z ej(                  e«      Zej.                  j1                  d	«      r eej.                  d	   «      ned
z  dz  at2        dz  at2        dz  at2        dz  adZ ej<                  d«      Z ej<                  d«      Z d0d„Z!dede"e#   fd„Z$dede"e#   ddfd„Z%de"e#   fd„Z&de"e#   ddfd„Z'de#e(e#f   fd„Z)de#ddfd„Z*de(de(fd„Z+de(de,e(d f   fd!„Z-de(fd"„Z.	 d1de(fd#„Z/d2de0fd$„Z1de#fd%„Z2de0fd&„Z3d3de#fd'„Z4e
d(„ «       Z5de#fd)„Z6d2de#fd*„Z7d4de"e#   fd+„Z8d2de#fd,„Z9d2de"e(   fd-„Z:d.„ Z;ed/k(  r e;«        yy)5a6  
pose_bank: banco de poses validadas (JSONL) + CLI. Es la base compartida del
pipeline de contenido (pack_builder lo consume, la auditoria lo promociona y
penaliza).

Ruta por defecto: Archivos/pose_bank/
    pose_bank.jsonl -> una pose validada por linea
    avoid.jsonl     -> poses/bloques fallidos (con blacklist automatica)
    refs/<id>.png   -> render de referencia aprobado

Se puede apuntar a otro directorio con la variable de entorno PLUMLOOM_BANK_DIR
(lo usan las verificaciones para no tocar el banco real).

    python Engine/pose_bank.py --stats
    python Engine/pose_bank.py --list
    python Engine/pose_bank.py --check
    python Engine/pose_bank.py --avoid KEY --motivo M [--threshold N]
    python Engine/pose_bank.py --unblacklist KEY
    python Engine/pose_bank.py --promote RUN_DIR --verdicts PATH
é    N)Úcontextmanager)Údatetime)ÚPathúutf-8Úbackslashreplace)ÚencodingÚerrorsÚPLUMLOOM_BANK_DIRÚArchivosÚ	pose_bankúpose_bank.jsonlúavoid.jsonlÚrefs)Ú	sugerenteÚspicyÚ	explicitoz!\(\s*([^():]*?)\s*:\s*[\d.]+\s*\)z	^pb(\d+)$Úreturnc                  ó`   — t         j                  dd¬«       t        j                  dd¬«       y )NT)ÚparentsÚexist_ok)ÚBANK_DIRÚmkdirÚREFS_DIR© ó    úEngine/pose_bank.pyÚensure_dirsr   3   s"   € Ü‡N�N˜4¨$€NÔ/Ü‡N�N˜4¨$€NÕ/r   Úpathc           	      óš  — | j                  «       sg S g }| j                  dd¬«      5 }t        |d«      D ];  \  }}|j                  «       sŒ	 |j	                  t        j                  |«      «       Œ= 	 d d d «       |S # t
        j                  $ r,}t        j                  d| j                  ||«       Y d }~Œƒd }~ww xY w# 1 sw Y   |S xY w)NÚrr   ©r   é   z"%s:%d linea corrupta, saltada (%s))ÚexistsÚopenÚ	enumerateÚstripÚappendÚjsonÚloadsÚJSONDecodeErrorÚloggerÚwarningÚname)r   ÚoutÚfÚlinenoÚlineÚes         r   Ú_read_jsonlr3   8   s±   € Ø�;‰;Œ=Øˆ	Ø
€CØ	�‰�3 ˆÔ	)¨QÜ% a¨žO‰LˆF�DØ—:‘:”<Øð[Ø—
‘
œ4Ÿ:™: dÓ+Õ,ñ	 ,÷ 
*ð €Jøô ×'Ñ'ò [Ü—‘ÐCÀTÇYÁYÐPVÐXY×ZÑZûð[ú÷ 
*ð €Jús5   ¨$C Á$A>Á1C Á>B=Â"B8Â3C Â8B=Â=C Ã C
Úrowsc                 óÌ   — t        «        | j                  ddd¬«      5 }|D ]+  }|j                  t        j                  |d¬«      dz   «       Œ- 	 d d d «       y # 1 sw Y   y xY w)NÚwr   Ú
)r   ÚnewlineF©Úensure_ascii)r   r$   Úwriter(   Údumps)r   r4   r/   Úrows       r   Ú_write_jsonlr>   G   sM   € Ü„MØ	�‰�3 °$ˆÔ	7¸1ÛˆCØ�G‰G”D—J‘J˜s°Ô7¸$Ñ>Õ?ñ ÷ 
8×	7Ñ	7ús   Ÿ1AÁA#c                  ó    — t        t        «      S ©N)r3   Ú	BANK_FILEr   r   r   Ú	load_bankrB   N   s   € Ü”yÓ!Ð!r   Úentriesc                 ó$   — t        t        | «       y r@   )r>   rA   )rC   s    r   Ú	save_bankrE   R   s   € Ü”˜GÕ$r   c                  ód   — i } t        t        «      D ]  }|j                  d«      }|sŒ|| |<   Œ | S )NÚkey)r3   Ú
AVOID_FILEÚget)Úavoidr=   rG   s      r   Ú
load_avoidrK   V   s6   € Ø€EÜœ:Ö&ˆØ�g‰g�e‹nˆÚØˆE�#ŠJð 'ð €Lr   Údc                 óR   — t        t        t        | j                  «       «      «       y r@   )r>   rH   ÚlistÚvalues)rL   s    r   Ú
save_avoidrP   _   s   € Ü”œT !§(¡(£*Ó-Õ.r   Ú	pose_linec                 óÄ   — | xs dj                  «       }t        j                  d|«      }|j                  dd«      }t	        j                  dd|«      j                  «       S )NÚ z\1Ú_Ú z\s+)ÚlowerÚ
_WEIGHT_REÚsubÚreplaceÚrer&   )rQ   Úss     r   Únormalize_keyr\   c   sP   € Ø	Š�b×ÑÓ!€AÜ�‰�u˜aÓ €AØ	�	‰	�#�sÓ€AÜ�6‰6�&˜#˜qÓ!×'Ñ'Ó)Ð)r   .c                 ó    — | xs dj                  d«      D �ch c]  }t        |«      rt        |«      ’Œ }}t        t        |«      «      S c c}w )a  Tags normalizados y ordenados, sin duplicados.

    `normalize_key` conserva el orden (lo usa avoid.jsonl, que no se puede
    romper). Para detectar casi-duplicados hace falta una firma insensible al
    orden: dos lineas con los mismos tags en distinto orden son la misma pose.
    rS   Ú,)Úsplitr\   ÚtupleÚsorted)rQ   ÚtokenÚtagss      r   Ú	signaturerd   j   sV   € ð  ’o 2×,Ñ,¨SÔ1óá1ˆEÜ˜Ôô 	�eÕØ1ð 	ð ô
 ”˜“ÓÐùòs   ˜Ac           	      óÐ   — d}| D ]W  }t         j                  t        |j                  dd«      «      «      }|sŒ4t	        |t        |j                  d«      «      «      }ŒY d|dz   d›�S )Nr   ÚidrS   r"   ÚpbÚ04d)Ú_ID_REÚmatchÚstrrI   ÚmaxÚintÚgroup)rC   Útopr2   Úms       r   Únext_idrq   y   s^   € Ø
€CÛˆÜ�L‰Lœ˜QŸU™U 4¨›_Ó-Ó.ˆÚÜ�cœ3˜qŸw™w q›z›?Ó+‰Cð ð ��a‘˜ˆ}ÐÐr   c	                 ó²  — t        «       }	t        |	«      }
t        |t        «      r|g}t	        |xs g «      }d }|rPt        |«      }|j                  «       r3t        «        t        |
› d�z  }t        j                  ||«       d|
› d�}n|}|
| |||||||t        j                  «       j                  d«      |dœ}|	j                  |«       t        |	«       |
S )Nz.pngzrefs/ú%Y-%m-%d)rf   rQ   ÚnivelÚtemaÚ
provenanceÚref_pngÚcharÚseedÚlora_weightÚfechaÚnotas)rB   rq   Ú
isinstancerk   rN   r   r#   r   r   ÚshutilÚcopy2r   ÚnowÚstrftimer'   rE   )rQ   rt   ru   rw   rx   ry   rv   rz   r|   rC   Únew_idÚ
ref_storedÚsrcÚdestÚentrys                  r   Úadd_poser‡   ‚   sØ   € ä‹k€GÜ�WÓ€Fä�$œÔØˆvˆÜ�’
˜Ó€Dà€JÙÜ�7‹mˆØ�:‰:Œ<ÜŒMÜ  ¨˜oÑ-ˆDÜ�L‰L˜˜dÔ#Ø   ¨Ð-‰Jà ˆJð ØØØØ ØØØØ"Ü—‘“×(Ñ(¨Ó4Øñ€Eð ‡N�N�5ÔÜˆgÔØ€Mr   c                 óŠ   — |€
t        «       }|j                  t        | «      «      }t        |xr |j                  d«      «      S )NÚ	blacklist)rK   rI   r\   Úbool)rQ   rJ   r=   s      r   Ú
is_avoidedr‹   ¨   s:   € Ø€}Ü“ˆØ
�)‰)”M )Ó,Ó
-€CÜ�Ò,˜Ÿ™ Ó,Ó-Ð-r   c                 óæ   — t        | «      }t        «       }|j                  |«      xs ||ddddœ}||d<   d|d<   t        j                  «       j                  d«      |d	<   |||<   t        |«       |S )
zÎMete la pose en avoid con blacklist directa (la usa la UI, D2.3).

    A diferencia de `penalize`, no cuenta fallos: deja la pose fuera del pool
    ya. Es idempotente (volver a llamar no cambia nada).
    r   FrS   ©rG   ÚmotivoÚfallosr‰   ÚultimarŽ   Tr‰   rs   r�   )r\   rK   rI   r   r€   r�   rP   )rQ   rŽ   rG   rJ   r=   s        r   r‰   r‰   ¯   s}   € ô ˜	Ó
"€CÜ‹L€EØ
�)‰)�C‹.ò Ø˜f°ÀÐQSñ€Cð €Cˆ�MØ€CˆÑÜ—L‘L“N×+Ñ+¨JÓ7€Cˆ�MØ€Eˆ#�JÜˆuÔØ€Jr   c                 óT   — t        | «      }t        «       }||vry||= t        |«       y)z5Saca la pose de avoid (reactivar). -> True si estaba.FT)r\   rK   rP   )rQ   rG   rJ   s      r   Úunblacklistr’   Â   s0   € ä
˜	Ó
"€CÜ‹L€EØ
�%ÑØØˆcˆ
ÜˆuÔØr   c                 ó4  — t        | «      }t        «       }|j                  |«      xs ||ddddœ}||d<   t        |j                  dd«      «      dz   |d<   t	        j
                  «       j                  d«      |d	<   |d   |k\  |d
<   |||<   t        |«       |S )Nr   FrS   r�   rŽ   r�   r"   rs   r�   r‰   )r\   rK   rI   rm   r   r€   r�   rP   )rQ   rŽ   Ú	thresholdrG   rJ   r=   s         r   Úpenalizer•   Í   s¢   € Ü
˜	Ó
"€CÜ‹L€EØ
�)‰)�C‹.ò Ø˜f°ÀÐQSñ€Cð €Cˆ�MÜ˜Ÿ™ ¨!Ó,Ó-°Ñ1€Cˆ�MÜ—L‘L“N×+Ñ+¨JÓ7€Cˆ�MØ˜8‘}¨	Ñ1€CˆÑØ€Eˆ#�JÜˆuÔØ€Jr   c              #   óÂ   K  — | €d–— yt         t        t        t        f}t	        | «      a t         dz  at         dz  at         dz  a	 d–— |\  a aaay# |\  a aaaw xY w­w)zBApunta temporalmente el banco a `bank_dir` (None = el del modulo).Nr   r   r   )r   rA   rH   r   r   )Úbank_dirÚsaveds     r   Ú_bank_dir_overrider™   Ü   sn   è ø€ ð ÐÛØÜ”y¤*¬hÐ7€EÜ�H‹~€HÜÐ,Ñ,€IÜ˜MÑ)€JÜ˜&Ñ €Hð:Ûà49Ñ1ˆ�)˜Z©ø°EÑ1ˆ�)˜Z©üs   ‚AAÁA ÁAÁ	AÁAc                 ó�  — t        | «      } | j                  «       st        j                  d| «       i S 	 t	        j
                  | j                  d¬«      «      }t        |t        «      st        j                  d| «       i S |S # t        j                  t        t        f$ r#}t        j                  d| |«       i cY d}~S d}~ww xY w)zŽLee un verdicts_<stamp>.json (dict por nombre de fichero).

    Devuelve {} (sin lanzar) si el fichero falta, no es JSON o no es un dict.
    zverdicts no encontrado: %sr   r!   zverdicts ilegible %s (%s)Nz3verdicts con forma inesperada en %s (dict esperado))r   r#   r+   r,   r(   r)   Ú	read_textr*   Ú
ValueErrorÚOSErrorr}   Údict)r   Údatar2   s      r   Úload_verdictsr    î   s¢   € ô
 �‹:€DØ�;‰;Œ=Ü�‰Ð3°TÔ:Øˆ	ðÜ�z‰z˜$Ÿ.™.°'˜.Ó:Ó;ˆô �dœDÔ!Ü�‰ÐLÈdÔSØˆ	Ø€Køô × Ñ ¤*¬gÐ6ò Ü�‰Ð2°D¸!Ô<Ø�	ûðús   µ%B ÂCÂ"C Â:CÃ Cc                 óÜ  — t        | «      } ddddœ}| dz  }|j                  «       st        d| › d�«       |S t        |«      }|st        d|› d�«       |S 	 t	        j
                  |j                  d¬«      «      }t        |t        «      st        d|› �«       |S t        |«      5  t        «       }|D �ch c].  }t        |j                  dd«      «      |j                  d«      f’Œ0 }	}|D �]z  }
t        |
t         «      sŒt        |
j                  dd«      «      j"                  }|j                  |«      }|€ |j                  |
j                  d«      «      }t        |t         «      s|dxx   dz  cc<   Œ‹t%        |j                  d«      xs d«      j'                  «       j)                  «       }t        |j                  d«      xs g «      }|xs d|
d<   ||
d<   |dk(  �r|
j                  d«      dk7  r|dxx   dz  cc<   �Œ|
j                  dd«      }t        |«      |
j                  d«      f}||	v r|dxx   dz  cc<   �Œ[| dz  |z  }|j                  «       s| dz  |z  }t+        ||
j                  d«      |
j                  d«      xs g |j                  «       r|nd|
j                  dd«      |
j                  d«      d|
j                  dd«      ¬«       |	j-                  |«       |d xx   dz  cc<   �Œ|d!k(  rX|
j                  dd«      }t/        |«      r|dxx   dz  cc<   �ŒBt1        |d"j3                  |«      d¬#«       |d$xx   dz  cc<   �Œn|dxx   dz  cc<   �Œ} 	 ddd«       |j5                  t	        j6                  |d%d¬&«      d¬«       |S # t        j                  t        t        f$ r}t        d	|› d
|› �«       |cY d}~S d}~ww xY wc c}w # 1 sw Y   ŒwxY w)'aI  Pliega los veredictos de una corrida en el banco.

    - `aprobada` + `origin=="explore"` -> `add_pose` (ref_png = raw/<file> si
      existe, si no img/<file>; original limpio preferido).
    - `rechazada` -> `penalize` con `threshold=1`: un rechazo de auditoria
      excluye la pose en TODAS partes de inmediato (Review Focus #5), ya que la
      clave avoid es la linea de pose normalizada. Idempotente: si la pose ya
      esta en avoid, se salta (no re-incrementa `fallos`).
    - `dudosa` -> skipped (ni promociona ni penaliza).
    - `origin=="bank"` aprobada -> skipped (ya estaba en el banco).
    Nunca duplica: si `normalize_key(pose_line)` ya esta en el banco para ese
    nivel, se salta. Escribe `verdict`/`motivos` de cada registro de vuelta en
    `pack_manifest.json`. -> {"promoted":int,"penalized":int,"skipped":int}
    r   )ÚpromotedÚ	penalizedÚskippedzpack_manifest.jsonz[!] sin pack_manifest.json en z; nada que promoverz[!] sin verdicts en r   r!   z[!] manifest ilegible en z: Nz%[!] manifest con forma inesperada en rQ   rS   rt   Úfiler¤   r"   ÚverdictÚmotivosÚaprobadaÚoriginÚexploreÚrawÚimgru   rx   ry   rz   ç      ð?)rQ   rt   ru   rw   rx   ry   rv   rz   r¢   Ú	rechazadaú, )r”   r£   F)r:   Úindent)r   r#   Úprintr    r(   r)   r›   r*   rœ   r�   r}   rN   r™   rB   r\   rI   rž   r-   rk   r&   rV   r‡   Úaddr‹   r•   ÚjoinÚ
write_textr<   )Úrun_dirÚverdicts_pathr—   ÚresultÚmanifest_pathÚverdictsÚrecordsr2   ÚbankÚknownÚrecr-   Úvr¦   r§   rQ   rG   Úrefs                     r   Úpromote_runrÀ     s¿  € ô �7‹m€GØ¨!¸Ñ:€FàÐ2Ñ2€MØ×ÑÔ!ÜÐ.¨w¨iÐ7JÐKÔLØˆä˜]Ó+€HÙÜÐ$ ] OÐ3FÐGÔHØˆðÜ—*‘*˜]×4Ñ4¸gÐ4ÓFÓGˆô �gœtÔ$ÜÐ5°m°_ÐEÔFØˆä	˜HÕ	%Ü‹{ˆáó Ù�Qô   §¡ k°2Ó 6Ó7¸¿¹¸w»ÒHØð 	ð  ô ˆCÜ˜c¤4Ô(ØÜ˜Ÿ™ ¨Ó+Ó,×1Ñ1ˆDØ—‘˜TÓ"ˆAØˆyØ—L‘L §¡¨£Ó1�Ü˜a¤Ô&Ø�yÓ! QÑ&Ó!Øä˜!Ÿ%™% 	Ó*Ò0¨bÓ1×7Ñ7Ó9×?Ñ?ÓAˆGÜ˜1Ÿ5™5 Ó+Ò1¨rÓ2ˆGØ$š_¨ˆC�	‰NØ$ˆC�	‰Nà˜*Ó$Ø—7‘7˜8Ó$¨	Ò1Ø˜9Ó%¨Ñ*Ó%ÙØŸG™G K°Ó4�	Ü$ YÓ/°·±¸Ó1AÐB�Ø˜%‘<Ø˜9Ó%¨Ñ*Ó%ÙØ ‘o¨Ñ,�Ø—z‘z”|Ø! E™/¨DÑ0�CÜ 9°C·G±G¸GÓ4DØ!Ÿg™g f›oÒ3°Ø(+¯
©
¬¡¸$Ø!Ÿg™g f¨bÓ1¸¿¹À»Ø$-Ø%(§W¡W¨]¸CÓ%@õBð —	‘	˜#”Ø�zÓ" aÑ'Õ"Ø˜KÒ'ØŸG™G K°Ó4�	Ü˜iÔ(ð ˜9Ó%¨Ñ*Ó%ÙÜ˜ D§I¡I¨gÓ$6À!ÕDØ�{Ó# qÑ(Õ#à�yÓ! QÑ&Õ!ñ] ÷ 
&ðj ×ÑÜ�
‰
�7¨°qÔ9ÀGð ô Mà€Møô} × Ñ ¤*¬gÐ6ò ÜÐ)¨-¨¸¸1¸#Ð>Ô?Ø�ûðüò ÷ 
&Ð	%ús=   Á%N Â'O"Â63OÃ)JO"ÎOÎ=OÏOÏOÏO"Ï"O+c           	      ó@  — |xs t         }t        |xs g «      }t        «       }| }|�$|D �	cg c]  }	|	j                  d«      |k(  sŒ|	‘Œ }}	|�+|D �	cg c]  }	||	j                  d«      xs g v sŒ|	‘Œ }
}	|
r|
}|D �	cg c]3  }	|	j                  d«      |vrt	        |	j                  dd«      |«      s|	‘Œ5 }}	t        dt        |«      «      }|dk  rg S |t        |«      k\  rt        |«      }|j                  |«       |S |j                  ||«      S c c}	w c c}	w c c}	w )Nrt   ru   rf   rQ   rS   r   )ÚrandomÚsetrK   rI   r‹   rl   rm   ÚlenrN   ÚshuffleÚsample)rC   rt   ru   Úexclude_idsÚnÚrngÚexcluderJ   Úpoolr2   ÚtaggedÚchosens               r   rÆ   rÆ   a  s%  € Ø
Š-”€CÜ�+Ò# Ó$€GÜ‹L€Eà€DØÐÙÓ;™4�a 1§5¡5¨£>°UÓ#:’˜4ˆÐ;ØÐÙ!ÓC™T˜ T¨a¯e©e°F«mÒ.A¸rÒ%B’!˜TˆÐCÙØˆDáó ?‘t�!Ø�u‰u�T‹{ 'Ñ)Ü˜qŸu™u [°"Ó5°uÔ=ò �t€Dð ?ô 	ˆAŒs�1‹v‹€AØˆA‚vØˆ	ØŒC�‹I‚~Ü�d“ˆØ�‰�FÔØˆØ�:‰:�d˜AÓÐùò# <ùâCùò?s   ¬DÁDÁDÁ/DÁ=8Dc                 ó~  — | €
t        «       } t        D �ci c]  }|d“Œ }}t        «       }| D ]I  }|j                  d«      |v r||d   xx   dz  cc<   |j	                  |j                  d«      xs g «       ŒK t        d„ t        «       j                  «       D «       «      }t        | «      |t        |«      |dœS c c}w )Nr   rt   r"   ru   c              3   óD   K  — | ]  }|j                  d «      sŒd–— Œ y­w)r‰   r"   N)rI   )Ú.0r=   s     r   Ú	<genexpr>zstats.<locals>.<genexpr>…  s   è ø€ ÐMÑ4˜¸¿¹ÀÕ8L”!Ñ4ùs   ‚ ™ )ÚtotalÚby_levelÚtemasÚavoided)
rB   ÚLEVELSrÃ   rI   ÚupdateÚsumrK   rO   rÄ   ra   )rC   ÚlvrÓ   rÔ   r2   rÕ   s         r   ÚstatsrÚ   |  s²   € Ø€Ü“+ˆÝ &Ó'¡˜"��A‘ €HÐ'Ü‹E€EÛˆØ�5‰5�‹>˜XÑ%Ø�Q�w‘ZÓ  AÑ%Ó Ø�‰�Q—U‘U˜6“]Ò( bÕ)ð ô ÑMœz›|×2Ñ2Ô4ÓMÓM€GÜ˜“\¨xÜ˜E“]¨wñ8ð 8ùò (s   •
B:c                 óv  — | €
t        «       } g }t        «       }| D ]›  }|j                  d«      }||v r|j                  d|› �«       |j	                  |«       |j                  d«      }|sŒQt        |«      }|j                  «       s	t        |z  }|j                  «       rŒ†|j                  |› d|› �«       Œ� |S )Nrf   zduplicate id: rw   z: ref_png missing on disk: )	rB   rÃ   rI   r'   r²   r   Úis_absoluter   r#   )rC   ÚproblemsÚseenr2   Úeidr¿   Úps          r   Úcheck_integrityrá   Š  sª   € Ø€Ü“+ˆØ€HÜ‹5€DÛˆØ�e‰e�D‹kˆØ�$‰;Ø�O‰O˜n¨S¨EÐ2Ô3Ø�‰�ŒØ�e‰e�IÓˆÚÜ�S“	ˆAØ—=‘=”?Ü˜s‘N�Ø—8‘8•:Ø—‘ 3 %Ð'BÀ3À%Ð HÕIð ð €Or   c                  óB  — t        j                  t         j                  d¬«       t        j                  d¬«      } | j                  ddd¬«       | j                  d	dd
¬«       | j                  ddd¬«       | j                  ddd¬«       | j                  dd¬«       | j                  dt        dd¬«       | j                  ddd¬«       | j                  ddd¬«       | j                  ddd¬«       | j                  «       }|j                  rU|j                  st        d «      ‚t        |j                  |j                  «      }t        d!|d"   › d#|d$   › d%|d&   › �«       y |j                  rc|j                  st        d'«      ‚t        |j                  |j                  |j                   «      }t        t#        j$                  |d(¬)«      «       y |j&                  rOt)        «       }t+        |j&                  «      }||v r||= t-        |«       t        d*|› �«       y t        d+|› �«       y |j.                  r8t1        «       }|D ]  }t        d,|› �«       Œ |rt        d-«      ‚t        d.«       y |j2                  r‰t3        «       }t        d/|d0   › �«       t        d1d2j5                  d3„ |d4   j7                  «       D «       «      z   «       t        d5|d6   rd2j5                  |d6   «      nd7z   «       t        d8|d9   › �«       y t9        «       }	|	D ]j  }
d:j5                  |
j;                  d;«      xs g «      }t        |
j;                  d<«      › d=|
j;                  d>«      › d?|› d@|
j;                  dAdB«      › �«       Œl t        dCt=        |	«      › dDt>        › dE�«       y )FNz%(levelname)s %(message)s)ÚlevelÚformatz#Banco de poses PlumLoom (pose_bank))Údescriptionz--listÚ
store_truezlista las poses del banco)ÚactionÚhelpz--statszresumen por nivel/temaz--checkzchequeo de integridadz--avoidÚKEYzpenaliza una pose)Úmetavarrè   z--motivoz'motivo de la penalizacion (con --avoid))rè   z--thresholdé   z,fallos para blacklist automatica (default 3))ÚtypeÚdefaultrè   z--unblacklistzsaca una pose del avoidz	--promoteÚRUN_DIRz8promociona los aprobados de una corrida (con --verdicts)z
--verdictsÚPATHz%verdicts_<stamp>.json (con --promote)z![!] --promote requiere --verdictsz	promoted r¢   z penalized r£   z	 skipped r¤   z[!] --avoid requiere --motivoFr9   zunblacklisted: zno estaba en avoid: z[!] r"   z[OK] banco integroztotal: rÒ   z
by_level: r¯   c              3   ó0   K  — | ]  \  }}|› d |› �–— Œ y­w)Ú=Nr   )rÐ   Úkr¾   s      r   rÑ   zmain.<locals>.<genexpr>Õ  s!   è ø€ Ð&TÑ>S±d°a¸¨!¨¨A¨a¨S¤zÑ>Sùs   ‚rÓ   ztemas: rÔ   Ú-z	avoided: rÕ   r^   ru   rf   z  [rt   z]  z  rQ   rS   Ú(z
 poses en Ú)) ÚloggingÚbasicConfigÚWARNINGÚargparseÚArgumentParserÚadd_argumentrm   Ú
parse_argsÚpromoter¹   Ú
SystemExitrÀ   r±   rJ   rŽ   r•   r”   r(   r<   r’   rK   r\   rP   Úcheckrá   rÚ   r³   ÚitemsrB   rI   rÄ   rA   )rà   ÚargsÚresr=   rJ   rG   rÝ   Úprr[   rC   r2   rÔ   s               r   Úmainr  ž  sF  € Ü×ÑœgŸo™oÐ6QÕRÜ×ÑÐ,QÔR€AØ‡N�N�8 LÐ7R€NÔSØ‡N�N�9 \Ð8P€NÔQØ‡N�N�9 \Ð8O€NÔPØ‡N�N�9 eÐ2E€NÔFØ‡N�N�:Ð$M€NÔNØ‡N�N�=¤s°AØFð ô Hà‡N�N�?¨EÐ8Q€NÔRØ‡N�N�;¨	ØRð ô Tà‡N�N�<¨Ø?ð ô Aà�<‰<‹>€Dà‡|‚|Ø�}Š}ÜÐ@ÓAÐAÜ˜$Ÿ,™,¨¯©Ó6ˆÜ�	˜#˜j™/Ð*¨+°c¸+Ñ6FÐ5Gð HØ˜Y™Ð(ð*ô 	+àà‡z‚zØ�{Š{ÜÐ<Ó=Ð=Ü�t—z‘z 4§;¡;°·±Ó?ˆÜŒd�j‰j˜¨5Ô1Ô2Øà×ÒÜ“ˆÜ˜D×,Ñ,Ó-ˆØ�%‰<Ø�c�
Ü�uÔÜ�O C 5Ð)Ô*ð 	ô Ð(¨¨Ð.Ô/Øà‡z‚zÜ"Ó$ˆÛˆBÜ�D˜˜�+Õð áÜ˜Q“-ÐÜÐ"Ô#Øà‡z‚zÜ‹GˆÜ�˜˜'™
�|Ð$Ô%Üˆl˜TŸY™YÑ&T¸aÀ
¹m×>QÑ>QÔ>SÓ&TÓTÑTÔUÜˆi°A°g²J˜4Ÿ9™9 Q w¡ZÔ0ÀCÑHÔIÜ�	˜!˜I™,˜Ð(Ô)Øä‹k€GÛˆØ—‘˜Ÿ™˜v›Ò,¨"Ó-ˆÜ�—‘�t“�˜S §¡ w£Ð 0°°E°7¸"¸Q¿U¹UÀ;ÐPRÓ=SÐ<TÐUÕVð ô 
ˆAŒc�'‹lˆ^˜:¤i [°Ð
2Õ3r   Ú__main__)r   N)r­   rS   r@   )rë   )NNNr"   N)<Ú__doc__rù   r(   rö   ÚosrÂ   rZ   r~   ÚsysÚ
contextlibr   r   Úpathlibr   ÚstdoutÚreconfigureÚ__file__ÚresolveÚparentÚBASE_DIRÚ	getLoggerÚ__name__r+   ÚenvironrI   r   rA   rH   r   rÖ   ÚcompilerW   ri   r   rN   rž   r3   r>   rB   rE   rk   rK   rP   r\   r`   rd   rq   r‡   rŠ   r‹   r‰   r’   r•   r™   r    rÀ   rÆ   rÚ   rá   r  r   r   r   Ú<module>r     su  ðñó( Û Û Û 	Û Û 	Û Û 
Ý %Ý Ý à ‡
�
× Ñ  Ð0BÐ Ô Cá�‹>×!Ñ!Ó#×*Ñ*×1Ñ1€Ø	ˆ×	Ñ	˜8Ó	$€ð �z‰z�~‰~Ð1Ô2ñ �—‘Ð/Ñ0Ô1à˜JÑ&¨Ñ4ð 	ô Ð(Ñ(€	Ü˜Ñ%€
Ü�fÑ€à	,€àˆR�Z‰ZÐ<Ó=€
Ø	ˆ�‰�LÓ	!€ó0ð
�dð ˜t D™zó ð@�tð @ 4¨¡:ð @°$ó @ð"�4˜‘:ó "ð%�t˜D‘zð % dó %ð�D˜˜d˜‘Oó ð/�$ð /˜4ó /ð*˜Sð * Só *ð˜ð   s¨C x¡ó ð˜ó ð %'ñ#Ø+.ó#ñL.¨ó .ð Dó ð&˜dó ñ°ó ð ñ:ó ð:ð"˜4ó ñ(\¸$ó \ñ~ÈtÐTXÉzó ñ68˜4ó 8ñ T¨#¡Yó ò(@4ðF ˆzÒÙ…Fð r   