
    [lLj                        d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	 ddl
mZ  e	e      j                         j                  d   Zedz  Zed	z  Zdd
ZddZddZddZddZddZedk(  r e        yy)aB  Classify dynamic object-VM target +0 writers by root context.

The status-comment selector consumer reads object+0xa8+0 only after a status
payload binds object+0xa8 to 0x004576d8.  A previous broad scan found 52
dynamic object-VM commands that write to local target offset +0, but none were
inside the status/menu payload.

This review prevents a false promotion: local target offset +0 is not enough.
The candidate root/resource contexts are battle effects, monsters, or field
object scripts, so they are object-local writers unless a status/menu base
binding is also proven.
    )annotationsN)Counterdefaultdict)Path)Any   outwebc                    	 t        j                  t        | z  j                  d            }t        |t              r|S i S # t        $ r i cY S w xY w)Nutf-8encoding)jsonloadsOUT	read_textFileNotFoundError
isinstancedict)namedatas     ;tools/build_status_comment_target0_writer_context_review.py	load_jsonr      sS    zz3:00'0BC dD)41r1  	s   ,A AAc                V    t        j                  | dd      S t        |       d      S )N T)quote)htmlescapestr)values    r   hr!   $   s%    ;;U]r$GGE
$GG    c                    dj                  | j                  d      xs g       j                         }| j                  d      xs g }d|v s%t        d | j                  d      xs g D              ry|sd|v sd|v ry	y
)N 	linkedCns	fieldMapsbtl_c              3  >   K   | ]  }|j                  d         yw)zN)
startswith).0r   s     r   	<genexpr>z#classify_context.<locals>.<genexpr>+   s     ZTDOOC0Zs   zbattle-or-monster-object-localmap_cara_zfield-object-localzresource-object-local)joingetlowerany)rowcnsmapss      r   classify_contextr6   (   su    
((377;'-2
.
4
4
6C77;%2D}Zcggk>R>XVXZZ/v}3#"r"   c                    t        d      } | j                  dg       }t        |t              sg }t	        t              }|D ]I  }t        |t
              s||j                  dd      |j                  dd      f   j                  |       K g }t               }t               }d}d}d}	t        |j                         d       D ]k  \  \  }
}}t        |D ch c]  }|j                  d	      xs g D ]  }|   c}}      }t        |D ch c]  }|j                  d
      xs g D ]  }|   c}}      }t        d |D              }t        d |D              }|r|j                  d      d   d   nd}||xx   t        |      z  cc<   |j                  |       |t        d |D              z  }|t        d |D              z  }|j                  |
|t        |      t        |      |t        |      |d d t        |      |d d d|d d D cg c]  }|j                  dd       c}d       n t        |      t        |      t        |      t        |      |||	ddd	}dddg|||dS c c}}w c c}}w c c}w )Nz3status_comment_indirect_selector_writer_review.jsontarget0WriterCandidates	rootVaHexr   	rootClassr   c                    | d   d   S )Nr    )items    r   <lambda>zbuild.<locals>.<lambda>C   s    TXYZT[\]T^ r"   )keyr&   r%   c              3  @   K   | ]  }|j                  d d        yw)	opcodeHexr   Nr0   r+   r3   s     r   r,   zbuild.<locals>.<genexpr>F   s     Cs#''+r2Cs   c              3  2   K   | ]  }t        |        y w)N)r6   rC   s     r   r,   zbuild.<locals>.<genexpr>G   s     AS+C0As   r   unknownc              3  D   K   | ]  }|j                  d       sd  yw)inStatusMenuPayloadRanger   NrB   rC   s     r   r,   zbuild.<locals>.<genexpr>K   s     YcSWW=W5XY     c              3  D   K   | ]  }|j                  d       sd  yw)inStatusCommentPayloadRanger   NrB   rC   s     r   r,   zbuild.<locals>.<genexpr>L   s     "_@]8^1"_rH         F   commandVaHex)r9   r:   candidateCountopcodeCountscontextClassfieldMapCountr&   linkedCnsCountr%   statusBackingBindProvensampleCommandVaHexeszThe 52 target +0 dynamic writes are object-local active-script/resource writers. They do not occur inside status/menu payloads and no 0x004576d8 backing-base bind is proven, so they must not be promoted as the status comment story/chapter selector writer.)	target0CandidateCountuniqueRootCountrP   contextClassCountsstatusMenuPayloadHitCountstatusCommentPayloadHitCountstatusBackingBindHitCountstatusCommentWriterPromoteddecisionz3hwanse-status-comment-target0-writer-context-reviewz7out/status_comment_indirect_selector_writer_review.json)versionkindsourceArtifactssummaryrootRowscandidateRows)r   r0   r   listr   r   appendr   sorteditemsmost_commonlenupdatesum)indirecttarget_rowsroot_groupsr3   	root_rowsclass_countsopcode_countsstatus_menu_hitsstatus_comment_hitsstatus_backing_bind_hitsroot_va
root_classrowsmr5   cr4   opcodescontextscontext_classra   s                        r   buildr}   2   s   NOH,,8"=Kk4(?J4?PK Zc4 b1377;3KLMTTUXYZ I!(L"))M '-k.?.?.AG^'_ 
#*tDOS377;3G3M2OQqOqOP4NC#''+2F2L"NAaNaNOCdCCADAA9A,,Q/215y]#s4y0#W%CYTYYYs"_"___ 	$'"%d) $W -!$T!#2Y"%c( "X+0PTUWVWPX(Y)D(Y	

< "%[!1y>]+"<0%5(;%=',`G  EUV$ W PN. )Zs   #I.#I4I:c                    dj                  d | d   j                         D              }dj                  d | d   D              }d| d| dS )	Nr   c              3  X   K   | ]"  \  }}d t        |       dt        |       d $ yw)z<div class='card'><b>z
</b><span>z</span></div>N)r!   )r+   kvs      r   r,   zrender_html.<locals>.<genexpr>z   s3      Aq  !vZ!v]Cs   (*ra   c              3    K   | ]  }d t        |d          dt        |d          dt        |d          dt        |d          dt        |d          dt        dj                  |d	                dt        dj                  |d
                dt        |d          dt        dj                  |d                d  yw)z<tr><td><code>r9   z</code><br>r:   z	</td><td>rO   rQ   rP   z, r&   r%   rT   rU   z
</td></tr>N)r!   r/   rC   s     r   r,   zrender_html.<locals>.<genexpr>~   s       	s;'()Qs;7G5H4I J%&'( )^$%& '^$%& '3{+,-. /3{+,-. /./01 2356789 :		s   CCrb   uE  <!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Status Comment Target +0 Writer Context Review</title>
<style>
  :root { color-scheme: light dark; }
  body { margin:24px; font-family:system-ui,-apple-system,Segoe UI,sans-serif; line-height:1.45; }
  h1 { margin:0 0 8px; font-size:24px; }
  .muted { color:#667085; }
  .cards { display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:10px; margin:16px 0; }
  .card { border:1px solid #d0d5dd; border-radius:8px; padding:10px 12px; background:rgba(127,127,127,.05); }
  .card b { display:block; color:#667085; font-size:12px; }
  .card span { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; overflow-wrap:anywhere; }
  .scroll { overflow-x:auto; }
  table { width:100%; border-collapse:collapse; }
  th,td { border:1px solid #d0d5dd; padding:7px 8px; vertical-align:top; }
  th { text-align:left; background:rgba(127,127,127,.08); }
  code { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; }
</style>
<h1>Status Comment Target +0 Writer Context Review</h1>
<p class="muted">dynamic writer target offset <code>+0</code> 후보를 root/resource 문맥으로 재분류합니다. offset만 같아도 status/comment backing writer로 승격하지 않습니다.</p>
<div class="cards">z</div>
<div class="scroll"><table>
<thead><tr><th>root</th><th>count</th><th>context</th><th>opcodes</th><th>field maps</th><th>linked CNS</th><th>status backing bind</th><th>samples</th></tr></thead>
<tbody>z</tbody>
</table></div>
)r/   rg   )r   cardsrw   s      r   render_htmlr   y   su    GG O))+ E 77  
# D* 7  	v 1 r"   c                    t               } t        j                  d       t        j                  d       t        dz  j	                  t        j                  | dd      d       t        d	z  j	                  t        |       d       y )
NT)exist_okz1status_comment_target0_writer_context_review.jsonF   )ensure_asciiindentr   r   z1status_comment_target0_writer_context_review.html)r}   r   mkdirWEB
write_textr   dumpsr   )r   s    r   mainr      sy    7DIItIIItI>>JJ

4eA6 K  	>>JJD K r"   __main__)r   r   returndict[str, Any])r    r   r   r   )r3   r   r   r   )r   r   )r   r   r   r   )r   None)__doc__
__future__r   r   r   collectionsr   r   pathlibr   typingr   __file__resolveparentsROOTr   r   r   r!   r6   r}   r   r   __name__r<   r"   r   <module>r      s    #   ,   H~''*
Ul
Ul2H#DN,^ zF r"   