
    UHjGA                    l   d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	  ee
      j                         j                  d   Zedz  ZddZdd	Zdd
ZddZddZddZ	 	 	 	 	 	 	 	 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e dk(  r e        yy)+zBSummarize reverse-transition candidates for confirmed map entries.    )annotationsN)Path)Any   outc                p    | j                         s|S t        j                  | j                  d            S )Nutf-8encoding)existsjsonloads	read_text)pathfallbacks     G/home/exedev/hwanse/tools/summarize_reciprocal_transition_candidates.py	load_jsonr      s*    ;;=::dnngn677    c                R    | sy| j                  d       d| j                  d       S )N-x,yget)points    r   
point_textr      s+    iinQuyy~.//r   c                .    t        fd| D        i       S )Nc              3  L   K   | ]  }|j                  d       k(  s|  yw)mapNr   ).0rownames     r   	<genexpr>zmap_exit_row.<locals>.<genexpr>   s      ?$(>?s   $$)next)rowsr#   s    `r   map_exit_rowr'      s    ??DDr   c                ,    | j                  d      xs i S )Nsampler   )	candidates    r   r)   r)       s    =="(b(r   c                h    | j                  d      xs g D ]  }|j                  d      |k(  s|c S  y )NtargetHintstargetr   )r*   r-   hints      r   hint_forr/   $   s:    m,2 88H'K r   c                   |r t        |t              rt        |t              sy | j                  d      xs g D ]O  }t        |      }|j                  d      |k(  s#|j                  d      |k(  s8|j                  d      |k(  sM|c S  y )NexitCandidatessider   r   )
isinstanceintr   r)   )r"   r2   r   r   r*   r   s         r   candidate_atr5   +   s}    z!S)As1CWW-.4" 	y!== D(UYYs^q-@UYYs^WXEX r   c                    | j                  |      xs i }|j                  d      xs g D cg c].  }||j                  d      xs |j                  d      xs g v r|0 c}S c c}w )Nrecordstargets	fieldMapsr   )save_selector_scene_linkssourcer-   entryrecords        r   selector_recordsr>   5   sm    
 &))&17RE ii	*0bfjj+Lvzz+/FL"M 	  s   3A#c                    | D cg c]/  }|j                  d      |k(  r||j                  d      xs g v r|1 c}S c c}w )Nr    r8   r   )event_transitionsr;   r-   r"   s       r   strict_event_recordsrA   B   sI     %775>V#37793E3K(L 	  s   4<c                    | j                         D cg c]@  }|j                  d      |k(  r*|j                  d      |k(  r|j                  d      dk(  r|B c}S c c}w )Nr;   r-   state	confirmed)valuesr   )reviewsr;   r-   reviews       r   confirmed_reviewsrH   J   s^     nn&::h6)JJx F*JJw;.	 	  s   AAc                |   t        | |      }t        | |      }g }|j                  d      xs g D ]  }t        |      }t        ||      }|st	        ||j                  d      |j                  d      |j                  d            }	|	rt        |	xs i |      nd }
d}|
rm|
j                  d      |j                  d      k(  xrH |
j                  d      |j                  d      k(  xr# |
j                  d      |j                  d      k(  }|j                  |j                  d      |j                  d      |j                  d      |j                  d      |j                  d      |j                  d      dk(  |j                  d      |j                  d      |j                  d      |j                  d      |j                  d      |j                  d	      |j                  d
      |j                  d      d||j                  d      |j                  d      d
        |j                  d        |S )Nr1   r2   r   r   F	standableedgeDistancer   autoTriggerprojectionDelta	sideMatch)r2   r   r   rJ   rK   rL   rM   rN   	reviewUrltrialUrl)
r2   r   r   rJ   rK   rL   
targetHintreciprocalHintrO   rP   c                F   | j                  d       | j                  d       | j                  d      | j                  d      nd| j                  d      xs d| j                  d      | j                  d      nd| j                  d      | j                  d      fS dfS )	NrR   rL   rK   i  r2    r   r   r   )r"   s    r   <lambda>z)reverse_exit_candidates.<locals>.<lambda>{   s    GG$%%GGM""#&77>#:#FC20c0  7: r   )key)r'   r   r)   r/   r5   appendsort)map_exit_candidatesr;   r-   
source_row
target_rowr&   r*   r   r.   hinted_candidatereverse_hint
reciprocals               r   reverse_exit_candidatesr_   T   s   16:J16:JD^^$45; "	y!	6*'
DHHV4DdhhsmUYU]U]^aUbcCSx 0 6B?Y]
  (IMM&,AA < $$S)UYYs^;< $$S)UYYs^; 
 	MM&)33;/%MM.9$==8A=(XXc]XXc]!XXk2 $ 8#xx6#'88,=#>!XXk2	 )"{3!j1'
 	"F 	II I  Kr   c                &    |ry| ry|r|ry|ry|ryy)NrD   zstrict-event-unreviewedzselector-and-geometry-candidatezselector-only-candidatezgeometry-only-candidatezno-reverse-evidence )reverse_strictreverse_confirmedselector_rowsexitss       r   classifyrf      s%    (0(( r   c                "   | | nt        t        dz  i       } ||nt        t        dz  dz  i       }||nt        t        dz  g       }||nt        t        dz  i       }||nt        t        dz  g       }g }| j                  d      xs g D ]  }|j                  d      }|j                  d	      }t	        |t
              rt	        |t
              sG|}	|}
t        ||	|
      }t        ||	|
      }t        |xs g |	|
      }t        |xs i |	|
      }t        |D ch c]%  }|j                  d
      s|j                  d
      ' c}      }t        |D ch c]%  }|j                  d      s|j                  d      ' c}      }|j                  d      xs g }|j                  ||||r)|d   j                  d      |d   j                  d      dnd d|	|
t        ||||      |rdndt        |      ||t        |      t        |      t        |      t        d |D              t        d |D              |dd        t        d |D              }dt        | j                  d      xs g       t        |      ||ddS c c}w c c}w )Nplayable_progress.jsondatatransition_reviews.jsonevent_transitions.jsonsave_selector_scene_links.jsonmap_exit_candidates.jsonconfirmedEdgesr;   r-   selectorleafPointerHexpointsr   spawnXspawnY)r   r   )r;   r-   rq   spawnrD   zmanual-review-onlyc              3  D   K   | ]  }|j                  d       sd  yw)rR   r   Nr   r!   r"   s     r   r$   z build_summary.<locals>.<genexpr>   s     3d##''RbJcA3d     c              3  D   K   | ]  }|j                  d       sd  yw)rL   r   Nr   rv   s     r   r$   z build_summary.<locals>.<genexpr>   s     -[CCGGMDZa-[rw   )r;   r-   classificationpromotionStatusselectorRecordCount	selectorsleafPointersstrictEventRecordCountconfirmedReviewCountexitCandidateCountreciprocalExitCandidateCountautoExitCandidateCountr1   )r<   reversec              3  p   K   | ].  }|j                  d       xs i j                  d      dk7  s+d 0 yw)r   rz   rD   r   Nr   rv   s     r   r$   z build_summary.<locals>.<genexpr>   s2     gsswwy'9'?R&D&DEV&W[f&fgs   ,66z4reverse candidates for already-confirmed map entriesa  Reverse candidates are useful for route-assist playtesting, but they are not normal gameplay proof unless the reverse side has confirmed reviews or a strict source event record. The current start-route reverse map1_01a -> map1_02b has selector and geometry evidence only.)	objectiveconfirmedEdgeCountcandidateCountmanualReviewOnlyCountr&   
conclusion)r   OUTROOTr   r3   strr>   r_   rA   rH   sortedrW   rf   lensum)playable_progresstransition_reviewsr@   r:   rY   r&   edger;   r-   reverse_sourcereverse_targetrd   re   rb   rc   r=   r|   leaf_pointersentry_pointsmanuals                       r   build_summaryr      s    .?-J)PY&&
Q 0B/M+S\v11
T .?-J)PY&&
Q >W=b 9hq..
i 2E1P-V_((
W D!%%&67=2 ((#(#&#&j.E()BNTbc'(;^^\-.?.E2~Wef-.@.FBXfgivRXR\R\]gRhFJJz2ij	=y\b\f\fgw\x

+; <yzxx)/R  & $ 'q/--h7l1o>Q>QRZ>[\	 )("*>;Lm]b"c2C;I]'*='9& -*-n*=(+,=(>&)%j033d3d0d*--[5-[*["'
 	(R gdggFK!"3"7"78H"I"ORPd)!'T ? jys   J
5J
J
/J
c                N   | j                  d      xs i }| j                  d       d| j                  d       d| j                  d       d| j                  d       d	|j                  d       d|j                  d       d|j                  d       d
| j                  d       S )NrQ   r2    r   r   r   z auto=rL   z hint=z reciprocal=rR   r   )r"   r.   s     r   	exit_textr      s    77< &BD776?
1SWWS\N!CGGCL>@V?W X !488C=/488C=/ Bgg./0	2r   c                   ddddd| d    d| d    d| d	    d| d
   dddg}| d   D ]  }|d   }|d   }t        t        |j                  d      xs g       i       }|j                  d      xs |j                  d      xs	 d|d    d}dj                  |j                  d      xs g       xs d}|j	                  d|d    d|d    dt        |j                  d             d|d    d|d    d|d    d | d |d!    d |d"    d |rt        |      nd d#| d$        | d   s|j	                  d%       |j                  g d&       | d   D ]  }|d   }|d   }|j                  d'|d    d(|d    dd)|d    d|d    d*dj                  d+ |j                  d,      xs g D              z   d-|d    d.d/|d0    d.d1|d2    d3dj                  |j                  d      xs g       xs d d4d5|d!    d6|d7    dg	       |j                  d      r(|d   D ]  }|j	                  d8t        |              ! n|j	                  d9       |j	                  d        d:j                  |      S );Nz"# Reciprocal Transition CandidatesrT   znGenerated from confirmed transition reviews, save-selector scene links, and geometry-only map exit candidates.z- confirmed edges scanned: r   z- reverse candidates: r   z)- manual-review-only reverse candidates: r   r   zd| confirmed entry | spawn | reverse | class | selector | strict events | exits | first exit | open |z9| --- | --- | --- | --- | --- | ---: | ---: | --- | --- |r&   r<   r   r1   rP   rO   ../web/game.html?map=r;   #&trialTransitions=saveSelectorLinks, r|   r   z| `z` -> `r-   z` | `rt   z` | ry   z | r~   r   z
 | [open](z) |z%| - | - | - | - | - | - | - | - | - |)rT   z
## DetailsrT   z###  -> z- confirmed entry: `z	` points c              3     K   | ]O  }d |j                  d       d|j                  d       d|j                  d       d|j                  d       d 	 Q yw)`r   r   r   r   rr   rs   Nr   )r!   r   s     r   r$   zmarkdown.<locals>.<genexpr>  s[       EIIcN#1UYYs^$4D89L8MQuyyYaObNccdes   AArq   z- classification: `r   z- promotion status: `rz   z- selector records: r{   z ()z- strict event records: z- confirmed reverse reviews: r   z- z- no geometry exit candidate
)r%   iterr   joinrW   r   r   extend)	summarylinesr"   r<   r   
first_exit	open_hrefro   r*   s	            r   markdownr      sY   ,
x

%g.B&C%DE
 )9!: ;<
3G<S4T3UV

nCE v 
Gi.$w{{+;<BCRH
NN:. 
*..2M 
#GH$5#66YZ 	 99W[[5;<C%/"&x(9z%))T[J\?]>^ _!"&):(;4HX@Y?ZZ]jG$<=>c'J^B_A``c(2y$<JykQTV	

 6?<=	LL'(v Gi.78$%T'(*;)<="5?"36%/9J)Tii "YYx06B 
 "'*:";!<A>#G,=$>#?qA"7+@#A"B C		'++k28b9@SAD&w/G'H&IJ+G4J,K+LM
 	  ;;'($%56 :	r)I"6!789: LL78R12 99Ur   c                   g }| d   D ]  }|d   }|d   }t        t        |j                  d      xs g       i       }|j                  d      xs |j                  d      xs	 d|d    d	}|j                  d
t	        j
                  |d          dt	        j
                  |d          dt	        j
                  t        |j                  d                   dt	        j
                  |d          dt	        j
                  |d          dt	        j
                  |d          dt	        j
                  dj                  |j                  d      xs g       xs d       d|d    d|d    dt	        j
                  |rt        |      nd       dt	        j
                  |       d        g }| d   D ]  }|d   }dj                  d |j                  d      xs g D              xs d}|j                  dt	        j
                  |d          dt	        j
                  |d          dt	        j
                  |d          dt	        j
                  |d          d |d!    d"|d    d#| d$        d%j                  d&d'd(d)| d*    d+| d,    d-| d.    d/d0t	        j
                  | d1          d2d3d%j                  |      xs d4d5d%j                  |      g	      S )6Nr&   r<   r   r1   rP   rO   r   r;   r   z<tr><td><code>z</code> -> <code>r-   z</code></td><td><code>rt   z</code></td><td>ry   z	</td><td>r   r|   r   r~   r   z</td><td><a href="z">open</a></td></tr>rT   c              3  `   K   | ]&  }d t        j                  t        |             d ( yw)z<li>z</li>N)htmlescaper   )r!   r*   s     r   r$   zhtml_page.<locals>.<genexpr>F  s0      
 4;;y345U;
s   ,.z#<li>no geometry exit candidate</li>z
<h2><code>z)</code></h2><ul><li>classification <code>z'</code></li><li>promotion status <code>rz   z!</code></li><li>selector records r{   z</li><li>strict event records z</li></ul><ul>z</ul>r   zT<!doctype html><meta charset="utf-8"><title>Reciprocal Transition Candidates</title>z<style>body{font-family:system-ui,sans-serif;background:#111;color:#eee;max-width:1200px;margin:24px auto}table{border-collapse:collapse;width:100%}td,th{border:1px solid #444;padding:6px 8px;vertical-align:top}code{color:#9bd4ff}a{color:#9bd4ff}</style>z)<h1>Reciprocal Transition Candidates</h1>z<p>Confirmed edges scanned: r   z; reverse candidates: r   z; manual-review-only: r   z.</p>z<p>r   z</p>z<table><thead><tr><th>confirmed entry</th><th>spawn</th><th>reverse</th><th>class</th><th>selector</th><th>strict events</th><th>exits</th><th>first exit</th><th>open</th></tr></thead><tbody>z"<tr><td colspan="9">none</td></tr>z</tbody></table>)	r%   r   r   rW   r   r   r   r   r   )	r   r&   r"   r<   r   r   r   detail_rowsre   s	            r   	html_pager   -  sx   Dv 
Gi.$w{{+;<BCRH
NN:. 
*..2M 
#GH$5#66YZ 	 	U8_566GTYZbTcHdGe fZ		'0B%CDE FWX%6788I$++V]^fVgJhIi j;;w'789: ;;;tyy[)A)GRHOCPQ R345 6/01 2;;
y4LM N![[34 5
	

( Kv 
i. 
$[[)9:@b
 
 3 3 	 	WX%6788I$++V]^fVgJhIi j,,0KK@P8Q,R+S T**.++g>O6P*Q)R S$$+,A$B#C D((/0H(I'J K' 	

 99` 	I3
&w/C'D&EE[\cdt\u[v  wM  NU  Vm  Nn  Mo  ot  	u
dkk',/016 	J		$AA		+
 
 
r   c                    |j                  dd       |dz  j                  t        j                  | dd      dz   d	       |d
z  j                  t	        |       d	       y )NT)parentsexist_okz%reciprocal_transition_candidates.jsonF   )ensure_asciiindentr   r	   r
   %reciprocal_transition_candidates.html)mkdir
write_textr   dumpsr   )r   out_dirs     r   write_outputsr   _  se    MM$M.66BB

7q9D@ C  66BB9WCU`gBhr   c            
        t        j                  t              } | j                  dt        t
        dz         | j                  dt        t        dz  dz         | j                  dt        t
        d	z         | j                  d
t        t
        dz         | j                  dt        t
        dz         | j                  dt        t
               | j                         }t        t        |j                  i       t        |j                  i       t        |j                  g       t        |j                  i       t        |j                  g             }t        ||j                          t#        d|j                   dz          y )N)descriptionz--playable-progressrh   )typedefaultz--transition-reviewsri   rj   z--event-transitionsrk   z--save-selector-scene-linksrl   z--map-exitsrm   z	--out-dirz*wrote reciprocal transition candidates -> r   )argparseArgumentParser__doc__add_argumentr   r   r   
parse_argsr   r   r   r   r@   r:   	map_exitsr   r   print)parserargsr   s      r   mainr   h  sG   $$9F
-D#H`B`a
.T4&=SlClm
-D#H`B`a
5D#PpJpq
D#@Z:Z[
$<D$(("-$))2.$(("-$00"5$.."%G '4<<(	6t||Fm7m6n
opr   __main__)r   r   r   r   returnr   )r   dict | Noner   r   )r&   
list[dict]r#   r   r   dict)r*   r   r   r   )r*   r   r-   r   r   r   )
r"   r   r2   z
str | Noner   
int | Noner   r   r   r   )r:   dict[str, dict]r;   r   r-   r   r   r   )r@   r   r;   r   r-   r   r   r   )rF   r   r;   r   r-   r   r   r   )rY   r   r;   r   r-   r   r   r   )
rb   r   rc   r   rd   r   re   r   r   r   )NNNNN)r   r   r   r   r@   list[dict] | Noner:   zdict[str, dict] | NonerY   r   r   r   )r"   r   r   r   )r   r   r   r   )r   r   r   r   r   None)r   r   )!r   
__future__r   r   r   r   pathlibr   typingr   __file__resolver   r   r   r   r   r'   r)   r/   r5   r>   rA   rH   r_   rf   r   r   r   r   r   r   __name__ra   r   r   <module>r      s+   H "      H~''*
Ul80E)
.

 
 	
/d! &*&*+/8<-1Q"Q#Q )Q  6	Q
 +Q 
Qh9x/d 25 iq( zF r   