
    Iji                       d Z ddlmZ ddlZddlmZ ddlZddlZddlm	Z	 ddl
mZ ddlmZmZmZmZ  e	e      j%                         j&                  d   Zed	z  Zd d!d
Zefd"dZefd#dZefd#dZefd#dZefd#dZd$dZd%dZd&dZd'dZd(d)dZ d*dZ!d+dZ"d,dZ#efd-dZ$d.dZ%d.dZ&d/d0dZ'defd1dZ(edfd2dZ)d3dZ*e+dk(  r e*        yy)4z?Summarize the next active-nearest transition review components.    )annotationsN)defaultdict)Path	urlencode)bounds_textcomponent_groupspatch_file_stem
review_key   outc                "    | dt        |        S )Nz/game.html?r   )params
web_prefixs     B/home/exedev/hwanse/tools/summarize_transition_review_shortlist.pyweb_hrefr      s    \Yv%6$788    c                    | j                  d      }t        t        |t              xr ||z  j	                               S )NconfirmNearestPatch)getbool
isinstancestrexistsrowout_dirrels      r   patch_existsr      s5    
'''
(C
3$A'C-)?)?)ABBr   c                v    | j                  d      }t        |t              syt        | |      rd| dS d| dS )Nr   -z[confirm nearest]()`z` (not generated))r   r   r   r   r   s      r   markdown_patch_cellr$      sG    
'''
(Cc3C!#C5**se$%%r   c                P    | j                  d      }|syt        | |      syd| dS )NdryRunCommandr!   zpatch preview onlyr#   )r   r   r   r   commands      r   markdown_dry_run_cellr)   %   s1    ggo&GW%#wiq>r   c                    | j                  d      }t        |t              syt        j                  |      }t        | |      rd| dS d| dS )Nr   r!   z	<a href="z">confirm nearest</a><code>z5</code><br><span class="missing">not generated</span>)r   r   r   htmlescaper   )r   r   r   escapeds       r   html_patch_cellr/   .   sV    
'''
(Cc3kk#GC!7)#899G9QRRr   c                v    | j                  d      }|syt        | |      sydt        j                  |       dS )Nr&   r!   z/<span class="missing">patch preview only</span>r+   z</code>)r   r   r,   r-   r'   s      r   html_dry_run_cellr1   8   s<    ggo&GW%@DKK()11r   c           	     ,   | j                  d      xs g }|sy |d   \  }}t        | d   ||| d   | j                  d      xs | j                  d      xs d      }|| d   ||| d   dd	d
D ci c]  }| j                  |      || |    c}iS c c}w )NactiveReviewPointsr   sourcetargetrecordVaHexrecordVarecord	confirmed)r4   xyr5   state)r7   r6   sceneId
sceneIdHex	eventKindtargetSceneIdtargetSceneIdHex)r   r   )	componentpointsr:   r;   keyfields         r   patch_recordrF   A   s    ]]/06BF!9DAq
(		(m$M	j(AMXC 	)) 
 D=='3 y''
 s   .Bc                    i }| xs i j                  d      xs g D ]5  }|j                  d      xs g D ]  }|j                  d      }|s|||<    7 |S )NclusterseventRecordsr6   r   )field_map_rootsindexclusterevent	record_vas        r   
root_indexrP   ]   sj    E#)r..z:@b +[[06B 	+E		-0I#*i 	++
 Lr   c                Z   g }| xs i j                  d      xs g D ]  }|j                  d      xs i }|j                  d      xs g }|j                  d      xs g }|sE|j                  d      du sY|j                  |j                  d      |j                  d      ||d	        |S )
NmanifestRecordsrenderacceptedTilesetsrecordTilesetsmatchesAcceptedFmapr6   )rW   r6   rU   rT   )r   append)rM   rowsr8   rS   acceptedcurrents         r   render_mismatchesr\   g   s    D=b%%&78>B 
H%+::017R**-.4"

#45>KKzz%(%zz-8")$,	 
 Kr   c           	        | j                  d      }| j                  d      dk7  | j                  dd      |dn|| j                  dd       | j                  d	      xs d
| j                  d      xs d
| j                  d      xs d
fS )NactiveDistancerootClassificationstrict event-linked clusterrootRenderMismatchCounti  i'  unreviewedStandableCountr   r4    r6   r5   rJ   )r   active_distances     r   row_priorityre   w   s    gg./O$%)FF)3/'_	+Q	//R$"R r   c                   g }t        |      }t        |       D ]:  }|j                  dd      dk  r|j                  d      s,|d   d   \  }}|j                  d      xs t        |j                  d      xs d      }|j                  |j                  d            }	t	        |	      }
|j                  i d|d   d|d   d|j                  d      d	|j                  d	      d
|j                  d
      d|j                  d      d|d   d   |d   d   |d   d   |d   d   dd|j                  d      d|j                  dd      d|j                  dd      d|	r|	j                  d      nd d|	r|	j                  d      nd d|	r|	j                  d      nd d|	r|	j                  d      ng d|	r|	j                  d      ng dt        |
      d|
||dt        |d   d d | d!| | d!| |d   |d"      t        |d   d#| d!| |d   |d$      d%t        |d&d'       d(d)t        |d&d'       d*t        |      d+       = t        |t        ,      d | S )-Nrb   r   r3   r6   r7   r8   r4   r5   r>   r?   rA   boundsr         )minXminYmaxXmaxYr^   standableCountrootClusterStartHexclusterStartHexrootClusterEndHexclusterEndHexr_   classificationrootManifestMapsmanifestMapsrootEventSourceseventSourcesra   rootRenderMismatchesr:   r;   1,)rW   eventsoverview	startTile	focusTiletransitionTargettransitionRecordactiveNearest)rW   trialTransitionsr~   r   r   ztransition_review_patches/r9   Tz.jsonzJpython3 tools/transition_reviews.py --merge out/transition_review_patches/z.json --dry-run)activeReviewPoint	reviewUrltrialUrlr   r&   confirmNearestPatchPreviewrD   )rP   r	   r   r   r\   rX   lenr   r
   rF   sortedre   )gap_rowslimitrK   rY   roots_by_recordrB   r:   r;   r8   root
mismatchess              r   
build_rowsr      s1   D 1O%h/ 7	==3Q71<}}12-.q11}-[Y]]:5N5ZRZ1[""9==#?@&t,
 .
i).
i).
 9==7.
 )--5	.

 {3.
 	.@ A.
 !(+A.!(+A.!(+A.!(+A.	.
 imm,<=.
 imm,<a@.
 '	6PRS(T.
  "$488,=#>D!.
"  d/!:#.
$ !$((+;"<$%.
& D 8b'.
( D 8b).
* &s:+.
, #J-.
. ()q!1! * !s!A3Z !s!A3Z$-h$7$*#  ! *$3 !s!A3Z$-h$7$*"  &@PY[fhl@m?nns#t11@KY]1^0__np +7y*A[.
 .	7p $L)&511r   c                r    | j                  d      xs i }|j                  d      |j                  d      dS )Nr   r:   r;   ry   rJ   )r   points     r   active_pointr      s6    GG'(.BEYYs^YYs^ r   c                t   t        t              }| D ]a  }t        |      }||j                  d      |j                  d      |j                  d      |j                  d      f   j	                  |       c g }|j                         D ]  \  \  }}}}}	t        |	      dk  r|j	                  ||||dt        |	      t        d |	D ch c]  }|j                  d       c}D              t        d	 |	D ch c]  }|j                  d
       c}D              d        t        |d       S c c}w c c}w )Nr4   r5   r:   r;   r   ry   c              3  $   K   | ]  }|r| 
 y wN ).0r8   s     r   	<genexpr>z7duplicate_source_target_point_groups.<locals>.<genexpr>   s          r6   c              3  $   K   | ]  }|r| 
 y wr   r   )r   r   s     r   r   z7duplicate_source_target_point_groups.<locals>.<genexpr>   s      ( (r   ro   )r4   r5   r   rowCountrecordsrootClusterStartsc                    | d    | d   xs d| d   xs d| d   j                  d      | d   j                  d      nd| d   j                  d      | d   j                  d      fS dfS )	Nr   r4   rc   r5   r   r;   r:   rJ   )groups    r   <lambda>z6duplicate_source_target_point_groups.<locals>.<lambda>   s    :(O!r(O!r389L3M3Q3QRU3V3bE%&**3/hj389L3M3Q3QRU3V3bE%&**3/
 
 ik
 r   r   )r   listr   r   rX   itemsr   r   )
rY   groupedr   r   duplicate_groupsr4   r5   r:   r;   
group_rowss
             r   $duplicate_source_target_point_groupsr      sA   '24'8G dS!"CGGH$5uyy~uyyQT~VW^^_bcd .5mmo *A
z?a'(q!1J AKL#sww}5L 
 "( (GQRSWW%:;R( "!
 	& 
	 	 M
 Ss   D06D5c                   g }| D ]  }|j                  d      }t        |t              r||z  nd }t        |xr |j	                               }d}|r;|r9t        j                  |j                  d            }||j                  d      k(  }t        |      }	|j                  |j                  d      |j                  d      |j                  d      |	|||d	        |S )
Nr   Futf-8encodingr   r4   r5   r6   )r4   r5   r6   r   patchpatchExistspreviewMatchesPatch)
r   r   r   r   r   jsonloads	read_textr   rX   )
rY   r   checksr   r   
patch_pathr   preview_matches_patchr   r   s
             r   patch_preview_checksr      s    F gg+,&0c&:Ws]
J>:+<+<+>? %,JJz33W3EFE$)SWW5Q-R$R!S!ggh'ggh'77=1!&'#8
 	$ Mr   c                   t        |       }t        | |      }| D ch c]$  }|j                  d      |j                  d      f& }}| D ch c]%  }|j                  d      s|j                  d      ' }}| D ch c]%  }|j                  d      s|j                  d      ' }}t        d | D              }t        d | D              }	t        d | D              }
t        d |D              }t        d |D              }t        d	 |D              }t        d
 | D              }| r| d   ni }i dddt	        |       dt	        |      dt	        |      dt	        |      d|	d|d|
d|dt	        |      d|dt	        |      d|dt	        |      |z
  d|d|d|r|j                  d      |j                  d      |j                  d      |rt        |      nd |j                  d      |j                  d      |j                  d       |j                  d!      d"nd d#d$d%g d&d'S c c}w c c}w c c}w )(Nr4   r6   r5   c              3  J   K   | ]  }|j                  d       dk(  sd  yw)ra   r   r   NrJ   r   r   s     r   r   zbuild_audit.<locals>.<genexpr>  s"     #a#AZ9[_`9`A#a   ##c              3  J   K   | ]  }|j                  d       dk(  sd  yw)r_   r`   r   NrJ   r   s     r   r   zbuild_audit.<locals>.<genexpr>  s"     jC3773G+HLi+iajr   c              3  J   K   | ]  }|j                  d       dk(  sd  yw)r^   r   r   NrJ   r   s     r   r   zbuild_audit.<locals>.<genexpr>  s!     O8H0IQ0N1Or   c              3  D   K   | ]  }|j                  d       sd  yw)r   r   NrJ   r   s     r   r   zbuild_audit.<locals>.<genexpr>  s     KSCGGM4JqK     c              3  h   K   | ]*  }|j                  d       s|j                  d      s'd , ywr   r   r   NrJ   r   s     r   r   zbuild_audit.<locals>.<genexpr>  s*     qsww}7MRURYRYZoRp!q   222c              3  h   K   | ]*  }|j                  d       s|j                  d      r'd , ywr   rJ   r   s     r   r   zbuild_audit.<locals>.<genexpr>  s*     x3#''-:PY\Y`Y`avYwQxr   c              3  D   K   | ]  }|j                  d       rd  yw)rA   r   NrJ   r   s     r   r   zbuild_audit.<locals>.<genexpr>  s     TS@R8SqTr   r   	objectivez;root-aware active-nearest transition review shortlist auditr   sourceCounttargetCountrecordGroupCountstrictEventLinkedRowszeroRenderMismatchRowsactiveDistanceZeroRowsmissingTargetSceneRows$duplicateSourceTargetPointGroupCount duplicateSourceTargetPointGroupspatchPreviewCheckCountpatchPreviewFilesPresentpatchPreviewMissingFileCountpatchPreviewMatchespatchPreviewMismatchCountfirstCandidatero   r_   ra   r&   )r4   r5   r6   r   ro   r_   ra   r&   zmanual-review-onlyznot-auto-confirmedz\none until a reviewer merges a confirmed transition review into data/transition_reviews.json)zaShortlist rows are generated from unreviewed standable components and are not normal-route proof.zgDuplicate source/target/active-point groups mean multiple EXE records still need manual discrimination.z{Confirm-nearest patches are dry-run merge inputs; they do not change data/transition_reviews.json unless explicitly merged.)
reviewModepromotionStatusnormalRouteImpactcautions)r   r   r   sumr   r   )rY   r   r   patch_checksr   unique_record_groupsunique_targetsunique_sourceszero_render_mismatch_rowsstrict_rowsactive_zero_rowsr   preview_matchespreview_mismatchesmissing_target_scenefirsts                   r   build_auditr     s   ;DA'g6L  
	CGGM23  48MC3778;Lcggh'MNM37MC3778;Lcggh'MNM ##a#a aj4jjKOOOKLKKLq|qqOx,xxTDTTDGE#R#CI# 	s>*# 	s>*	#
 	C 45# 	 # 	!";# 	!"2# 	!"6# 	/4D0E# 	+,<# 	!#l"3# 	#L# 	'L(9L(H# 	#  	$%7!#" 	  ii)ii) 99]38=e!44#(99-B#C"')),@"A',yy1J'K"YY7	
 5#6 +/{
=# # NMs   )H1H6"H6;H;H;c                l   ddd| d    d| d    dd| d	    dd
| d    dddg	}dD ]*  }|j                  d| d| j                  |d       d       , | j                  d      xs i }|j                  d      xs i }|j                  dddd|j                  d       d|j                  d       dd|j                  d       d|j                  d       dd|j                  d       d |j                  d!       dd"|j                  d#       d$|j                  d%       d&|j                  d'       ddd(dg       |j                  d) | j                  d*      xs g D               |j                  g d+       | j                  d,      xs g D ]i  }|d   }|j                  d|d    d|d    d|d    d|d    d|d-    dd.j                  |d/         xs d0 dd.j                  |d1         xs d0 d       k | j                  d,      s|j                  d2       d3j                  |      d3z   S )4Nz## Transition Review Shortlist Auditrc   z- objective: r   - review mode: `r   r#   - promotion status: `r   z- normal route impact: r   z| metric | value |z| --- | ---: |r   r   r   r   r   r   r   r   r   r   r   r   r   r   |  | r    |r   r   z## First Candidatez- source/target: `r4   z` -> `r5   z- active point: `r:   r{   r;   z- record/root: `r6   z` / `ro   z- root: r_    with render mismatches ra   z- dry-run: `r&   z## Cautionsc              3  &   K   | ]	  }d |   yw)z- Nr   r   items     r   r   z!audit_markdown.<locals>.<genexpr>i  s     E2dVEs   r   )rc   z.## Duplicate Source/Target/Active-Point Groupsrc   z;| source | target | active point | rows | records | roots |z&| --- | --- | --- | ---: | --- | --- |r   r   , r   r!   r   z| - | - | - | - | - | - |
)rX   r   extendjoin)auditlinesrD   r   r   r   s         r   audit_markdownr   =  s   -

k*+,
5./q1
&7 89;
!%(;"<!=>

E 9  	r#c%))C"3!4B78!9" II&'-2EII)*0bE	LL


UYYx01		(8K7LAN
EIIcN+1UYYs^,<A>
599]34E%))DY:Z9[[\]
5991233KEIIVoLpKqr
uyy12!4

  
LLE:)>)D"EE	LL   =>D" 
)*x!U8_$5SsAeCj\QTZ !TYYuY/?%@%GC$Hyy234;<B@	

 99780199Ud""r   c                T    dj                   fddD              } j                  d      xs i }|j                  d      xs i }dj                  d  j                  d      xs g D              }dj                  d  j                  d	      xs g D              }dj                  g d
ddddddddddt        j                   d          dt        j                   d          dt        j                   d          ddt        j                   d          dd|dd d!d"t        j                  t	        |j                  d#                   d$t        j                  t	        |j                  d%                   d&d'|j                  d(       d)|j                  d*       d&d+t        j                  t	        |j                  d,                   d-t        j                  t	        |j                  d.                   d&d/t        j                  t	        |j                  d0                   d1|j                  d2       d3d4t        j                  t	        |j                  d5                   d&d6d7d!| d8d9d:|xs d;dd<d=d>      S )?Nr   c              3  v   K   | ]0  }d t        j                  |       dj                  |d       d 2 yw)<tr><td>	</td><td>r   
</td></tr>N)r,   r-   r   )r   rD   r   s     r   r   z"audit_html_page.<locals>.<genexpr>~  s>       4;;s#$IeiiQ.?-@
Ks   69r   r   r   c              3  N   K   | ]  }d t        j                  |       d  yw)z<li></li>N)r,   r-   r   s     r   r   z"audit_html_page.<locals>.<genexpr>  s#     f$T[[%6$7u=fs   #%r   c              3  f  K   | ]  }d t        j                  |d          dt        j                  |d          d|d   d    d|d   d    d|d    dt        j                  d	j                  |d
         xs d       dt        j                  d	j                  |d         xs d       d  yw)r   r4   r   r5   r   r:   r{   r;   r   r   r   r!   r   r   N)r,   r-   r   )r   r   s     r   r   z"audit_html_page.<locals>.<genexpr>  s      
 	{{5?+, -{{5?+, -()#./q7J1KC1P0Q RZ ! "{{499U9%56=#>? @{{499U+>%?@GCHI J	
s   B/B1r   <!doctype html><html lang="en"><head>  <meta charset="utf-8">F  <meta name="viewport" content="width=device-width, initial-scale=1">z2  <title>Transition Review Shortlist Audit</title>a4    <style>body{font-family:system-ui,sans-serif;background:#111;color:#ddd;margin:24px;max-width:1200px}a{color:#8fd3ff}table{border-collapse:collapse;width:100%;margin:12px 0 20px}td,th{border:1px solid #333;padding:6px 8px;text-align:left;vertical-align:top}th{background:#1f1f1f}code{color:#f5d76e}</style></head><body>z,  <h1>Transition Review Shortlist Audit</h1>z  <p>r   z. Review mode: <code>r   !</code>. Promotion status: <code>r   z</code>.</p>z  <p>normal route impact: r   z</p>zE  <table><thead><tr><th>metric</th><th>value</th></tr></thead><tbody>z  </tbody></table>z  <h2>First Candidate</h2>  <ul>z    <li>source/target: <code>r4   z -&gt; r5   z</code></li>z    <li>active point: <code>r:   r{   r;   z    <li>record/root: <code>r6   z / ro   z    <li>root: r_   r   ra   r   z    <li>dry-run: <code>r&     </ul>z  <h2>Cautions</h2>z</ul>z6  <h2>Duplicate Source/Target/Active-Point Groups</h2>z  <table><thead><tr><th>source</th><th>target</th><th>active point</th><th>rows</th><th>records</th><th>roots</th></tr></thead><tbody>z2<tr><td colspan="6">No duplicate groups.</td></tr></body></html>rc   )r   r   r,   r-   r   )r   metric_rowsr   r   caution_itemsduplicate_rowss   `     r   audit_html_pager  }  s   )) 
 K& II&'-2EII)*0bEIIf%))T^J_JeceffMYY 
 YYABHb
 
N 99 !!! 	! 	#	!
 	Q! 	=! 	! 	! 	! 	7! E+./00EdkkRWXdReFfEg  hI  JN  JU  JU  V[  \m  Vn  Jo  Ip  p|  	}! %T[[7J1K%L$MTR! 	P! 	! 	!  	%!!" 	#!$ (C		(8K4L(M'NgVZVaVabefkfofopxfybzV{U|  }I  	J%!& 'uyy~&6a		#7G|T'!( &dkk#eii6N2O&P%QQTUYU`U`adejenen  pE  fF  bG  VH  UI  IU  	V)!* S3G)H%IJKKcdidmdm  oH  eI  dJ  JO  	P+!, "$++c%))O2L.M"N!O|\-!. 	/!0 	1!2 u%3!4 	A5!6 	Q7!8 	NN9!: 	;!< 	=!> 	?!@ 	A! ! !r   c                   g d}| D ]?  }|d   }|j                  dj                  g d|d    d|d    d|d    d	|d
    d|j                  d      |j                  d      nd d|j                  dd       d|j                  d      xs d d|j                  d      xs d d|j                  dd       d|j                  d      xs d d|j                  d      xs d d|j                  d      xs d d|d    d|d    dt        |       dt	        |       d             B | s|j                  d       |rm|j                  dddd |d!    d"d#|d$    d"d%|d&    d'|d(    d'|d)    d'|d*    d+|d,    d'|d-    d'|d.    d/|d0    d1|d2    d'|d3    d4|d5    d6dd7g       d8j                  |      d8z   S )9N)z# Transition Review Shortlistrc   zActive-nearest, source-standable transition components to inspect next. These are review targets, not auto-confirmed transitions.rc   z| source | target | active point | dist | standable | root | render mismatches | scene | target scene | record | review | trial | patch | dry-run |zX| --- | --- | --- | ---: | ---: | --- | ---: | --- | --- | --- | --- | --- | --- | --- |r   rc   r   r4   r   r5   r:   r{   r;   r^   r!   rb   r   r_   z `ro   z` | ra   r>   rA   z | `r6   z` | [review](r   z) | [trial](r   z) | r   z9| - | - | - | - | - | - | - | - | - | - | - | - | - | - |z## Shortlist Auditr   r   r#   r   r   z - rows/sources/targets/records: r   /r   r   r   z'- strict/zero-render/active-zero rows: r   r   r   z/- duplicate source-target active-point groups: r   z1- patch previews matching generated patch files: r   r    present; missing files r   zv- normal route impact: none until a reviewer merges a confirmed transition review into `data/transition_reviews.json`.z4[full audit](transition_review_shortlist_audit.html)r   )rX   r   r   r$   r)   r   )rY   r   r   r   r   s        r   markdownr    s   E  
'(K Kb KX Ks K3x=/ K KU3ZL K K%* KS K,/GG4D,E,Qsww'(WZ[K[^Kww1156K69K ww+,34K 57K 8;ww?T7U7\Y\6]K ^bK ww0!45	K 69	K :=9N9URU8V	K WZ	K
 ww)*1c2K
 37K
 8;ww}7M7TQT6UK
VK K()K *6K 7:*o5FK GKK #3'(K ),K -B#,F+GK HJK		

 PQ u\2315#E*;$<#=Q?.uZ/@.A5CWBXXYZ_`mZnYoopqv  xJ  rK  qL  M5e<S6T5UUVW\]uWvVwwxy~  @X  zY  yZ  [=eDj>k=lm?F[@\?]]^_de  `A  _B  BZ  [`  a  [@  ZA  B EB
 	 99Ud""r   c                   g }| D ]  }|d   }|j                  dj                  g dt        j                  |d          dt        j                  |d          d|d    d|d	    d|j	                  d
      |j	                  d
      nd d|j	                  dd       dt        j                  |j	                  d      xs d       dt        j                  |j	                  d      xs d       d|j	                  dd       dt        j                  |j	                  d      xs d       dt        j                  |j	                  d      xs d       dt        j                  |j	                  d      xs d       dt        j                  |d          dt        j                  |d          dt        ||       dt        ||       d              d}|rdj                  ddt        j                  |d           d!t        j                  |d"          d#d$d%|d&    d'|d(    d'|d)    d'|d*    d+	d,|d-    d'|d.    d'|d/    d+d0|d1    d+d2|d3    d'|d4    d5|d6    d+d7d8g	      }dj                  d9d:d;d<d=d>d?d@dAdBdC|dDdEdj                  |      xs dF dGdHdIdg      S )JNr   rc   r   r4   r   r5   r:   r{   r;   r^   r!   rb   r   r_   z
<br><code>ro   z</code></td><td>ra   r>   rA   z</td><td><code>r6   z</code></td><td><a href="r   z">review</a></td><td><a href="r   z">trial</a></td><td>r   r   z  <h2>Shortlist Audit</h2>z  <p>Review mode: <code>r   r  r   zy</code>. Normal route impact: none until a confirmed review is merged into <code>data/transition_reviews.json</code>.</p>r  z&    <li>rows/sources/targets/records: r   r  r   r   r   r   z-    <li>strict/zero-render/active-zero rows: r   r   r   z5    <li>duplicate source-target active-point groups: r   z7    <li>patch previews matching generated patch files: r   r   r  r   zL    <li><a href="transition_review_shortlist_audit.html">full audit</a></li>r  r   r   r  r  r  z,  <title>Transition Review Shortlist</title>a$    <style>body{font-family:system-ui,sans-serif;background:#111;color:#ddd;margin:24px}a{color:#8fd3ff}table{border-collapse:collapse;width:100%}td,th{border:1px solid #333;padding:6px 8px;text-align:left;vertical-align:top}th{background:#1f1f1f}code{color:#f5d76e}.missing{color:#999}</style>r  r  z&  <h1>Transition Review Shortlist</h1>z  <p>Active-nearest, source-standable transition components to inspect next. These are review targets, not auto-confirmed transitions.</p>a    <table><thead><tr><th>source</th><th>target</th><th>active point</th><th>dist</th><th>standable</th><th>root</th><th>render mismatches</th><th>scene</th><th>target scene</th><th>record</th><th>review</th><th>trial</th><th>patch</th><th>dry-run</th></tr></thead>z	  <tbody>z1<tr><td colspan="14">No shortlist rows.</td></tr>z</tbody></table>r	  r
  )rX   r   r,   r-   r   r/   r1   )rY   r   r   bodyr   r   
audit_htmls          r   	html_pager    s   D 
'(   ;;s8}-./;;s8}-./ :,   !&c
|, 148H0I0U377+,[^_	`	
 775q9:
; ;;sww';<CDE FP QUP[P[\_\c\cdy\z  ]B  B  QC  PDD 774a89: ;;sww|4;<=> ;;sww'9:AcBCD SWW]%;%BsCDE !KKK(89:; !KKJ89: #3012 %S'234	

( JYY(&t{{53F'G&HHijnjujuv{  }N  wO  kP  jQ  QJ  K4U:5F4Gq}I]H^^_`efs`t_uuvw|  ~P  xQ  wR  RW  X;EBY<Z;[[\]bc{]|\}}~  @E  F^  @_  `  `e  fCEJpDqCrrwxEeLaFbEccdej  lF  fG  eH  H`  af  gE  aF  `G  GL  MZ
 
 

 99"P6 	o0 	U 	R
BGGDMZ%Z[[kl
#  r   c                   |j                  dd       t        | |      }|dz  j                  t        j                  | dd      dz   d	       |;|j
                  j                  dd       |j                  t        | ||      d	       |d
z  j                  t        j                  |dd      dz   d	       |dz  j                  t        |      d	       y )NT)parentsexist_ok transition_review_shortlist.jsonF)r{   :)ensure_ascii
separatorsr   r   r   z&transition_review_shortlist_audit.jsonz&transition_review_shortlist_audit.html)mkdirr   
write_textr   dumpsparentr  r  )rY   r   html_outr   s       r   write_outputsr#  $  s    MM$M.g&E11==

4e
CdJ >  dT:IdE7;gN77CC

5uDtK D  77CCOTYDZelCmr   c                    t        j                  t              } | j                  dt        t
        dz         | j                  dt        t
        dz         | j                  dt        d       | j                  d	t        t
               | j                  d
t        d d       | j                         }|j                  j                         r/t        j                  |j                  j                  d            nd }|j                  j                         rEt        t        j                  |j                  j                  d            |j                  |      }nR|j                   dz  j                         r3t        j                  |j                   dz  j                  d            }ng }t#        ||j                   |j$                         t'        dt)        |       d|j                   dz          y )N)descriptionz--gapsztransition_review_gaps.json)typedefaultz--field-map-rootszfield_map_record_roots.jsonz--limit   z	--out-dirz
--html-outz$Optional shortlist HTML output path.)r&  r'  helpr   r   r  zwrote z% transition review shortlist rows -> )argparseArgumentParser__doc__add_argumentr   OUTint
parse_argsrK   r   r   r   r   gapsr   r   r   r#  r"  printr   )parserargsrootsrY   s       r   mainr6  5  s   $$9F
tS;X5XY
+$Fc@cd
	R8
$<
4DjkDLPL`L`LgLgLiDJJt++55w5GHosEyy$**TYY%8%8'%8%JKTZZY^_
,,;
;	C	C	Ezz4<<*LLWWahWij$dmm4	F3t9+B4<<RtCtBu
vwr   __main__)z../web)r   zdict[str, str]r   r   returnr   )r   dictr   r   r8  r   )r   r9  r   r   r8  r   )rB   r9  r8  dict | None)rK   r:  r8  zdict[str, dict])rM   r:  r8  
list[dict])r   r9  r8  tuple)r(  N)r   r;  r   r/  rK   r:  r8  r;  )r   r9  r8  r9  )rY   r;  r8  r;  )rY   r;  r   r   r8  r;  )rY   r;  r   r   r8  r9  )r   r9  r8  r   r   )rY   r;  r   r:  r8  r   )rY   r;  r   r:  r   r   r8  r   )rY   r;  r   r   r"  zPath | Noner8  None)r8  r=  ),r,  
__future__r   r*  collectionsr   r,   r   pathlibr   urllib.parser   transition_reviewsr   r	   r
   r   __file__resolver  ROOTr.  r   r   r$   r)   r/   r1   rF   rP   r\   re   r   r   r   r   r   r   r  r  r  r#  r6  __name__r   r   r   <module>rG     s   E "  #    " Y Y H~''*
Ul9 -0 C
 47 & 69  03 S 25 28 
;2|"J. 36 4n=#@CL&#R 6:3 5p 58QU n"x& zF r   