
    
3jO                     t   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J	r	J
r
JrJr  SSKJr  \R                  R!                  \R                  R#                  \R                  R#                  \5      5      SS5      rS rS rS	 rS
 rSS jrS rS rSS jrS rS rS rS r " S S\R@                  5      r!g)zIdeogram 4 prompt builder.

A single self-contained node with a visual bbox editor: draw regions on a blank
canvas, set each region's type/desc/text/color palette, and assemble the Ideogram 4 JSON caption prompt.
    N)Image	ImageDraw	ImageFontImageEnhance)iofontszFreeMono.ttfc                     U R                  S5      n [        U 5      S:X  a,  [        U SS S5      [        U SS S5      [        U SS S5      4$ S$ )N#   r            )   r   r   )lstriplenint)hs    R/home/wildlama/comfy/ComfyUI/custom_nodes/ComfyUI-KJNodes/nodes/ideogram4_nodes.py_hex_rgbr      sP    	ABEa&A+C!AOS1Q_c!Aa&"o>bSbb    c                     U u  pnSU-  SU-  -   SU-  -   nUS:  aF  SU-
  SU-
  -  n[        USU-
  U-  -   5      [        USU-
  U-  -   5      [        USU-
  U-  -   5      p2nXU4$ )NA`"?bX9?v/?   r   )round)rgbrgblumts         r   	_readabler#      s    GA!
!)eai
%!)
+C
Sy3Y39%S1WM)*E!sQw!m2C,DeAQTWXQX\]P]L]F^a!9r   c                      [         R                  " [        U 5      $ ! [         aA     [         R                  " U 5      s $ ! [         a    [         R                  " 5       s s $ f = ff = fN)r   truetype
_FONT_PATH	Exceptionload_default)sizes    r   _fontr+   %   s]    ,!!*d33 ,	,))$// 	,))++	,,s+    
A(A A( A$A(#A$$A(c                    / nUR                  S5       Ho  nSnUR                  5        HE  nU(       d  UOUS-   U-   nU(       a(  U R                  XS9U:  a  UR                  U5        UnMC  UnMG     UR                  U5        Mq     U$ )N
  font)split
textlengthappend)	drawtextr1   max_wlinesparalinewordtests	            r   _wrapr=   /   s    E

4 JJLD#4d):D85@T" ! 	T ! Lr   c                 z   Ub  UR                   u  pV[        XV5      nUS:  a  [        SSU-  5      OSn[        S[        XX-  5      5      [        S[        Xh-  5      5      pUR	                  S5      R                  X4[        R                  5      nUS:  a2  [        R                  " U5      R                  [        SUS-  5      5      nUR	                  S	5      nOi[        X5      nUS:  a  [        SSU-  5      OSn[        S[        X-  5      5      n	[        S[        X(-  5      5      n
[        R                  " S	X4S
5      n[        R                  " S	X4S5      n[        R                  " U5      n[        S[        U
S-  5      5      n[        U5      n[        [        SUS-
  5      5      nUS-   n[        U 5       GH  u  nn[!        U["        5      (       a  UR%                  S5      (       a  M4  UR%                  S5      =(       d    /  Vs/ s H  nU(       d  M  UPM     nnU(       a  ['        US   5      OSu  nnn[        S[        U	[        UR%                  SS5      U	-  5      5      5      n[        S[        U
[        UR%                  SS5      U
-  5      5      5      n[        S[        U	[        UR%                  SS5      UR%                  SS5      -   U	-  5      5      5      n[        S[        U
[        UR%                  SS5      UR%                  SS5      -   U
-  5      5      5      nUU:  a  UUnnUU:  a  UUnnUR)                  UUUU/UUUS4SS9  US S nU(       a  UU-
  S:  ax  [        SUS-  5      nUU-
  [+        U5      -  n [        U5       HI  u  n!n"U[        U!U -  5      -   n#UR)                  U#UU[        U!S-   U -  5      -   UU-   /['        U"5      S9  MK     UR%                  S5      S:X  a  SOSn$[-        US-   5      R/                  S5      n%UR1                  U%US9n&UR)                  UUUU&-   S-   UU-   S-   /UUUS4S9  S U-  S!U-  -   S"U-  -   S#:  a  S
OS$n'UR3                  US%-   US-   4U%U'US&9  UR%                  S'S(5      =(       d    S(n(U$S:X  a/  UR%                  S5      (       a  S)US   < S)U((       a  S*U(-   OS(< 3n(U((       d  GM!  UU-
  S+:  d  GM-  UU-   S-   n)[5        UU(UUU-
  S+-
  5       H8  n*U)U:  a    GMV  UR3                  US,-   U)4U*[7        UUU45      S--   US&9  U)U-  n)M:     GM     [        R8                  " X5      R	                  S5      n[:        R<                  " U[:        R>                  S.9S/-  n+[@        RB                  " U+5      RE                  S5      $ s  snf )0Nr   g      ?      RGBd           g      Y@RGBA)r   r   r   r   )r   r   r   r   
   @   	   r   nobboxpalette)   rJ   rJ   xywr   r   )outlinewidth   )filltyper6   objr0   r   r   r   r   rJ   )r   r   r   r      )rQ   r1   descr.   "u    —    r   )r   )dtypeg     o@)#r*   maxminr   convertresizer   LANCZOSr   
Brightnessenhancenewr   Drawr+   	enumerate
isinstancedictgetr   	rectangler   strzfillr3   r6   r=   r#   alpha_compositenpasarrayfloat32torch
from_numpy	unsqueeze),boxesrO   heightbg
brightnessiwih	long_edgescalerwrhbaseimgoverlayr5   fsr1   tag_fontlhiboxcrI   r   r   r    x1y1x2y2pal5shsegphexcsxetypetagtwtagfillbodytyr:   arrs,                                               r   _render_previewr   >   s=   	~K	.7!mC	)*Qbj)*C53D,EBzz% ''%--@**4088S*uBT9UVDll6"&	.7!mC	)*E%-()E&.)*ii.9ii,7G>>'"D	RrBw	 B9DSBF^$H	aBE"3#t$$(9(9"wwy17R7>7A17>*1(71:&1aCE#''#q/B"6789CE#''#q/B"6789CE3773?SWWS!_#D"JKLMCE3773?SWWS!_#D"JKLM7B7BBB'!Q3qIr{R"WMQaB7c$i'C$T?4%C.(BUAES=-A(A27KRZ[_R`a + ''&/V3!a%jq!__Sx_0BR!R"Wq[9Aq#O%*QY%:UQY%F#$M.Sg		2626"CgH	Ewwvr"(bF?swwv"6{dGdN,JKD4R"WMb1BdD$R!<7		262,9aAY3G&3PW[	\b	 =I #T 


-
5
5e
<C
**S


+e
3CC **1--S ?s   V8V8c                    S nU R                  SS5      U R                  SS5      U R                  SS5      U R                  SS5      4u  p#pEU" U5      U" U5      U" X5-   5      U" X$-   5      4u  pgpXh:  a  XpXy:  a  XpXgX/$ )Nc           
      F    [        S[        S[        U S-  5      5      5      $ )Nr   i  )rY   rZ   r   vs    r   r   _norm_bbox.<locals>.c   s    1c$a$h011r   rK   rC   rL   rM   r   )re   )
r   r   rK   rL   rM   r   yminxminymaxxmaxs
             r   
_norm_bboxr      s    2c"CGGC$5swwsC7H#''RUWZJ[[JA!qT1Q4151QU8;D{d{d##r   c                     [        U [        5      (       a  U R                  5       n U  Vs/ s H  o(       d  M  UR                  5       PM     sn$ s  snf r%   )rc   rd   valuesupper)colorsr   s     r   _paletter      s<    &$%+v!IAGGIv+++s
   
AAc           
        ^^ STS-   -  ST-  smn[        U [        5      (       a  [        R                  " U SS9$ [        U [        5      (       ah  U (       d  g[        S U  5       5      (       a!  SSR                  U4S	 jU  5       5      -   S
-   $ SSR                  UU4S jU  5       5      -   S-   U-   S
-   $ [        U [        5      (       ar  U (       d  gU R                  5        VVs/ s H0  u  p4T[        R                  " USS9-   S-   [        UTS-   5      -   PM2     nnnSSR                  U5      -   S-   U-   S-   $ [        R                  " U SS9$ s  snnf )Nz    r@   F)ensure_asciiz[]c              3   X   #    U  H   n[        U[        [        45      (       + v   M"     g 7fr%   )rc   rd   list).0rK   s     r   	<genexpr>_dumps.<locals>.<genexpr>   s!     :1:a$...s   (*[z, c              3   <   >#    U  H  n[        UT5      v   M     g 7fr%   _dumps)r   rK   lvls     r   r   r      s     "=1a6!S>>1s   ]z[
z,
c              3   H   >#    U  H  nT[        UTS -   5      -   v   M     g7f)r@   Nr   )r   rK   r   pads     r   r   r      s!     !FAq#q#'(:":As   "r-   z{}z: z{
})
rc   rg   jsondumpsr   alljoinrd   itemsr   )r   r   endkvalr   r   s    `    @r   r   r      s=   q!6C<HC!Szz!%00!T::::"=1"===CCuzz!FA!FFFMPSSVYYY!Tefelelenoen[a[\tzz!%884?&cTUgBVVenouzz%((4/#5;;::ae,, ps   (7Ec                     U (       a1   [         R                  " U 5      n[        U[        5      (       a  U$  / $ / $ ! [         R                   a     / $ f = fr%   )r   loadsrc   r   JSONDecodeError)sr   s     r   _parse_json_listr      sX    	

1A!T"" # I2I ## 	I	s   ,; AAc                     U R                  S5      U R                  S5      p!US:w  a  X!:  a  XUS-    OU n[        R                  " SS U5      $ )N{r   r@   z("(?:[^"\\]|\\.)*")|,(\s*[}\]])c                 T    U R                  S5      =(       d    U R                  S5      $ )Nr@   r   )group)ms    r   <lambda>_repair_json.<locals>.<lambda>   s    
@XaggVWj@Xr   )findrfindresub)r   r   jr"   s       r   _repair_jsonr      sJ     66#;qBw15AE
qA6646XZ[\\r   c                 >   U (       a"  U R                  5       (       a  U [        U 5      4OS HM  n [        R                  " U5      n[	        U[
        5      (       a  XLa  [        R                  " S5        Us  $ MO     g ! [        R                  [        4 a     Mo  f = f)N zO[Ideogram4PromptBuilderKJ] import_json had errors; recovered with lenient parse)
stripr   r   r   rc   rd   loggingwarningr   	TypeError)r   candr   s      r   _loads_captionr      s    )*qwwyy!\!_%b@	

4 A!T""=OO$uv # A  $$i0 		s   AA>>BBc           	         U R                  S5      =(       d    0 n/ nUR                  S5      =(       d    /  GH  n[        U[        5      (       d  M  UR                  S5      S:X  a  SOSUR                  SS5      =(       d    SUR                  SS5      =(       d    S[        UR                  S5      =(       d    / 5      S	.nUR                  S
5      n[        U[        [        45      (       a7  [        U5      S:X  a(  Uu  pgpUR                  US-  US-  X-
  S-  X-
  S-  S9  OUR                  SSSSSS9  UR                  U5        GM     U$ )Ncompositional_deconstructionelementsrR   r6   rS   r.   rU   color_palette)rR   r6   rU   rI   bboxr   g     @@)rK   rL   rM   r   gQ?g)\(?gQ?T)rK   rL   rM   r   rH   )re   rc   rd   r   tupler   updater4   )
capcdrp   elr   bbr   r   r   r   s
             r   _caption_to_boxesr      s,   	/	0	6BBEvvj!'R'"d##!#6!9vuvvfb)/R9K9Qrrvvo6<"=? VVF^b4-((SW\%'"DJJ$-+/DK63I  K JJdJCS ( Lr   c                   Z    \ rS rSr\S 5       r\   SS\R                  4S jj5       rSr	g)Ideogram4PromptBuilderKJ   c                 p   [         R                  " SSS/ SQSS[         R                  R                  SSS	S
SSS9[         R                  R                  SSS	S
SSS9[         R                  R                  SSSSS9[         R                  R                  SSSSS9[         R
                  R                  S[         R
                  R                  S/ 5      [         R
                  R                  S[         R                  R                  SSS9/5      [         R
                  R                  S[         R                  R                  SSS9/5      /S9[         R                  R                  SSSS9[         R                  R                  SSSS9[         R                  R                  S SSS9[         R                  R                  S!SS"S#9[         R                  R                  S$SSSS%S&9[         R                  R                  S'SSSS(S)9[         R                  R                  S*SSSS+S)9[         R                  R                  S,S-S.S/SSS0S19[         R                  R                  S2S3S4/S3S5S69[         R                  R                  S7S8SSS9S)9[         R                  R                  S:SSS;S<9/[         R                  R                  S=S>9[         R                  R                  S?S>9[         R                  R                  S:S>9[         R                  R                  SS>9[         R                  R                  SS>9/S@9$ )ANr   zIdeogram 4 Prompt Builder KJzKJNodes/text)ideogramcaptionr   zprompt builderzjson promptTu  
Visual prompt builder for Ideogram 4's structured JSON caption format.

Drag on the canvas to draw regions; select a region to set its type (obj/text),  
description, text, and color palette. Set the background and optional style fields  
as widgets. Outputs the assembled caption JSON string.  

bbox is normalized to a 0-1000 grid as [ymin, xmin, ymax, xmax]; width/height set
the canvas aspect ratio.

Canvas controls:
- Drag: draw a new region
- Ctrl/Cmd-drag: force-draw a new region even on top of an existing one
- Click: select a region · Alt-click: cycle overlapping regions
- Double-click: edit the description inline
- Right-click: region list (select / delete / duplicate / reorder, top = front)
- Del / Backspace: remove the selected region
- Ctrl/Cmd + C / V / D: copy / paste / duplicate the selected region
- bbox fields (px / out) next to obj/text are editable

Color swatches:
- Click: edit · Drag: reorder · Right-click: remove
- Hover + Ctrl/Cmd + C / V: copy / paste the hex
- "+": add a color (uses the clipboard color if it is one)

Toolbar:
- Live: use the live sampling preview as the background (and grab the final result)
- Grab BG / Clear BG: use the last generated image as the background
- brightness slider, token estimate, and Copy / Paste / Clear allrO   r?   rF   i @  r   zdCanvas aspect width (also the pixel grid the bbox is measured in). Ideogram 4 needs multiples of 16.)defaultrZ   rY   steptooltiprq   zeCanvas aspect height (also the pixel grid the bbox is measured in). Ideogram 4 needs multiples of 16.high_level_descriptionr.   z@Optional one-line overview of the whole image (blank = omitted).)	multiliner   r   
backgroundz&Required scene background description.stylenonephoto)r   	art_style)options
aestheticsz#Style descriptor (blank = omitted).)r   r   lightingmediumimagezQOptional reference image shown as the editor background (and behind the preview).)optionalr   import_jsonzpOptional: a full caption JSON. When connected, it loads into the editor and drives the output per 'import_mode'.)r   r   force_inputr   style_palette_datazHSerialized style color palette from the editor (managed by the node UI).)r   
socketlessadvancedr   elements_dataz<Serialized regions from the editor (managed by the node UI).bg_brightness   r   rB   z>Background image brightness % (managed by the node UI slider).)r   rZ   rY   r   r   r   import_mode
when emptyalwayszHow a wired import_json is used: 'when empty' only seeds the editor while it has no regions (then the editor wins, so you can edit); 'always' makes the wired JSON authoritative so its changes always propagate to the output.)r   r   r   output_formatcompactzOutput JSON formatting (set via the editor toolbar): 'compact' (default, what Ideogram 4 expects) or 'pretty' (indented, for readability).bboxeszOptional pixel-space boxes ({x, y, width, height}) used to seed the editor's regions when it has none. Ignored once regions exist.)r   r   r   prompt)display_namepreview)node_idr  categorysearch_aliasesis_experimentaldescriptioninputsoutputs)r   SchemaIntInputStringDynamicComboOptionr   ComboBoundingBoxOutput)clss    r   define_schema&Ideogram4PromptBuilderKJ.define_schema   s   yy.7#[ E< WdB &L  MXtR &M  N		 8DRT(j   l		b(P   R%%gOO**626OO**7		<5  OO**;		R@9 8%  		bBgh		
B@ef		">cdw'z  |		rDVZ)S   T 		 4bT\`(r   t		W[(f   h_baSUYdh%e  g}|X6NXd(u  v 		t^b)g   h $$X$.n % oO*X 		  h 7Y7%%8%<7384]U
 U	
r   Nreturnc                 	   US;  a  SnUS:X  a  [         OS n[        U
5      nSnU(       d  U(       a  [        U[        5      (       a  U/nO-U(       a$  [        US   [        [
        45      (       a  US   nOUnU H  n[        U[        5      (       d  M  UR                  UR                  SS5      U-  UR                  SS5      U-  UR                  S	S5      U-  UR                  S
S5      U-  SSS/ S.5        M     [        U5      n[        U5      nUS   nUS L=(       a    US:H  =(       d    U(       + nU(       a  Un[        U5      nGO\0 nUR                  5       (       a  UUS'   US:w  ad  XgS.nUS:X  a  UR                  SS5      US'   UUS'   OUUS'   UR                  SS5      US'   [        [        U	5      5      nU(       a  UUS'   UUS'   / nU H  n[        U[        5      (       d  M  UR                  S5      S:X  a  SOSnSU0nUR                  S5      (       d  [        U5      US'   US:X  a  UR                  SS5      US'   UR                  SS5      US'   [        UR                  S/ 5      5      nU(       a  US S US'   UR                  U5        M     UUS.US '   S n Ubt   [        R                  " US   R!                  5       R#                  5       R%                  5       S!-  R'                  SS!5      R)                  [*        R,                  5      5      n [1        UXU U5      n!/ n"U H  n[        U[        5      (       a  UR                  S5      (       a  M0  UR                  SS"5      UR                  SS"5      n$n#UR                  S#S"5      UR                  S$S"5      n&n%U%S:  a  U#U%-  n#U%* n%U&S:  a  U$U&-  n$U&* n&U"R                  [3        U#U-  5      [3        U$U-  5      [3        U%U-  5      [3        U&U-  5      S%.5        M     U"(       a  U"/O/ n'S&X/0n(U(       a  [4        R6                  " U5      /U(S''   U(       a  [        U5      /U(S('   [8        R:                  " U" U5      U!U'XU(S)9$ ! [.         a    S n  GNef = f)*N)r  r  r  prettyc                 .    [         R                  " U SSS9$ )NF),:)r   
separators)r   r   r   s    r   r   2Ideogram4PromptBuilderKJ.execute.<locals>.<lambda>C  s    4::a^cpzC{r   Fr   rK   rL   rO   rq   rS   r.   )rK   rL   rM   r   rR   r6   rU   rI   r   r  r   r   )r   r   r   r   r   r   style_descriptionrR   r6   rH   r   rU   rI   rP   )r   r   r   r   rC   rM   r   )rK   rL   rO   rq   dimsrp   r   )ui)r   r   rc   rd   r   r   r4   re   boolr   r   r   r   r   r   	fromarraydetachcpunumpyclipastyperj   uint8r(   r   r   r   r   r   
NodeOutput))r  rO   rq   r   r   r   r   r   r   r   r   r   r  r  r  r   r   dumprp   boxes_seededframer   importedkindused_importr   sdrI   r   r   r   elemrr   r	  
bbox_dictsrK   rL   bwbh
bboxes_outr'  s)                                            r   execute Ideogram4PromptBuilderKJ.execute<  st   
 66&K&(2v9{ /&$''Jvay4-@@q	!"d++266#q>E#9sAQW@W#%66'1#5#=BFF8UVDWZ`D`&+RPRT U   ;L!+.W~
 d*Ux0G0Tu9G%h/EG%++--4J01v~ %/E7?"'))GR"8BwK#)BxL#)BxL&+iiR&@B{O"#34F#GH*1B'/1+,H!#t,,"%''&/V";wwx((#-c?DLF?#&7762#6DL"wwvr2V"3779b#9:,3BQKD)%   )$7G23 __eAhoo&7&;&;&=&C&C&E&K%Q%QRSUX%Y%`%`acaiai%jk "%MJ 
Cc4((CGGH,=,=773$cggc3&7qAWWS#&S(9BAvRSAvRSE!e)$45V;L(-b5j(9U2PV;EWY Z  &0j\R
 uo&::e,-BwK#H-.ByM}}T']GZSUVV=  s   0A3Q9 9R	R	r   )r.   r.   r.   r.   r.   r.   r.   r  r  NNr   )
__name__
__module____qualname____firstlineno__classmethodr  r   r0  r=  __static_attributes__r   r   r   r   r      sL    V
 V
p NPUaOQoW WYVcVcoW oWr   r   )N2   )r   )"__doc__r   osr   r   r,  rj   rm   PILr   r   r   r   comfy_api.latestr   pathr   dirname__file__r'   r   r#   r+   r=   r   r   r   r   r   r   r   r   	ComfyNoder   r   r   r   <module>rN     s     	 	    9 9  WW\\"''//"''//(*CDg~^
c
,D.N
$,-&]*JWr|| JWr   