
    `gja                       d Z ddlmZ ddlZddlmZmZ ddlmZmZm	Z	 dZ
dZdZd	Zd
ZdZdZdZdZdZdZdZ ed      ZeZeZeZd@dZdAdZdBdZdCdZdDdZ dEdZ!dFdZ"dGdZ#dHdZ$dIdZ%dJdZ&dKdZ'dLdZ(d d!dMd"Z)dNd#Z*dOd$Z+dOd%Z, G d& d'      Z-dPd(Z.dQd)Z/dRd*Z0dSd+Z1dTdUd,Z2dVd-Z3dWd.Z4dXd/Z5dYdZd0Z6d[d1Z7d\d2Z8d3d4d5d6d]d7Z9d^d8Z:dXd9Z;d_d:Z<d`d;Z=dad<Z>d3d4d=d>dbd?Z?y)cu  Terminal renderer for the learning timeline (learned skills + memories).

The desktop app (``apps/desktop/src/app/starmap``) paints a GPU radial
constellation; a terminal can't, so this is a *rendition* of the same data as a
timeline bar chart — date rows, proportional skill/memory bars colored by the
day's dominant category, and a cumulative trajectory sparkline — plus per-slice
bucket metadata the TUI walks as a tree. The age gradient and complementary
memory ink are ported from the desktop source, not guessed.

Grids are emitted as style runs — ``[text, style, alpha, hex?]`` — so each
consumer maps the semantic style + brightness onto its own palette; the
optional 4th element overrides the base color (category heatmap). Pure,
stdlib-only.
    )annotationsN)datetimetimezone)AnyIterableOptionalgQ?gzG?gGz?ffffff?gp=
ף?bgskillmemorylabeldim   ●   ◆123456789abcc                L    	 | d S t        |       S # t        t        f$ r Y y w xY wN)float	TypeError
ValueError)values    N/root/.hermes/venv/lib/python3.12/site-packages/agent/learning_graph_render.py_to_tsr   0   s1    }t6%,6z" s    
 ##c                "    | |k  r|S | |kD  r|S | S r    )vlohis      r   _clampr   7   s    R201r6R0q0    c                8    t        | dd      } | | z  dd| z  z
  z  S )N              ?      )r   )ps    r   _smoothstepr'   ;   s'    q#sAq5AAIr    c                    t        | dd      }|t        k  r't        t        t        z
  t	        |t        z        z  z   S t        t
        t        z
  t	        |t        z
  dt        z
  z        z  z   S )uD   Port of geometry.ts ``recencyInk`` — smoothstep age → ink alpha.r"   r#      )r   AGE_MIDAGE_OLD_INKAGE_MID_INKr'   AGE_NEW_INK)rects     r   recency_inkr0   @   s_    sCAG|kK7;q7{;SSSS+3{AKTUX_T_C`7aaaar    c                    | sy	 t        j                  t        |       t        j                        }|j
                   d|j                  d       S # t        t        t        f$ r Y yw xY w)Nunknowntz %b %Y)
r   fromtimestampr   r   utcdaystrftimer   OSErrorOverflowError)tsdts     r   format_dater?   H   s_    ##E"I(,,?&&2;;w/011/ s   AA A*)A*c           
        d | D        D cg c]  }||	 }}|rt        |      nd}|rt        |      nd}|duxr |duxr ||kD  }t        | d       }t        t        |      dz
  d      }t	        |      D 	ci c]4  \  }}	t        |	j                  dd            t        |      dkD  r||z  nd6 }
}}	i }| D ]~  }	t        |	j                  dd            }t        |	j                  d	            }|r|||||z
  ||z
  z  }n|
j                  |d      }t        dt        z
  t        |dd
      z  z   ||<    ||||dS c c}w c c}	}w )uK   Port of time-axis.ts ``computeRecency`` (id → recency ratio, timed flag).c              3  P   K   | ]  }t        |j                  d                yw)	timestampN)r   get.0ns     r   	<genexpr>z"compute_recency.<locals>.<genexpr>T   s     Ck 23Cs   $&Nc                    t        | j                  d            t        | j                  d            nt        j                  t	        | j                  dd            fS )NrB   id )r   rC   mathinfstr)rF   s    r   <lambda>z!compute_recency.<locals>.<lambda>[   sH    *0{1C*D*PF155%&VZV^V^dB 
 r    keyr)   rI   rJ   r"   rB   r#   )r.   timedminTsmaxTs)
minmaxsortedlen	enumeraterM   rC   r   LEAD_INr   )nodesr/   knownmin_tsmax_tsrQ   orderedlastirF   	ord_ratior.   nidr=   ratios                  r   compute_recencyrd   R   sp   CUCU1q}QUEU SZdF SZdF$I6#5I&6/E
G s7|a#D[del[mnSWSTVWQUU4_%CL14DD#MnInC E!%%b/"AEE+&'R^(:v?Q&[Vf_5EMM#s+Ea'kVE3-DDDCE &II3 V os   EE=9E
c                    | j                  d      sy | j                  d      | j                  d      }}||y t        |t        |dd      ||z
  z  z         S )NrQ   rR   rS   r   r)   )rC   roundr   )r.   revealr   r   s       r   _date_atrh   p   sZ    777WWWswww/B	zRZfVQ*b2g6677r    c                   | j                         j                  d      } t        |       dk(  rdj                  d | D              } 	 t	        | dd d      t	        | dd d      t	        | dd	 d      fS # t
        t        f$ r Y y
w xY w)N#r$   rJ   c              3  &   K   | ]	  }|d z    yw)r%   Nr   )rE   cs     r   rG   zhex_to_rgb.<locals>.<genexpr>   s     %aAE%   r   r%            )      r   )striplstriprW   joinintr   
IndexError)ss    r   
hex_to_rgbry   |   s    		A
1v{GG%1%%1Qq62AaFBQqVR@@
# s   +A3 3BBc                .     dj                   d | D         S )Nz#{:02X}{:02X}{:02X}c              3  H   K   | ]  }t        t        |d d              yw)r   rq   N)rv   r   )rE   r   s     r   rG   zrgb_to_hex.<locals>.<genexpr>   s     )LQ#fQ3.?*@)Ls    ")format)rl   s    r   
rgb_to_hexr}      s    ' '')L!)LMMr    c                `     t        |dd      t         fdt        d      D              S )Nr"   r#   c              3  X   K   | ]!  }t        |   |   |   z
  z  z          # y wr   )rf   )rE   r`   abr&   s     r   rG   zmix_rgb.<locals>.<genexpr>   s0     CQqtqtad{a//0Cs   '*r$   )r   tuplerange)r   r   r/   r&   s   `` @r   mix_rgbr      s&    q#sAC%(CCCr    c                    d | D        \  }}}t        |||      t        |||      }}||z   dz  }||z
  }|sdd|fS |dkD  r|d|z
  |z
  z  n|||z   z  }||k(  r||z
  |z  ||k  rdndz   }	n||k(  r||z
  |z  dz   }	n||z
  |z  dz   }	|	dz  ||fS )	Nc              3  &   K   | ]	  }|d z    yw)rq   Nr   )rE   xs     r   rG   z_rgb_to_hsl.<locals>.<genexpr>   s     "1q3w"rm   r%   r"         ?rp   r   ro   <   )rU   rT   )
rl   rgr   mxmnlightdrx   hs
             r   _rgb_to_hslr      s    ""GAq!Aq\3q!Q<B"WME
RAC"S[QVb[a27mA	QwUaKA11-	qUaK!OUaK!Or61er    c                r   | dz  dz   dz  }dt        d|z  dz
        z
  |z  }|dt        |dz  dz  dz
        z
  z  }||dz  z
  }|dk  r||d}	}}n6|dk  r||d}	}}n*|dk  rd||}	}}n|dk  rd||}	}}n|d	k  r|d|}	}}n|d|}	}}t        ||z   d
z        t        ||z   d
z        t        |	|z   d
z        fS )Nh  r)   r%   r   r"   x         i,  rq   )absrf   )
r   rx   r   huerl   r   mr   r   r   s
             r   _hsl_to_rgbr      s   Gs?c
!C	
SUQ	1$A	QsRx1n)**+AAA
RxQa1	sQa1	sq!a1	sq!a1	sS!a1S!a1!a%3A}!5ua!es]7KKKr    c           	     j    t        |       \  }}}t        |dz   t        |d      t        |dd            S )N   r   ffffff?)r   r   rU   r   )rl   r   rx   r   s       r   _complementary_inkr      s3    a.KAq%q3wAsVE3-DEEr    T)darkc                  t        |       }|rdnd}|rdnd}| t        t        |||rdnd            t        t        t        |      |d            t        t        ||d            t        t        ||d	            t        |      d
S )z@Port of color.ts ``computePalette`` (the bits a terminal needs).)rq   rq   rq   )r   r   r   )   r      )   r   r   gQ?g
ףp=
?g?gffffff?r   )primaryr   r   r   r   r
   )ry   r}   r   r   )primary_hexr   r   baser
   s        r   derive_paletter      s    %G"?	DB WWdDDdKLG$6w$?TJKGD"d34'$C01n	 	r    c                    | j                  d      dk(  rd|z   S t        | j                  dd      xs d      }|dz  t        j                  t	        d|            z   | j                  d      rd	z   S dz   S )
z<Pick which visible objects deserve map markers + label rows.kindr   g      @useCountr   r%   r"   pinnedg       @)rC   r   rK   sqrtrU   )noder.   uses      r   _node_scorer      sn    xx8#Sy
Q',1
-C7TYYs3}--8JTTPSTTr    c                    t        | j                  d      xs | j                  d      xs d      j                         }t        |      dk  r|S |d d j	                         dz   S )Nr   rI   r2         u   …)rM   rC   rs   rW   rstrip)r   texts     r   _node_labelr      sY    txx ?DHHTN?i@FFHDt9?4BSb	(8(8(:U(BBr    c           	        | j                  d      dk(  r@| j                  d      dk(  rdnd}| dt        t        | j                  d                   S t        | j                  d      xs d	      t        t        | j                  d                  g}t	        | j                  d
d      xs d      }|r|j                  d|        | j                  d      r|j                  d       dj                  |      S )Nr   r   memorySourceprofilezprofile memory    · rB   categoryr   r   r   r   r   )rC   r?   r   rM   rv   appendru   )r   sourcebitscounts       r   
_node_metar      s    xx8#%)XXn%=%J!PXk&+1F*GHIJJ$/0+fTXXkEZ>[2\]DQ',1-EawK xxH;;tr    c                  *    e Zd ZdZddZedd       Zy)_ChartBucketr   r=   skillsmemoriesrZ   r.   c                X    || _         || _        d| _        d| _        g | _        d| _        y )Nr   r#   r   )selfr   r=   s      r   __init__z_ChartBucket.__init__   s,    
+-
r    c                4    | j                   | j                  z   S r   )r   r   )r   s    r   totalz_ChartBucket.total   s    {{T]]**r    N)r   rM   r=   r   )returnrv   )__name__
__module____qualname__	__slots__r   propertyr   r   r    r   r   r      s     EI + +r    r   c                    t        j                  | t        j                        }|dk(  r#|j                  |j
                  |j                  fS |dk(  r|j                  |j
                  fS |j                  fS )Nr3   r9   month)r   r7   r   r8   yearr   r9   r=   granularityr>   s      r   _period_keyr      s`    			x||	4Be266**g""GG:r    c                    t        j                  | t        j                        }|dk(  r |j                   d|j                  d       S |dk(  r|j                  d      S |j                  d      S )Nr3   r9   r5   z%br   r6   z%Y)r   r7   r   r8   r9   r:   r   s      r   _period_labelr      se    			x||	4Be&&2;;t,-..g{{7##;;tr    c                   | sg S d   s#t        | fd      }t        |t        dt        |                  }t	        |      D cg c]  }t        d|dz    t        |             }}|D ]  }t        t        t        j                  d   j                  t        |j                  dd            d	      |z        d
|dz
              }||   }	|	j                  j                  |       |j                  d      dk(  r|	xj                  dz  c_        |	xj                   dz  c_         |S d}
dD ]  }i }| D ]  }t#        |j                  d            }| t%        ||      }|j                  |      }|t        t'        ||      |      }|||<   |j                  j                  |       |j                  d      dk(  r|xj                  dz  c_        |xj                   dz  c_         t        |      |k  s|dk(  st        |      dk  st        |      D cg c]  }||   	 }
} n |
Qj                  d      j                  d      }}t        d|      }g }
t	        |      D ]P  }|r|r||t        d|dz
        z  ||z
  z  z   n
t        |      }|
j                  t        t)        |      |             R | D ]  }d   j                  t        |j                  dd            d	      }t        t        t        j                  ||z        d
|dz
              }|
|   }	|	j                  j                  |       |j                  d      dk(  r|	xj                  dz  c_        |	xj                   dz  c_         j                  d      j                  d      }}||
||kD  r||z
  nd
}|
D ].  }|r#t*        dt*        z
  |j,                  |z
  |z  z  z   nd|_        0 |
S c c}w c c}w )uD   Timeline rows: finest date granularity that fits, oldest → newest.rQ   c                `    d   j                  t        | j                  dd            d      S )Nr.   rI   rJ   r"   )rC   rM   )rF   r.   s    r   rN   z&_build_chart_buckets.<locals>.<lambda>  s&    c%jnnStR=QSV.W r    rO   r)   rj   r.   rI   rJ   r"   r   r   r   N)r9   r   r   rB   r9       rR   rS   r#   )rV   rT   rU   rW   r   r   r   rv   r   rK   floorrC   rM   rZ   r   r   r   r   r   r   r?   rY   r=   r.   )rZ   r.   max_rowsr^   n_binsr`   bucketsr   idxr   chosenr   groupsr=   rP   bucketr\   r]   r   spans    `                  r   _build_chart_bucketsr   	  s   	w<$WXXs1c'l34@EfN1<!AE7U1X6NN 	DfTZZE
s488D";M7NPS(TW](]^`acilmcmnoCAGGNN4 xx8+

a
A	 +/F/ 68 	#D-.Bzb+.CZZ_F~%mB&DbI$sLL%xx8+1$"	#" v;("{e';Fr@Q-3F^<cfSk<F<+. ~)3777+;Q!v 	=AJPU[1s1fqj11fvoFFafghaiBMM,{2;<	=  	DE
s488D"#56<AfTZZF
3Q
CDCsAGGNN4 xx8+

a
A	 WWW%swww'7FF & 2v7IfW]oFVOcdD ^PTWGV1Ct0KLLZ]
^Ms O@ =s   "O, O1c                R      j                   sy t         j                    fd      S )Nc                h    t        | t        | j                  d            xs j                        S NrB   )r   r   rC   r=   )r   r   s    r   rN   z$_bucket_label_node.<locals>.<lambda>O  s)    k$txxP[G\@]@jagajaj.k r    rO   )rZ   rU   )r   s   `r   _bucket_label_noder   L  s    <<v||!kllr    c                j    g }t         j                   fd      }|D ]  }|j                  d      dk(  rt        nt        }t        |j                  d      xs |j                  d      xs d      j                         }|xs i j                  t        |j                  dd                  }|j                  t        |j                  dd            |j                  d      dk(  rt        nt        t        |      |t        |      |rt        |j                  d	d            nd|d
        |S )Nc                T    t        | j                  d            xs j                  S r   )r   rC   r=   )rF   r   s    r   rN   z_bucket_nodes.<locals>.<lambda>U  s    k8J1K1Xvyy r    rO   r   r   r   rI   r2   rJ   body)rI   glyphr   	fullLabelmetar   style)rV   rZ   rC   STYLE_MEMORYSTYLE_SKILLrM   rs   r   MEMORY_GLYPHSKILL_GLYPHr   r   )r   memory_lookupoutr^   r   r   	raw_labelr   s   `       r   _bucket_nodesr   R  s     "CV\\'XYG 
 $ 0H <+)HTXXd^HyIOOQ	%2**3txxb/A+BC

$((4,-)-&)9X)E;$T*&"4(7=FJJvr232
	
	
 Jr    c                   t        |      }t        |j                  dg       xs g       D ci c]-  \  }}t        |t              rd|j                  d       d| |/ }}}g }t        |       D ]  \  }}t        |      }|j                  ||j                  t        |j                        |j                  |j                  |j                  ||r|j                  |      nd t        ||      d	        |S c c}}w )Nr   zmemory:r   :)	indexr   dater   r   r   r   colorrZ   )category_color_maprX   rC   
isinstancedict_bucket_categoryr   r   r?   r=   r   r   r   r   )	r   payloadcmapr   cardr   rowsr   cats	            r   _bucket_rowsr  h  s    g&D #7;;x#<#BCCdD! $((8$%Qse,d2M 
 "$D ) 
Vv&#FII. --"OO*-#4&v}=
	

 K+s   2C8c           
     
   | j                  dg       xs g D cg c]\  }|j                  d      rI|j                  d      dk7  r5t        |j                  d            t        |j                  dd            f^ }}|r|S i }| j                  dg       D ]M  }|j                  d      dk(  rt        |j                  d      xs d      }|j                  |d      d	z   ||<   O t        |j	                         d
       S c c}w )Nclustersr   r   r   r   rZ   r   r   r)   c                    | d    | d   fS )Nr)   r   r   )kvs    r   rN   z"_category_counts.<locals>.<lambda>  s    2a5&"Q% r    rO   )rC   rM   rv   rV   items)r  rl   r  countsr   r  s         r   _category_countsr    s     Z,255z!2h!> 
QUU:	QUU7A%6!78H 
 FGR( -88Fx'$((:&1'2jja(1,s	-
 &,,.&@AAs   A!D c                    t        |       }t        dt        |            }t        |      D ci c]%  \  }\  }}|t	        t        |dz  dz  dd            ' c}}}S c c}}}w )zHDeterministic, evenly-spread hue per skill category (theme-independent).r)   gK7A0a@r   皙?gףp=
?)r  rU   rW   rX   r}   r   )r  r  rF   r`   r  _cs         r   r   r     s`    (HAs8}A^ghp^qrrlaQZRUWYCKW(;T4HIIrrrs   *Ac           
        t        |       }t        |       }|d | }t        dt        |      t        |      z
        }|D cg c]!  \  }}d|j	                  |d      | d| dd# c}}|rddd| dgz   S g z   S c c}}w )	Nr   r   rJ   z ())r   r   r      ·+)r   r  rU   rW   rC   )r  limitr  catsshownhiddenr  r   s           r   category_legendr    s    g&DG$D%LECIE
*+F  C $((3"3Rwa>PQ CID2!F8
=	>R R OQR R s   &A=c                    i | j                   D ]M  }|j                  d      dk(  rt        |j                  d      xs d      }j                  |d      dz   |<   O rt        fd      S d S )	Nr   r   r   r   r   r)   c                    |    S r   r   kr  s    r   rN   z"_bucket_category.<locals>.<lambda>      VAY r    rO   )rZ   rC   rM   rU   )r   r   r  r  s      @r   r   r     sw    F -88Fx'$((:&1'2jja(1,s	-
 4:3v./CtCr    c           
     F   | sg S t        d | D              xs d}t        t        t        j                  |t        |       z        dt        |                   }d}g }| d| D ]4  }||j                  z  }|j                  t        ||z  |dz
  z               6 dg|z  }d}	|D ]\  }
t        t        |	|
      t        |	|
      dz         D ]  }d|cxk  r|k  sn ||   dk(  sd||<   ! d|
cxk  r|k  rn nd||
<   |
}	^ dt        d	gd
j                  |      t        dggS )z;Cumulative learning curve as a compact star-path sparkline.c              3  4   K   | ]  }|j                     y wr   r   rE   r   s     r   rG   z"_trajectory_row.<locals>.<genexpr>  s     )A)   r)   r   Nr5   r     ✦ztrajectory r  rJ   gQ?)sumrv   r   rK   ceilrW   r   r   rf   r   rT   rU   STYLE_LABELru   r   )r   widthrg   r   visibleaccpointsr   cellsr_   r&   r   s               r   _trajectory_rowr-    s7   	))).QE&6CL#891c'lKLG
CFXg :qwweS5[UQY789: EEMED s4|Sq\A%56 	 AA~~%(c/a	  >E>E!H K.d0STTr    P   rn   r#   colsr  rg   c               >
   t        |dd      }t        d|      }t        d|      }t        | j                  dg             }|sdt        dgg}|gd|d	d
S t        |      }t        |       }t        ||t        d|dz
              }t        |      }	t        t        t        j                  ||	z        d	|	            }
t        d |D        d      xs d}t        dt        d |D                    }t        d||z
  dz
        }g }g }d	}t        |      D ]  \  }}||
k\  r|j                  g        ||j                  z  }t!        |j"                        }|j                  r%t        dt%        |j                  |z  |z              nd	}|j                  r%t%        |j&                  |j                  z  |z        nd	}|j&                  r|d	k(  rd}||z
  }|j(                  r|d	k(  r|dkD  rd}|dz
  }t+        |      }d}|rt        |      dk  rt,        t        |         }|j                  d      dk(  rt.        nt0        }|j                  ||j                  d      dk(  rt2        nt4        t7        |      t9        |      |t%        |d      d       t;        |      }|r|j                  |      nd}|j<                  d| ddt>        |gdt        dgg}|r|j                  |t>        dg       nU|j                  rI|j&                  r|nd}|j                  |j&                  rdnd|j&                  rt0        nt.        ||g       |r|j                  d |z  t0        ||g       |r8|dk(  rd}ndd |d!z
  z  z   dz   }|j                  |t.        t        d"|      g       ||k  r|j                  d||z
  z  t@        dg       |j                  d#t@        dg       |j                  tC        |j&                        t0        t        d$|      g       |j(                  rM|j                  d%t        d&g       |j                  tC        |j(                        t.        t        d$|      g       ||
dz
  k(  r|j                  d't>        d(g       n,|j                  |k(  r|dkD  r|j                  d)t>        d*g       |j                  |        |j                  d|d!z   z  t@        dggtE        |t        d+||z
  d,z
        |             |tG        tI        ||            |||d-S ).u   Render one timeline frame at ``reveal`` (0→1).

    Date rows with proportional skill/memory bars colored by the day's dominant
    category, numbered markers tied to label rows, and a cumulative trajectory
    sparkline underneath.
    r"   r#   ,      rZ   u:   no learning yet — keep using Hermes and it maps out herer   rJ   r   )gridr   rg   r)  ro   r$   r   c              3  4   K   | ]  }|j                     y wr   r!  r"  s     r   rG   zrender_graph.<locals>.<genexpr>  s     .QWW.r#  r)   )default	   c              3  F   K   | ]  }t        |j                          y wr   )rW   r   r"  s     r   rG   zrender_graph.<locals>.<genexpr>  s     7!QWW7s   !rn   rp   r   r   )rP   r   r   r   r   alphaN>r5   u   │ r  r	   r$  r   u   ━r%   g?z  g
ףp=
?r  g333333?u	     ◀ nowg?u
     ☄ peakg      ?r      )r4  r   rg   r)  labels)%r   rU   listrC   	STYLE_DIMrd   r   r   rW   rv   rK   r&  rT   rX   r   r   r0   r.   rf   r   r   r   _LABEL_KEYSr   r   r   r   r   r   r   r   r'  STYLE_BGrM   r-  r?   rh   )r  r0  r  rg   rZ   placeholderr.   r  r   	n_bucketsvisible_bucket_count	max_totallabel_wbar_wr4  r=  r)  r`   r   inkbar_len	skill_len
memory_lenr   markerr   r  cat_hexrowhead_hex	mem_trails                                  r   render_graphrQ    s    FC%Fr4=Dr4=DWb)*ETV_adef$rVPQRR
%
 Cg&D"5#Atax8HIGGIvdii0B&CQ	RS.g.:?aI!S7w778GD7NR'(ED#%FGw' >	6$$KKO6<<&**%GM||#ay 8EABCYZGM||E6==6<<77BCYZ	==Y!^Iy(
??zQ7Q;J!I!&)CK!O V-F$(HHV$4$@LkEMM!-1XXf-=-I\{(.&t,""3]	 v&#&$((3-DQwipK02KEPY[_G`aJJT23\\"(--wTHJJE&--;]iknpxyzJJ	);WEFQ!	!Uj1n%=>F	JJ	<T3@AU? JJuw/3?@

D(C()

C&Ss^DE??JJY,-JJFOO,lCcNKL$q((JJ[#67\\Y&9q=JJk489C}>B 	KK3'A+&37y/'SVWY[_bi[iln[nSoqw:xyz HS&12 r    c                    | j                  dg       }t        d |D              }t        d |D              }t        t        d| ddt        t
        d| ddgS )NrZ   c              3  J   K   | ]  }|j                  d       dk7  sd  ywr   r   r)   NrC   rD   s     r   rG   zbuild_legend.<locals>.<genexpr>3  s     ?qQUU6]h%>?   ##c              3  J   K   | ]  }|j                  d       dk(  sd  ywrT  rU  rD   s     r   rG   zbuild_legend.<locals>.<genexpr>4  s     AquuV}'@1ArV  zskills (r  )r   r   r   z
memories ()rC   r%  r   r   r   r   )r  rZ   r   r   s       r   build_legendrX  1  sd    KK$E?E??FAeAAHPQ>RS*XJVW@XY r    c                    t        t        | j                  dg                   }|d   sdddS t        |j                  d            t        |j                  d            dS )NrZ   rQ   oldestnow)startendrR   rS   )rd   r>  rC   r?   )r  r.   s     r   axis_labelsr^  ;  sU    
$w{{7B78
9Cw<!%00 !12;swwwGW;XYYr    c                   i i }| j                  dg       D ]H  }t        |j                  d            }| t        |d      }j                  |d      dz   |<   |||<   J sy t        fd      }dt	        ||   d       d	|    d
S )NrZ   rB   r9   r   r)   c                    |    S r   r   r  s    r   rN   z_peak_day.<locals>.<lambda>N  r  r    rO   zbusiest day r   z learned)rC   r   r   rU   r   )r  repsr   r=   rP   bestr  s         @r   	_peak_dayrc  B  s    )+F)+DGR( DHH[)*:"e$jja(1,sS	 v./D-T
E:;4t~XVVr    c                   | j                  di       xs i }g }|j                  d|j                  dd            }|j                  dd      }|j                  dd      }|j                  | d| d| d	       g }|j                  d
      r|j                  |d
    d       t        |       }|r|j                  |       |r |j                  dj                  |             |S )Nstatslearned_skillsrZ   r   memory_nodesrelated_edgesu    learned skills · u    memories · z skill linksmemory_skill_edgesu    memory↔skill linksr   )rC   r   rc  ru   )r  re  lineslearnedmemedgesextrapeaks           r   build_summaryrp  R  s    KK$*EEii(%))GQ*?@G
))NA
&CIIoq)E	LLG9/uM%UVEyy%&2344IJKWDTV[['(Lr    c                   g }| D ]  }|d   |d   t        |      dkD  r|d   nd}}}t        |      dkD  r|d   nd }|rt        |d         dkD  r|d   d   nd }|r8|d   d   |k(  r-t        |d   d   |z
        dk  r||k(  r|d   dxx   |z  cc<   |||g}|r|j                  |       |j                  |        |S )Nr   r)   r%   r#   r$   gư>)rW   r   r   )	r,  r   runr   r   r:  hex_overrideprev_hexmergeds	            r   _merge_runsrw  d  s    C 
 VSVC1c!f#Ue!$SAs1v4!$SW)93r71:t3r71:&3s2wqzE/A+BT+IhZfNfGAJ$J.Fl+JJv
 Jr    0   )r0  r  framesc                  t        dt        |d            }t        | j                  dg             }t	        |      }|rt        ||t        d|dz
              ng }g }t        |      D ]L  }||dz
  z  }	t        | |||	      }
|j                  |
d	   |
d
   |
d   |
d   |
j                  dg       d       N |t        |       t        |       t        ||       t        |       t        |       t        | j                  dg             ||d	S )uI   Pre-render a full play-through (reveal 0→1) plus static legend/summary.r%   r   rZ   ro   r$   r5  r)   r/  rg   r   r)  r4  r=  )rg   r   r)  r4  r=  )	ry  legend
categoriesr   summaryaxisr   r0  r  )rU   rT   r>  rC   rd   r   r   rQ  r   rX  r  r  rp  r^  rW   )r  r0  r  ry  rZ   r.   r   
out_framesr`   rg   frames              r   render_framesr  t  s   C$%FWb)*E
%
 C NS"5#Atax8HIXZGJ6] 
fqj!W4d6J/f +f))Hb1	

 w'%g.1 )G$W[["-.
 
r    )r   r   r   Optional[float])r   r   r   r   r   r   r   r   )r&   r   r   r   )r.   r   r   r   )r=   r  r   rM   )rZ   list[dict[str, Any]]r   dict[str, Any])r.   r  rg   r   r   r  )rx   rM   r   tuple[int, int, int])rl   r   r   rM   )r   r   r   r   r/   r   r   r  )rl   r   r   ztuple[float, float, float])r   r   rx   r   r   r   r   r  )rl   r   r   r  )r   rM   r   boolr   dict[str, str])r   r  r.   r   r   r   )r   r  r   rM   )r=   r   r   rM   r   ztuple[int, ...])r=   r   r   rM   r   rM   )rZ   r  r.   r  r   rv   r   list[_ChartBucket])r   r   r   zOptional[dict[str, Any]]r   )r   r   r   z#Optional[dict[str, dict[str, Any]]]r   r  )r   r  r  r  r   r  )r  r  r   zlist[tuple[str, int]])r  r  r   r  )ro   )r  r  r  rv   r   r  )r   r   r   Optional[str])r   r  r(  rv   rg   r   r   Row)
r  r  r0  rv   r  rv   rg   r   r   r  )r  r  r   r  )r  r  r   r  )r  r  r   z	list[str])r,  zIterable[Run]r   r  )
r  r  r0  rv   r  rv   ry  rv   r   r  )@__doc__
__future__r   rK   r   r   typingr   r   r   rY   r+   r,   r-   r*   rA  r   r   r'  r?  r   r   r   r@  r>  Runr  Gridr   r   r'   r0   r?   rd   rh   ry   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r  r   r-  rQ  rX  r^  rc  rp  rw  r  r   r    r   <module>r     s^   #  ' * *  
 	 N#

1
bJ<8ND
"L(F
 6: "UC

 + + @Fm,4B"sRDU. :<]` dTZW $  ;="\^ r    