
    Qj:                        d Z ddlZddlZddlZddlmZ ddlmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ  ej"                  e      ZdZd	Zd
ZdZdZ	 dde
eeef      deeef   fdZdZdZd	Zd Zd Z G d de      Z y)u  ShotContiLightStep — 샷별 경량 콘티 생성 (order 21.92).

s40/s41 레시피 이식: 인물 샷(비 bgonly·비 prev)마다 배경 플레이트 느슨
참조 LIGHT_FRAME 콘티를 gpt-image-2 로 생성해
`<projects_dir>/<pid>/images/<eid>/conti/conti_{tag}.png` 에 저장한다.

  data.contis[tag] = {image_path, plate_path, prompt, skipped_reason, error}

플레이트는 background_render/background_chain_render 체크포인트 soft-load
(manifest 의존 아님 — mode off 시 게이트에 막히지 않도록, outdoor_place_canon
스타일 FP soft-load 선례). 플레이트 부재 샷=no_plate 격리(스틸은 진행).
moderation 거절 시 PromptSanitizer 1회 재시도.
    N)Path)AnyDictListOptional)
StepRunner)carried_clause_fortag_of   1416
gemini-proproject_configreturnc                     t        | xs i       }|j                  d      }t        }t        |t               r$t        |j                  d      t              r|d   }ddlm} | ||      dS )u  이 주행에서 lane 기하 판정이 **실제로 쓰는** 별칭과 물리 모델.

    ★`project_config` 가 덮을 수 있으므로 **effective 값**을 돌려준다 —
     기본값만 접으면 프로젝트가 다른 모델로 바꿨을 때 지문이 안 움직인다.
    outdoor_marker_geometrymodelr   )resolve_model_physicalaliasphysical)dictgetLANE_GEOMETRY_JUDGE_ALIAS
isinstancestr!app.modules.pipeline.era_researchr   )r   cfgentryr   r   s        Z/Users/manta/Documents/Projects/TheRoad-I1/backend/app/core/steps/shot_conti_light_step.pylane_geometry_judge_identityr#   V   s`     ~#
$CGG-.E%E%:eii.@##FgH(>u(EFF       c                      ddl m}  | S )uS   마네킹 저작 sketch 팩 집합 (지연 import — 모듈 로드 순환 방지).r   _MANNEQUIN_SKETCH_PACKS)'app.modules.pipeline.outdoor_marker_mapr(   r'   s    r"   _mannequin_sketch_packsr*   o   s     #"r$   c                  R    ddl m}  ddlm}  | t	        |j
                              S )u@   background_render_step._resolve_openai_client 와 동일 패턴.r   )openai_clientsettings)timeout)app.core.openai_keysr,   app.core.configr.   floatllm_timeout_image_gen)r,   r.   s     r"   _resolve_openai_clientr4   x   s#    2(h445 r$   c                      e Zd ZdZdefdZdefdZedefd       Z	edefd       Z
deeef   fdZdeeef   fdZd	edeeeef      fd
Zd Z	 d$deeef   deeef   deeeef      ddfdZdddedeeef   deeef   deeef   deeef   dededeeef   fdZd Zdddeeef   deeef   deeef   deeef   dedeeef   d eeef   dedeeef   fd!Zd%d"edeeef   fd#Zy)&ShotContiLightStepuQ   경량 콘티 — 플레이트 느슨 참조 단일 프레임 (레시피 이식).r   c           
         dd l }dd l}ddlm} ddlm}m} ddlm} ddl	m
} |j                  t         || j                               | || j                        |d}t        t!        |dd            rdd	lm}	m}
 d
|d<    |
|	      |d<   | j'                         rd
|d<   t        t!        |dd            r:ddlm} ddlm} d
|d<    |t,              |d<    |d      |d<   |j.                  |d<   t        t!        |dd            rddlm} ddlm}m}m} d
|d<    |t:              |d<   ddlm}m}m } tB        |v rHddlm"} ||d<   ||d<   tF        |d<   d|jH                  d|d<   tK        | j                        |d<   ||d <    |tB              |d!<   ||d"<   ||d#<   tB        tM               v rJtN        t        t!        |dd            t        t!        |dd            t        t!        |d$d            d%|d&<   t        t!        |d'd            r,dd(l(m)}m} d
|d'<    |d      |d)<   ||d*<   |jH                  |d+<    |jT                  |jW                  |d
,      jY                  d-            j[                         d d. S )/Nr   r-   CONTI_IMAGE_MODELresolve_prompt_versioncompute_config_hash)!CARRIED_PERSON_PROJECTION_VERSION)still_recipe_modeschema_versionprompt_versionimage_modelproject_config_hashcarried_person_projectionstill_bgfirst_enabledFCAMERA_FRAME_PROMPT_VERSIONr:   Tconti_camera_frame_packstill_bgfirst_full_enabledoutdoor_map_conti_enabledr:   outdoor_map_conti_packr   outdoor_shot_grounding_packmap_nb2_modeloutdoor_lane_pipe_enabled)EVIDENCE_VALIDATION_VERSION)GEOMETRY_TEXT_VERSIONr:   resolve_sketch_pack_versionlane_geometry_pack) MARKER_ANNOTATE_CONTRACT_VERSIONMARKER_MAP_SIZE_ANNOTATE_PACKS) MARKER_GEOMETRY_CONTRACT_VERSIONlane_marker_contractlane_marker_geometry_contractlane_marker_max_attemptsr   r   lane_marker_judgelane_geometry_judgelane_marker_map_sizelane_sketch_packlane_geometry_text_version lane_evidence_validation_versionstill_lane_prev_bgfirst_enabled)contractbgfirstbgfirst_full	lane_prevlane_mannequin_chainstill_plate_select_enabled)PLATE_AUTHORITY_VERSIONr:   plate_select_packplate_authority_versionplate_select_judge_model)	sort_keysutf-8   ).hashlibjsonr1   r.   %app.modules.pipeline.shot_conti_lightr9   r:   app.core.step_runnerr<   +app.modules.pipeline.shot_continuity_authorr=   r>   SCHEMA_VERSION_prompt_selectorr   boolgetattr!app.modules.pipeline.still_reciperF   _no_plate_conti_on&app.modules.pipeline.outdoor_map_conti+app.modules.pipeline.outdoor_shot_groundingPROMPT_VERSIONgemini_image_model%app.core.steps.outdoor_lane_plan_steprO   r)   rP   rQ   LANE_GEOMETRY_PACK_VERSIONrS   rT   rU   LANE_SKETCH_PACK_VERSIONrV   !LANE_MARKER_ANNOTATE_MAX_ATTEMPTSgemini_text_modelr#   r*    MANNEQUIN_CHAIN_CONTRACT_VERSION!app.modules.pipeline.plate_selectrg   sha256dumpsencode	hexdigest)selfrn   _jsonr.   r9   r:   r<   _carried_person_projpayload_cam_pack_sel_recipe_packmap_pack_versiongrounding_pack_version_lane_evidence_version_geometry_text_versiongeometry_pack_versionrQ   _marker_contract_marker_size_annotate_packs_geo_contractrg   _plate_select_packs                          r"   _config_hashzShotContiLightStep._config_hash   s   ,	

 	=	

 "*!;!;,4%%' -#6t7J7J#K *>
& "95AB
 04G+,1=m1LG-. ""$48G01 "=uEF 48G/00@1G,- 6L6G12 (0'B'BGO$ "=uEF  48G/0,A*-G()  (?: 3C./;H785 23 * ( : :0+, 11D1DE -.2>./*E(+G&' 5KG01& 67 (+B+DD @#G "95%B  C$( ">*G %H!%g "CU'L "M3./ ">FG
 59G01+=c+BG'(1HG-.2:2L2LG./ w~~KK4K077@

)+cr 	r$   c                 l    ddl m} | j                         ryt        t	        |dd            rdS t
        S )u   콘티 팩 selector — full=v5(키샷 레이아웃 가치, E2E13 fix①⑦ —
        v4 소품 방향+자연 연기+no_plate 헤더 승계), BGFIRST2 ON=v2(원근
        가이드), OFF=v1.r   r-   5rD   F2)r1   r.   rx   ru   rv   r{   )r   r.   s     r"   rt   z#ShotContiLightStep._prompt_selector   s>     	-""$ GH&=uEF 	
  	
r$   c                  j    ddl m}  t        t        | dd            xr t        t        | dd            S )u   fix④ full 게이트 — bgfirst 자체가 ON 일 때만 유효 (OFF 인데
        full 만 ON 이면 콘티는 v1 그대로, 서비스가 fail-closed).r   r-   rH   FrD   )r1   r.   ru   rv   r-   s    r"   rx   z%ShotContiLightStep._no_plate_conti_on.  s:     	-H:EB
 F78%<eDE	Fr$   c                  8     ddl m  t         fddD              S )u  마네킹 콘티를 만들어도 되는 조건 — 하류 교체 계약이 살아 있나.

        마네킹 산출은 배경 i2i·엔티티 단계의 교체 계약과 짝으로만
        유효하다. 세 플래그 중 하나라도 꺼지면 서비스가 lane_chain=False
        로 계산해 마네킹을 legacy 조립 참조로 넣고, 그 경로엔 교체 계약이
        없어 마네킹이 최종 스틸까지 유출된다(2026-07-26 설계 실측).
        r   r-   c              3   J   K   | ]  }t        t        |d               yw)FN)ru   rv   ).0namer.   s     r"   	<genexpr>z<ShotContiLightStep._mannequin_chain_ready.<locals>.<genexpr>C  s+      
 4/0s    #)rD   rH   r`   )r1   r.   allr-   s   @r"   _mannequin_chain_readyz)ShotContiLightStep._mannequin_chain_ready8  s$     	- 

 
 	
r$   c                     t        | dd      }||S ddlm}  || j                  | j                  | j
                        }|| _        |S )u  샷별 **확정 배정 인물의 short_id** (감사 1-B, 2026-08-27).

        ★한 실행에서 lane 갈래와 일반 콘티 갈래가 **각자 부른다.** 그때마다
         프로젝트 전체 `EntityCanon` 과 에피소드 전체 `SceneStill` 을
         훑으므로 인스턴스에 담아 둔다 (큰 판은 923 + 980 행이다).

        CARRIED 를 이 집합으로 거른다 — 그 샷에 없는 인물이
        "they must be one of: …" 와 함께 나가던 것을 막는다.

        ★`_char_refs_by_tag` 를 재사용하지 않는다. 그쪽은 ㉠ 이름과 참조
         경로만 돌려주고 short_id 를 버리며 ㉡ 팩 selector 가 바뀐 경우
         에만 불린다. **visibility 는 언제나 필요하다.**

        ★참조 이미지 유무와 **묶지 않는다.** 참조가 없어도 그 사람은
         화면에 있다 — 참조로 거르면 연속성이 조용히 사라진다.

        ★계산은 `shot_ref_classify.load_character_sids_by_tag` 하나다
         (2026-09-19) — 스틸 조립이 「캐릭터가 보이면 사람 샷」 규칙에 같은
         집합을 쓴다. 둘이 따로 세면 콘티 대상과 스틸이 갈린다.
        _vis_sids_cacheNr   )load_character_sids_by_tag)rv   &app.modules.pipeline.shot_ref_classifyr   db
project_id
episode_idr   )r   cachedr   outs       r"   _visible_char_sids_by_tagz,ShotContiLightStep._visible_char_sids_by_tagL  sO    * 0$7M	
 )GGT__doo7"
r$   c           	      b    ddl m ddlm}mm} ddlm}  j                  j                  |      j                  |j                   j                  k(  |j                  dk(        j                         D ci c]'  }|j                  |j                  xs |j                  ) }}i dt         dt"        t$           f fd}i } j                  j                  |      j                  |j                   j                  k(  |j&                   j&                  k(        j                         }|D ]  }	|	j(                  |	j*                  }}
|
| 	 t-        j.                  |	j0                  xs d
      }g }|D ]r  }t5        |t6              r$|j9                  d      xs% |j9                  d      nt5        |t               r|nd	}|r||vrR ||      }|]|j;                  ||   |f       t |s|| |t=        |
      t=        |            <    |S c c}w # t,        j2                  $ r Y w xY w)u4  샷별 캐릭터 비례 참조 — VE(scene_still SOT) → character 엔티티
        primary reference ImageAsset 경로. (BGFIRST2 v2 콘티 전용 —
        outlook v14 보편 계약으로 primary=기본 모습.) 결손=해당 샷 참조
        없음(fail-safe — 콘티 자체를 막지 않는다).r   )resolve_image_path)EntityCanon
ImageAsset
SceneStillr
   	charactereidr   c                 f   | vrj                   j                        j                  j                  j                  k(  j                  | k(  j
                  dk(  j                  dk(        j                         }|r |j                        nd }||j                         r|nd | <   |    S )N	reference   )
r   queryfilterr   	entity_id
asset_type
is_primaryfirst	file_pathexists)r   rowpr   ref_path_cacher   r   s      r"   _primary_refz:ShotContiLightStep._char_refs_by_tag.<locals>._primary_ref  s    .(GGMM*-V"--@",,3"--<"--2	 UW  :=&s}}5$188:A4 s# "#&&r$   Nz[]idr   )app.core.file_pathsr   app.models.projectr   r   r   r   r   r   r   r   r   entity_typer   r   r   r   r   r   r   scene_index
shot_indexro   loadsvisible_entities_jsonJSONDecodeErrorr   r   r   appendint)r   r   r   r   echar_name_by_idr   r   rowsr   sishiverefsvr   r   r   r   r   s   `                @@@r"   _char_refs_by_tagz$ShotContiLightStep._char_refs_by_tagn  s   
 	;JJA WW]];/V&&$//9'';6 SU+
 DD166>QTT! 	 +
 57	'c 	'htn 	' 	'$ !GGMM*%V%%8%%8 SU 	 Coos~~BzS[ZZ 9 9 ATB D "!T* UU4[6AEE+$6)!S1!t 
 c8 %=KK!5q 9:  15F3r7CH-.+ , 
y+
X '' s   :,H#HH.-H.step_idc                 L   ddl m} t        |j                        | j                  z  dz  dz  | j
                  z  |z  dz  }|j                         r&	 t        j                  |j                  d            S y # t        $ r!}t        j                  d||       Y d }~y d }~ww xY w)	Nr   r-   checkpointsepisodeszmanifest.jsonrl   )encodingu&   shot_conti_light: %s 로드 실패: %s)r1   r.   r   projects_dirr   r   r   ro   r   	read_text	Exceptionloggerwarning)r   r   r.   cpexcs        r"   _load_prev_checkpointz(ShotContiLightStep._load_prev_checkpoint  s    , &&'oo -.0:;oo '(*9: 	
 99;zz",,,"@AA
 	  <gs  	s   $A9 9	B#BB#c                    	 ddl m ddlm ddlm}m} ddlm} t                || j                        	||ddd	d
t        dt        dt        dt        f	fd}|S )u9   gpt-image edit + moderation 시 sanitizer 1회 재시도.r   call_gpt_image_bytesreserve_current_call)r9   
CONTI_SIZEPromptSanitizerr   highr   r   sizequalityntagpromptout_pathr   c                     |D cg c]
  \  }}|	| }}}|}dD ]6  }	  d        |rdnd||xs d dd| d	      }	d
dl m}
  |
||	      c S  t        d      c c}}w # t        $ r}t        |      j	                         }d|v xs d|v xs
 d|v xs d|v }|dk(  rS|rQj                  |t        |      g |      }|j                  d      xs d}|rt        j                  d|        |}Y d }~ڂ d }~ww xY w)Nr      zshot_conti_light.contisourceeditgenerateconti_lightshot_conti_lightoperation_typeshot_tagmoder   	ref_pathscall_kwargscapture_rolecapture_metadatar   atomic_write_bytes
moderationsafetycontent_policyrejectedr   sanitized_prompt u6   shot_conti_light %s: moderation — sanitize 재시도unreachable)
%app.modules.pipeline.multiroll_geminir	  r   r   lowersanitizer   r   r   RuntimeError)r   r   labeled_refsr   _labr   r  currentattemptpngr	  r   msg	moderatedsr	sanitizedr   r  clientr   	sanitizers                   r"   gen_fnz/ShotContiLightStep._make_gen_fn.<locals>.gen_fn  sK   
 +7H,wtQ!-,IHG!$(0HI.'0Vj&"+"3t$/%2.@(+*C .h<<) "L }--Q I. ! c(..*C$+ Hx3 H+s2H6@C6G  !|	&//S2wO$&FF+=$>$D"	$"NN!,-0 '0G$!s(   
A!A!1A''	C=0BC87C88C=)#app.modules.llm.gpt_image_primitiver   app.core.image_call_budgetr   rp   r9   r   app.modules.prompt_sanitizerr   r4   r   r   r   )
r   r9   r   r   r   r   r  r  r   r  s
        @@@@@r"   _make_gen_fnzShotContiLightStep._make_gen_fn  sq    LC	
 	A')#43F3FG	&	
-	.-	.!-	.;?-	.-	. -	.^ r$   Ncontis
map_plateslane_contisc                     ddl ddlmm ddlm} ddlm} ddlmm	} ddl
m} ddlm} dd	lm  j                   j#                  |      j%                  |j&                   j&                  k(  |j(                   j(                  k(        j+                         }	|	D 
ci c]%  }
|
j,                  |
j.                  f|
j0                  ' c}
dd
lm} ddl
m} ddlm dt8        f fd} fd}fd}	  ||||||||||j:                  	        j                   j=                          yc c}
w # t>        $ r  j                   jA                           w xY w)uo  콘티/맵 플레이트/lane 스케치를 intermediate ImageAsset 으로 영속
        (Codex 1차 리뷰 BLOCKING-2) — 스틸 lineage(input_image_ids)가 실을
        asset UUID 제공. file_path 기준 idempotent(재실행 시 기존 row
        재사용), 삭제 없음. 결과 asset_id 는 각 entry 에 병기되어
        체크포인트로 내려간다.r   N)datetimetimezone)to_relative_image_path)catalog)r   r   r9   	parse_tag)annotate_generated_assetr-   )register_intermediate_assetsrelc                     j                   j                        j                  j                  j                  k(  j                  | k(        j                         S N)r   r   r   r   r   r   )r2  r   r   s    r"   find_asset_by_relzKShotContiLightStep._register_intermediate_assets.<locals>.find_asset_by_rel5  sK    j)))T__<((C/ r$   c                 @    	|      \  }} t        
j                               j                  |d j                  ||f      j                  | ||dj                  j                        j                               }j                  j                  |       |S )N	generated)r   r   r   r   still_idr   r   prompt_usedgeneration_modelstatus
created_at)
r   uuid4r   r   r   nowutc	isoformatr   add)r2  r   r   r   r   r   r   assetr   _pt_uuidr)  r   still_by_keyr*  s           r"   	new_assetzCShotContiLightStep._register_intermediate_assets.<locals>.new_asset?  s    #hGBu{{}%??%%))2s)4??"!&"#<<5??AE GGKKLr$   c                      | |d||       y )Nconti)pipeline_rolestageinput_image_idspipeline_metadata )rB  role	input_idsmetar0  s       r"   annotate_fnzEShotContiLightStep._register_intermediate_assets.<locals>.annotate_fnQ  s    $" )"&r$   )	r%  r&  r'  rel_fnr5  rF  rQ  conti_modelplate_model)!uuidr)  r*  r   r+  
app.modelsr,  r   r   r   rp   r9   r   r/  #app.services.image_capture.annotater0  r   r   r   r   r   r   r   r   r   r1   r.   r1  r   r|   commitr   rollback)r   r%  r&  r'  r+  _catalogr   r9   r/  
still_rowss_sr1  r5  rF  rQ  r   rC  rD  r0  r)  rE  r*  s   `               @@@@@@@r"   _register_intermediate_assetsz0ShotContiLightStep._register_intermediate_assets
  s7    	/> 	3=KD	

 GGMM*%V%%8%%8 SU 	 :D
9CAQ]]ALL)144/
 	3	
 	L	3 		 	$		(%'-"3#'-11
 GGNNw
x  	 GG		s   &*D95D> >%E#F)forceshotsclassify_shotsclassify_scenesscene_textsscene_primaryout_dirr_  c                
   *+,- ddl m}	m}
 ddlm}m} ddlm- ddlm	} ddl
m,m}  j                  d      }|xs i j                  di       j                  d	i       xs i } j                  d
      }|xs i j                  di       j                  d	i       xs i }|st        j!                  d       di iS  |	 j                  d            }i }i }|j#                         D ]7  \  }}t%        |t&              r|j                  d      s)|j                  |      xs i }|j                  d      xs d}|j                  d      xs d}|j                  d      dk(  rT|rR|rPt)        |      j+                         r7t)        |      j+                         r|d   t)        |      t)        |      d||<    |
||j                  d      xs g t-        |j                  d      xs g       |||      }|D ]&  }|| |t/        |d         t/        |d               <   ( : |D ci c]7  } |t/        |d         t/        |d               |j                  d      xs d9 }} ||      D cg c]	  }||v s| } }| sdi iS  || D ci c]  }||j                  |d       c}t0         j2                   j5                               }!ddlm}"  |" j:                        *dt(        f*,- fd}#ddlm}$  |$       +dt(        d t(        f+ fd!}%dd"l m!}& dd#lm"}' dd#lm"}( dd$l#m$})  || ||||!|||#|%|t0        |&jJ                   |'t0               |(d%      *xs d |) j2                        d&|'      S c c}w c c}w c c}w )(u   야외 복잡 구도 → 맵 기반 플레이트 (outdoor_map_conti_enabled).

        캐논 자산(outdoor_place_spec/canon)·grounding 은 W22 스택 재사용.
        반환 = run_outdoor_map_conti 결과 {"map_plates": {tag: {...}}}.
        r   )build_shot_loc_mapfilter_group_shots)judge_complex_shotsrun_outdoor_map_conti)run_outdoor_shot_grounding_shot)conti_targetsr/  r   outdoor_place_specdatagroupsoutdoor_place_canonuB   shot_conti_light: 야외 스펙 그룹 없음 — 맵 분기 no-opr&  shot_validatorspecmaster_png_pathr  map_png_pathr;  ok)rs  
master_pngmap_pngscene_indicesoutdoor_loc_ids)ry  loc_idsrd  shot_loc_by_keyselected_keysr   r   description)shot_desc_by_tagr@   r   opik_metadata)project_corrections_blockc           
           	|       \  }} 
||||d||j                         j                  j                               }|d   S )Nr   r   r~  )rs  shot
scene_textrx  creator_corrections_blockr   r  ground)
read_bytesr   build_opik_metadata)r   rs  	shot_descr  ru  r   r   r   corrections_blockr/  rk  r   s           r"   	ground_fnz4ShotContiLightStep._run_map_conti.<locals>.ground_fn  s`    nGB1#%"%#,
 &$//1*;#22"668C x= r$   )GeminiImageClientr   r   c                    	j                  
j                  
j                  d       	j                  ||D cg c]   \  }}|t	        |      j                         f" c}}d      \  }}ddlm}  |||      S c c}}w )Noutdoor_map_conti_plate)r   r   r   z16:9)labeled_referencesaspect_ratior   r  )set_contextr   r   generate_imager   r  r  r	  )r   r   r  r   labelr   r  _msr	  geminir   s            r"   	bg_gen_fnz4ShotContiLightStep._run_map_conti.<locals>.bg_gen_fn  s    ????8  
 ,,BN$BNheQUDG..01,$ $ - HC &h44$s   %A<r-   rJ   r;   r   )	nb2_modelmap_packgrounding_packr  rB   )conti_target_tagsr  group_by_taggroup_assetscomplex_by_tagtime_of_day_by_scenerc  r  r  re  r@   extra_fingerprintr_  )&*app.modules.pipeline.outdoor_direct_commonrg  rh  ry   ri  rj  rz   rk  rp   rl  r   r/  r   r   r   r   infoitemsr   r   r   r   setr   r{   r   r  app.core.creator_correctionsr  r   #app.modules.llm.gemini_image_clientr  r1   r.   r:   rq   r<   r|   ).r   r`  ra  rb  rc  rd  r}  re  r_  rg  rh  ri  rj  rl  r   spec_cpspec_groupscanon_cpcanon_groupsr|  r  r  gidr!   canonmasterrx  gshotsshr\  desc_by_tagtoutdoor_targetsr  r  r  r  r  	_settingsr   r   r<   r  r  r/  rk  s.   `                                         @@@@r"   _run_map_contiz!ShotContiLightStep._run_map_contim  s   "	
	
	
 	HL,,-AB}"))&"599(BGM2--.CD B++FB7;;HbIORKK\] "%%,&&'78
 (*')%++-JCeT*%))F2C $$S)/REYY017RFii/52G		(#t+wL'')d7m.B.B.D "&M"&v,#G}%S!
 (#ii8>BEII&78>B?+ /+F   3r-013r,7G3HI 1 .B 	
  3q'(#ao*>?m$*+ 	 	 
 %^4
4!\8IA4 	 
  "%%,APQAaB!77Q)..224	
 	K5dooF	!d 	! 	!" 	J"$	54 	5D 	5& 	:	
	
 	=$-(%%)!0#)&99,^< #9"=%6%<"':''(
 /
 	
U

 Rs   %<M6-	M;7M;	N c                    	
 ddl m} ddlm ddlm ddlm
 ddlm	} ddl
m} t               	 | j                        t        t        |d	d
      xs d      |ddd	 	 	 	 ddt        dt        dt         dt        dt        dt"        dt        dt$        f
 fd}dt        dt        dt         dt        dt        dt$        f	fd|S )u  레인1 스토리보드 스케치 — 참조=클린 canon 맵, gpt edit +
        sanitize 재시도 (R4: 마커 굽힌 control 소멸).

        2026-08-25 — `model` 인자를 받는다. 마커 맵 검사가 소진되면 호출부가
        **다른 모델로** 다시 시킨다(같은 모델 되풀이는 값이 없다는 실측).
        슬러그 꼴(`provider/model`)이면 OpenRouter 로 나가고, 그 밖은
        종전대로 OpenAI edit 이다 — 두 경로는 API 모양이 다르다.
        r   r-   r   r   )draw_marker_map_via_model)r   r   r   marker_map_image_modelr  zgpt-image-2.5-sunburstr   r   r   r   r   r  rN  r   out_metar   r   c                      |xs 	} |t              j                  j                  d d
 fd      }j                  d       |d<   |S )Nshot_conti_light_lane)r   r   r   multiroll_tagc           	            |       S r4  rM  )m_sketch_via_openair  r   r  rN  r   r   s    r"   <lambda>zLShotContiLightStep._make_lane_sketch_fn.<locals>.sketch_fn.<locals>.<lambda>I  s    (:D$!)Er$   )r   r   r  rN  capture_contextopenai_rendereffective_promptr   )listr   r   
setdefault)r   r   r  rN  r   r  r   _modelr  _default_modelr  r  r   s   ``````   r"   	sketch_fnz:ShotContiLightStep._make_lane_sketch_fn.<locals>.sketch_fn6  st     ,nF+VtI"&//"&//&=%(	!E EC ###$6?$*!Jr$   c                    |}dD ]V  }	  d        d||D 	cg c]  }	t        |	       c}	t        fd|i|rd|ini |d| d	      }
|
||d
<   ||d<   |
c S  t        d      c c}	w # t        $ rw}t        |      j                         }d|v xs d|v xs
 d|v xs d|v }|dk(  r=|r;j	                  |t        |      g |      }|j                  d      xs d}|r|}Y d }~ d }~ww xY w)Nr   zshot_conti_light.markerr   r   r   r   r  r   r  r  r
  r  r  r  r   r  r  r  )r   r   r   r  r  r   r  )r   r   r  rN  r   r  r   r  r  r   r  r   r  r  r  r  r   r  r  r   r  s                   r"   r  zCShotContiLightStep._make_lane_sketch_fn.<locals>._sketch_via_openaiQ  sT    G! (0IJ.#&3<"=9a3q69"=$('%@/4%@15~2%@ &*.E(+*C  +7>!34,1)J) "D }--7 #> ! c(..*C$+ Hx3 H+s2H6@C6G  !|	&//S2wO$&FF+=$>$D"	$&/G$s.   A/A*-A/*A//	C/8A,C*)C**C/)lane_storyboard_sketchNNr  )r1   r.   r!  r   r"  r   &app.modules.pipeline.marker_map_enginer  rp   r   r#  r   r4   r   r   rv   r  r   bytes)r   _cfgr   r   r  r  r  r   r  r  r  r   r  s   `    @@@@@@@@r"   _make_lane_sketch_fnz'ShotContiLightStep._make_lane_sketch_fn  s    	5LCTD@')#43F3FG	D2B7S;SU $	
 1!		!	.2		 	 		
 	 	 	6*	.*	.!*	..2*	.*	..1*	. *	. *	.X r$   
continuitylocation_by_scenescene_headings	plate_mapassign_by_keyc       	         `"   ddl m}
 ddlm} ddlm}m} ddlm} ddl	m
}m}m}m} ddlm}m}m}m}m}m}m}m}m}m}m}m}m}m} m}!m}"m}#m }$m!}% ddl"m#}&m$}'m%}( dd	l&m' dd
l(m)}) ddl"m*}* | jW                  d      }+|+ |
ddd      |+jY                  di       xs i }, ||,      }-| jW                  d      }.|.xs i jY                  di       jY                  di       xs i }/ || jW                  d      | jW                  d      | jW                  d      | jW                  d            }0 ||,|/|0      }1|1r  |
dddj[                  |1dd       z   d      t]        |,jY                  di       xs i       D ]  }2|,d   |2   }3t_        |3t`              r|3jY                  d      dk7  r0 ||3jY                  d       xs i | |0|/jY                  |2      xs i       !      }4|4sj |
d"d#|2 d$dj[                  |4dd       z   d       |-stb        je                  d%       d&i iS | jW                  d'      }5|5xs i jY                  di       jY                  di       xs i }6| jW                  d(      }7|7xs i jY                  di       jY                  di       xs i }8| jW                  d      }9i }:|9xs i jY                  di       jY                  d)g       xs g D ]  };|;jY                  d*      }<|<|;jY                  d+g       xs g D ]Z  }=|=jY                  d,      }>|>ta        |=      }?tg        |<      |?d*<   tg        |>      |?d,<   |?|:d-tg        |<       d.tg        |>       <   \  | jW                  d      }@i }A|@xs i jY                  di       jY                  d+g       xs g D ]Z  }=|=jY                  d*      |=jY                  d,      }>}<|<(|>+|=jY                  d/      xs d0Ad-tg        |<       d.tg        |>       <   \ dd1l4m5}B dd2l"m6}C |-jo                         D DEcg c]*  \  }D}E|EjY                  d3      d4k(  r B D      |      rD, }F}D}Etp        ts               v r%Fr#| ju                         s |
d5d6tp         d7d       |$tp               |#tv              tp        ts               v rtx        nd0d8}G |)d9d: |$tp              ;      }H |!tp              }I| j{                         }Jtp        |v }Kd<d=t|        ii}L|Lj                  | j                  xs i        t        | j                        }Md>d=d?ii}N|Nj                  | j                  xs i        d@d=d?ii}O|Oj                  | j                  xs i        ddAlBmC}P |Pj                  }Q|dBz  }R |'|R      }S|j                  dCdCD       ddAlBmC}T ddElFmG}U  |Ut        |TdFd0            }Vi }W| j                         }Xt]        |-fdGH      D 
]  }Y|-|Y   }E |Y      \  }<}> B|<|>f|      s EdI   }2|Ed3   }Z|ZdJk(  r0Z|2EdK   dL}3|3WY<   |ZdMk(  r|8jY                  |2      xs i }[ddNl"mJ}\  |\|< dO|> |||[jY                  dP      |[jY                  d      xs dQR      \  }]}^}_|3j                  dS[jY                  dP      xs d[jY                  dT      |[jY                  d      xs dQ]^_U       |/jY                  |2      xs i jY                  dV      }`|`s|3j                  dWdXY       |	s/YVv r+|3j                  dWdZY       tb        j                  d[Y       P|6jY                  |2      xs i }a|ajY                  d\      xs d0}bajY                  d]      }c|ajY                  d      dk7  sbrt        b      j                         s |
dY d^Z d_|2 d`d      ajY                  da      xs d0}dajY                  db      }eKrZdrt        d      nd}f|f/fj                         rfj                         j                  dk(  ses |
dY d^Z dcdddede|2 d`
d      AjY                  Y      xs d0j                         }g|gs |
dY dfd      ta        |:jY                  Y      xs i       }h|hj                  |<|>gdg       |jY                  |<d0      }it        b      j                         }jt        tg        |<      tg        |>            }k C|jY                  dh      xs g k      }l|jY                  di      xs i jY                  k      xs i }mt        |jY                  dj      k|mXjY                  |k      xs
 t               hjY                  dkdC       l      }n|jY                  |<      xs |jY                  |<      xs d0}o | | `hiZEdm   |olnn      dot        b      fgKrdpt        d      fgng z   dqdr |#tv              | |$tp              ||*|t        QM|ds
t      }p|duY dvz  }q|dw|Y dvz  }rSjY                  |Y      xs i }s|	sqj                         rrj                         rsjY                  dx      pk(  rsjY                  dy      xs i jY                  dz      dru rsjY                  d{      xs i jY                  d|      dCu rjsjY                  d}      rXt        j                  rj                               j                         sjY                  d}      k(  r |3j~                  di ddd~t        q      dbdcdt        r      d{sjY                  d{      d|sjY                  d      d|sjY                  d      d|sjY                  ddr      d|sjY                  d      d|sjY                  d      d|sjY                  d      d|sjY                  d      d|sjY                  d      dy|sjY                  dy      d|sjY                  d      ddCG Kr|3j                  de       / |&q        |&r       	  |%`hijEdm   xs dtv        L| j                               }t|td   }u ||utp              }v |"tp              dz   dj[                   ||utp        |v tp        |v  |tp                          z   }wi }xi }yd}zdr}{ddl\m]}| ddlm^}}  ||       }~|~D cg c]  }t        dqt        dqz         D ]  }|f   }}}v}d0}g }|D ]  \  }}|k7  rv}rtb        j                  dY       } JYt        b      gd|y      }z |r|z        |d@Idwdddd |j      ddd ||z      g |       Od@| j                               }x|3d<   |xjY                  d|      rdC}{ nBj                  zxd       vdz   dz   t        |xjY                  dd0            z   dz   dz   } {ss1|3j                  dWddj[                  ~       t        |~             # }jutp        | j                         O      }||   }|d   }z|d   }x |r|z       tb        j                  dYt        |      |dqz   |d=   dj[                  ~             |3j                  dC|dqz   t        |      |jY                  dd0      |d=   |xt        |~              |hjY                  d      xs d0oulngdrKtp        	      }rg|Krt        d      gng z   }}i }dr}t        dqt        dqz         D ]  } JY      } |q|        |d>Hddgz   dddd ||      g |       Nd>| j                               }||3d<   |jY                  dz      sdC} n)dz   dz   t        jY                  dd0            z   dz   } s:|3j                  dWdt         dt        jY                  dd0            z   |       		 yjY                  d      xs v}t        j                  z      j                         } |3j~                  ddt        q      bct        r      x|utd   dG Kr|3j                  de       pux|3jY                  d      |3jY                  ddr      |3jY                  d      |3jY                  d      |3jY                  d      |3jY                  d      dSY<    |(R|S       
 d&WiS c c}E}Dw c c}}w # |
$ r  t        $ r=}tb        j                  dY       |3j                  dWt              Y       Y d}~Bd}~ww xY w)u  야외 lane 샷 처리 (Stage D → 2026-07-16 사용자 확정 재설계).

        - 레인1(map_marker), 팩 v5 (2026-07-24 사용자 지시 — 마커 맵
          단계 복원, i2i): base map(클린 canon map)→geometry(LLM)→
          **i2i 마커 맵**(이미지 모델이 1:1 캔버스로 CAM·시선·슬롯
          마커 작화, 코드 드로잉 금지 준수)→마커 VLM 검증(원본 대조
          2이미지, 소진=fail-closed)→스토리보드 스케치(gpt edit,
          참조=마커 맵+geometry ID-free 텍스트 절)→leakage VLM gate.
        - 레인2(structure_plate): 맵·마커·마커 스케치 **제거** — A/B 정책
          entry(ab_select_pending)만 기록하고 일반 경량 콘티 경로에 병합.
          finalize(finalize_structure_ab_entries)가 ready/bypass/failed 확정.

        persisted plan 소비 직전 재검증(fail-closed), camera_direction
        결손=AppError(Codex 배선 조건 ③). 팩이 마네킹 저작(v14+)이면
        진입 시 하류 교체 계약 3플래그를 요구한다(마네킹 유출 1층).
        반환 {"lane_contis": {tag: {...}}}. 샷 단위 실패 격리(leakage 소진
        =failed). 사이드카 지문(lane_records.json)으로 재개.
        r   )AppErrorcall_structured)r	  png_part)compute_input_fingerprint)build_group_shot_reconstructorlane_bindings_by_tagrevalidate_persisted_planvalidate_group_parity)rP   rS   rV   rT   _ANCHOR_SKETCH_PACKS_PLATE_LOOK_PACKS_VIEW_SKETCH_PACKS_coord_firstbuild_leakage_schemabuild_marker_annotate_promptbuild_marker_check_schemabuild_marker_check_user_linesbuild_marker_sketch_promptlane_conti_fingerprint_payloadload_marker_check_sysmarker_check_user_headerr:   rQ   run_marker_geometry_shot)archive_stale_outputload_sidecar_recordssave_sidecar_recordsr.  )load_promptr-  outdoor_lane_planNz(step.missing_input.shot_conti_light_laneua   outdoor_lane_plan 체크포인트 부재 — lane pipe ON 상태에서는 lane plan 선행 필수i  )codemessagestatus_codero  rn  rp  shot_stagingrr  shot_selectionscene_director)
staging_cpvalidator_cpselection_cpdirector_cp)	lane_datar  reconstructuG   lane plan 그룹 parity 위반 — outdoor_lane_plan 재실행 필요: z;    r;  rv  plan)group_shotsz-step.contract_violation.shot_conti_light_laneu,   persisted lane plan 재검증 실패 (group=z): u=   shot_conti_light: lane 바인딩 없음 — lane 분기 no-opr'  rq  outdoor_structure_seedscenesr   r`  r   Sr  camera_directionr  )is_selected)build_pose_clauseslane
map_markerz$step.config.lane_mannequin_chain_offu   lane sketch 팩 vu   (마네킹)인데 still_bgfirst_enabled/still_bgfirst_full_enabled/still_lane_prev_bgfirst_enabled 가 모두 ON 이 아님 — 마네킹 콘티는 배경/엔티티 교체 계약과 짝으로만 유효하다 (마네킹 유출 방지, fail-closed))r]   rR   mannequin_chain_contractmarker_map_sketchleakage_judge)versionr   r   marker_sketch_leakager   lane_marker_map_checkr-   zlane_records.jsonTparentsexist_okparse_no_conti_exempt_tagsbgfirst_no_conti_exempt_tagsc                      |       S r4  rM  )r  r/  s    r"   r  z4ShotContiLightStep._run_lane_conti.<locals>.<lambda>  s	    )A,r$   )keygroup_idnone
segment_id)r  r  r  structure_plate)resolve_structure_bg_source_seed_png_pathmissing)shot_keyr  r  	seed_pathseed_statusab_select_pendingseed_asset_id)r;  r  r   r  	bg_sourcebg_path	bg_reasonrs  failedu   outdoor_place_spec 부재)r;  erroruR   operator_exempt short-circuit — 운영자 무콘티 선언, 유료 시도 생략uj   shot_conti_light %s: 운영자 무콘티 예외 — 유료 시도 없이 계수 제외 대상으로 표시ru  map_asset_idz(lane=uB   ) base 자산 결손 — outdoor_place_canon 산출 필요 (group=)rt  master_asset_idu   ) canon master 결손/무효 (z, asset=u8   ) — lane 콘티의 장소 외형 권위 필요 (group=uZ    shot_staging camera_direction 결손 — lane 스케치는 카메라 연출 메모 필수)r   r   r  
pose_canonpose_fixcarriedperson_visible)visible_short_idsbg_onlysegment_label_en)rs  vshotr  r  r/  
place_textpose_clauses
carried_enmapr  r   F)
geometry_packmarker_geometry_contractsketch_packgeometry_text_versionrS  marker_contractmarker_max_attemptsmarker_judge_modelgeometry_judgemarker_map_size)r   r  
roll_countcritique_enabledextralane_sketch_z.pnglane_marker_map_input_fingerprintleakagehas_marker_leakagemarker_check
markers_okmarker_map_sha256
image_pathbase_map_pathbase_map_asset_idmarker_map_pathmarker_promptmarker_attemptsmarker_best_effortmarker_pick_indexmarker_pick_countmarker_pick_why_komarker_modelgeometryr   reused)rt  r(  z$fixed structure and its surroundings)rs  r  r  rx  r/  r@   r   r  )rT  r@   
)require_anchorsrequire_viewcoord_firstr$   )marker_map_models)pick_best_marker_mapud   shot_conti_light %s: 마커 맵 검사 소진 — 모델을 %s 에서 %s 로 바꿔 다시 그린다lane_marker_map)rN  r   r  r   text)typer]  zORIGINAL CLEAN SITE PLAN:zANNOTATED SITE PLAN (to check):)r   schema_namer  )r  checkr   r  u.   

[REGENERATE — the previous attempt failed zthe marker check: 
details_koz). Draw exactly the specified markers and z!change nothing else on the plan.]u3   marker map 을 한 장도 못 그렸다 — 모델 z, )r;  r%  marker_models_tried)base_png
candidatesrT  r@   r  r   r  r`  uy   shot_conti_light %s: 통과한 마커 맵이 없다 — %d장 중 %d번째를 VLM 이 골랐다 (%s). 시도한 모델 %spick_why_ko)rO  rP  rQ  rR  rS  rF  rb  r~  )	r  r1  rT  r2  r3  camera_direction_enseed_look_attachedplate_attachedr@   z>Shot CAMERA DIRECTION (the sketch is allowed to follow this): zThe storyboard sketch to check:sketch_attemptsu.   

[REGENERATE — the previous attempt leaked zstaging markers: z. Remove every marker symbol.]zmarker leakage u   회 소진: )r;  r%  rD  u    shot_conti_light lane: %s 실패r  attempts)r;  rI  rJ  rK  rL  rF  rM  rT  geometry_attemptsrD  r   )rC  rT  rF  rM  rN  rO  rP  rQ  rR  rS  rH  rD  r   rM  )fapp.core.errorsr  app.modules.llm.llm_clientr  r  r	  r  %app.modules.pipeline.multiroll_selectr  &app.modules.pipeline.outdoor_lane_planr  r  r  r  r)   rP   rS   rV   rT   r  r  r  r  r  r  r  r  r  r  r  r  r:   rQ   r  rp   r  r  r  r   r/  app.modules.prompt_loaderr  r9   r   r   joinsortedr   r   r   r  r   r  r  r  r  r   r*   r   r~   r   r  r   updater   r#   r1   r.   r   mkdir!app.services.still_recipe_servicer  rv   r   r  r   r   r   is_filestatst_sizestripr  r   r	   r  r   rn   r   r   r   r  r  rZ  r[  ranger   r  lenLANE_LEAKAGE_MAX_ATTEMPTSr   	exception)r   rc  r  r  r  r}  re  r  r  r_  r  r  r	  r  r  r  r  r  r  rP   rS   rV   rT   _anchor_sketch_packs_plate_look_packs_view_sketch_packsr  r  r  r  r  r  r  r  r  r:   rQ   r  r  r  r  r  _conti_modellane_cpr  bindingsr  r  r  parityr  r!   
violationsr  r  seed_cpseed_groupsr  vshot_by_keyscr   r  r   r   r  
cam_by_tagr  r  r  b_mannequin_shots_pack_stampleakage_sysmarker_check_sysr  plate_look_ongeometry_config
_geo_judgeleakage_configmarker_check_configr  _marker_judge_modelrecords_pathsidecar_exempt_settings_parse_exempt_lane_exempt_tagsr'  	_vis_sidsr   r  
seed_entryr  r!  r"  r#  rs  r  base_mapbase_asset_idrw  r(  _mpr  r0  r  rx  _tagr2  fixr+  r1  fingerprintsketch_pathrL  prev_recg_outrT  annotate_prompt
check_userrF  marker_meta
marker_png	marker_okrZ  r[  _models_m_a_plancurrent_annotate_prev_model_candsr  	m_attempt_idx_picksketch_promptr  r  verdictrv  r  r  r   _marker_prompt_marker_shar/  s                                                                                                                                                      @r"   _run_lane_contiz"ShotContiLightStep._run_lane_conti  sV   > 	->	
	
	
 	
	
 	
 	
 	
 	
 	
*	
 	

 	E9	
 ,,-@A? ?>    KK+1r	'	2,,-AB}"))&"599(BGM2 511.A334DE334DE223CD	
 '[#
 ?)+/99VBQZ+@A    )--"5;<Ch',EeT*eii.AT.I2		&!'R'(<(BCJ HFse3O))JrN34 !$  =" KKWX!2&&--.CD B++FB7;;b   	,,-EF}"))&"599(BGM2 112BC24%2**626::" $!#$B&BzffWb)/R/ff\*;H#&r7- "%c(,:;qR	CH:67 0$ //?
%'
#((488"EKKBff]+RVVL-AB~#/FF-.4" Qs2wir#c(45 L 	K	
 #..*
*$!QuuV},IaL-8 * 	 
 %(?(AA //1;'(@'A BJ J   ( !<(!*"8*#, ,/F/HH 1
'
 "/0HI

 11IJ--/	04EE &1J'KMt228b91$2E2EF
1G\3JKd117R8#g|%<>""4#6#6#<"=9'99!44&|4dT2
 	A	
 *$&DbIK ')224	((>??CAnGBCy-8J-CV9D
 v~o%E
  %K (((__S17R
 1L "t1SE]'"/(nn_= *x 8 EI1-	7I .(nn_=E",.."A *x 8 EI'#'   OOC(.B33F;DH#>  @ S$55#:  
 ?@CE  !$$S)/REyy06BH!IIn5M		(#t+tH~'<'<'>C%vdV ,DDG5K !$  #45;J#ii(9:O +5d:&$Ks{{}xxz))Q.o"G"e6$ 0  *~Xo5H I&&)U!-
 %(	 	 !+s 3 9r@@B#C%  K K !$  ))#.4"5ELL3.>@ A$R0J8n//1G #b'3s8,D-|,2D:L>>*-388>D"C )y)4"+--"5">"YY'7>?AG ,//3 :+//3:79 
 45)%&'9%:)!-&	 T(^,-' "4
#345-/1 !& &<2&4 9 $?0$2 .C#/ (H+L*=&0'6+%)KT "l3%t$<<K%*:3%t(DDO{{3'-2H&&(#**,LL!45D\\),277(*-23\\.17R<< "%)*
 LL!45NN#..022;)+<< 345  ";/ #+ '4	
 %($8 "*n!= #+,,"? %-LL1B$C (0||,e(5 '/ll3F&G '/ll3F&G (0||4H'I  "*n!=!" &\\*5#$ %LL3%& $<<1'(  !+. !LL(2(7 !   - 1f0)#,- BA#=#2"&":":"< !,
 #?%#;# --EFii = 434 512$04%6	!7 	88  02.0 
!	 ,-,3 HGb#( AA E$GR b$G "G H $3   02).%FI, ,;(&"NN!U #[&: '- "+-X/?.,!,$"&J '
C $3/1A"(*="("=?!'*"("CE!*-/ 23':$;&*&>&>&@$L 09E+,#''5$(	 MM*|,2y#J K (LM./ l..|R@AB F	F
 >> %[ */j !
 "#+#X&*ii&8%9$;04W	 %  !/!(#)!)'?&*&>&>&@':D #4LE!&uJ#(>L&
CNNRS[$(E'N		'*	,
 LL+/*.(*-f++099]B+G%*7^%1,0M !  !;#ii6<")%!-&(8',#0#;
! --*7T*%&RA	'*,$Q(AA(EFG#C)<C&{C8-/"($?%5$68 #)"CE!#( -.'5$;&*&>&>&@G 07E+,";;';<!%LM-. gkk,;<= ;	; +  G8 LL'-89G!'++lB"?@A !( !   &  23F !..4>>@KELL {+&"/ #O 4),!"'
"3$   $.$3  
 &1$ ,!/#(99->#? ',ii0De&L%*YY/B%C%*YY/B%C&+ii0D&E %		. 9%0"'+GCL. !w7A @D {++A
JHD     6=HCH=	sF   /AC&BAC"#AC&D!AC"	GAC"CAC"C"AD-C02AD(D(AD-r  c                 J   ddl m} ddlm}m} ddlm}m} | j                  d      }|xs i j                  di       j                  di       xs i }| j                  d      }	|	xs i j                  di       xs i j                  d	i       xs i j                  d
      xs i }
|
rpddl
m} |j                         D ci c]O  \  }}||
j                  |      )i |xs i d ||xs i j                  d      |
|         int        |xs i       Q }}}ddlm}  ||| j!                               }| j                  d      xs i j                  di       }| j                  d      }|xs i j                  di       j                  dg       xs g } || j                  d            }g }i }|D ]  }|j                  d      }|t#        |      }|j                  d      r|d   ||<   |j                  dg       xs g D ]\  }|j                  d      }| ||t#        |      f|      s,|j%                  |t#        |      |j                  d      xs dd       ^  |r|sFt&        j)                  dt+        |      t+        |             dddt,        | j/                         di idS | j                  d      }i }|xs i j                  di       j                  dg       xs g D ]=  }|j                  d      }|j                  dd      xs d}|-|s0||t#        |      <   ? ddlm}  || j2                  | j4                  ||      } ||j6                  | j4                  | j8                        }t;        |j6                        | j4                  z  dz  | j8                  z  dz  }t=        t?        |d d!            xr t=        t?        |d"d!            } t=        t?        |d#d!            }!i }"| s|!rz| j                  d$      }#|#xs i j                  di       j                  d%g       xs g D ]<  }$|$j                  d      }tA        |t"              s%|$j                  d&      xs d|"|<   > i }%| rWdd'l!m"}&  |&|j6                  | j4                  | j8                        }'| jG                  |"|||||||'|d(k(  )	      }(|(j                  d*      xs i }%dd+lm$}) |%j                         D ]^  \  }}*tA        |*t              s|*j                  d,      d-k(  s,|*j                  d.      s> |)|      \  }+},t;        |*d.         ||+ d/|, <   ` |%r~dd0lm%}- |%j                         D ./ch c]+  \  }.}/tA        |/t              r|/j                  d1      d2k(  r|.- }0}.}/|D 1cg c]'  }1 |-t#        |1d         t#        |1d               |0vr|1) }}1i }2|!r|xs i j                  di       j                  di       xs i }3| jM                  |||3|"||||d(k(  3      }4|4j                  d4      xs i }2dd+lm$}5 |2j                         D ]7  \  }6}7|7j                  d5      }8|8s |5|6      \  }}t;        |8      || d/| <   9 t=        t?        |d6d!            }9i }:|9rdd7l'm(}; dd8l!m)}<m*}=m+}> dd9lm,}?m-}@m.}A dd:lm$}Bm%}C |xs i j                  di       j                  di       xs i }D|D 1ci c]7  }1 Ct#        |1d         t#        |1d               |1j                  d      xs d9 }E}1|D 1ci c]h  }1t#        |1d         Dj                  t_        t#        |1d                     xs i j                  d;      xs |j                  t#        |1d         d      j }F}1 |<|j6                  | j4                  | j8                        \  }G}H |?|      D .cg c]  }.|.Ev r|.|2vr|. }I}.|ja                  d<d<=       |d>z  }J @|J      }K |>|I|H |=G      EF|K|;|jb                  | jd                  | jg                         |d(k(  ?      }: A|J|K       |:j                         D ]7  \  }L}M|Mj                  d5      }N|Ns BL      \  }O}Pt;        N      ||O d/|P <   9 dd@lm4}Qm5}R | jm                         }Sd }Td }Ud }V|Q |R|S      dA}W|Stn        k7  r|xs i j                  di       j                  di       xs i }T| j                  dB      }X|Xxs i j                  di       xs i j                  dg       xs g D ci c]2  }|j                  d      |j                  d      |d    d/|d    |4 }U}| jq                         }VddCl
m9}Ym5}Z  |Z|Y      WdD<    |||||||| ju                         SW|d(k(  TUV| jw                         | j!                         E      }[| jy                  |[d   |2|%       ddddF}\|%rddGlm=}]  |]|%[d   |H      }\|%j}                         D /cg c](  }/tA        |/t              r|/j                  d1      d2k(  r|/* }^}/ddIl?m@}_  |_t?        |dJd            }`|%j                         D ]w  \  }}*|`v stA        |*t              s|*j                  d1      d2k(  s1|*j                  dK      dLk(  sFd<|*dM<   t&        j                  dN||*j                  dO      xs dd dP        y t+        ^      \dQ   z   }at        dR |^D              |\dS   z   }bt        dT |^D              |\dL   z   }c[d   |2dU}dStn        k7  r RS      ddV<   | r|%ddW<   |9r|:ddX<   [dY   az   |[dZ   bz   |[d[   cz   t,        | j/                         ddS c c}}w c c}/}.w c c}1w c c}1w c c}1w c c}.w c c}w c c}/w )\Nr   r-   )build_selected_keysr  )resolve_shot_plate_maprun_shot_conti_lightshot_ref_classifyro  r`  background_share_planr  
shot_plans)apply_share_plan_prevprev)#force_person_visible_for_charactersshot_continuityrr  r  r  r   scene_headingr   r~  r  r  uO   shot_conti_light: 샷/분류 데이터 없음 — no-op (shots=%d, classify=%d)r%  )applicable_countcompleted_countfailed_countr?   config_hashro  r  primary_location)derive_location_by_sceneimagesrH  rN   Foutdoor_lane_plan_enabledrI   
scene_savesegmentsr]  )load_bg_assignment_any_statusr_  )	rc  r  r  r  r}  re  r  r  r_  r'  r.  r!  seedr"  r  r
   r  r  )r`  ra  rb  rc  rd  r}  re  r_  r&  
plate_pathrf   r  )load_bg_groups_and_assignmentplate_candidates_by_locationrun_plate_authority)rl  r  r  rm  place_enTr  zplate_authority.json)tagsr  r  cands_by_locr  place_text_by_scener  call_structured_fnjudge_modelr   r  r_  r8   )rS  
conti_packr  rE   rG   )r`  ra  r  r  r  re  r   r@   r  r_  rb  staging_by_keychar_refs_by_tagno_plate_contivisible_char_sids_by_tag)
applicable	completedr$  )finalize_structure_ab_entries)r'  r%  ra  r  r  r;  r$  operator_exemptu[   shot_conti_light %s: lane 실패 — 운영자 무콘티 예외로 계수 제외 (error=%s)r%  x   r  c              3   j   K   | ]+  }|j                  d       dk(  s|j                  d      rd - yw)r;  rv  r  r   Nr   r   r   s     r"   r   z.ShotContiLightStep._execute.<locals>.<genexpr>U  s3      'a55?d*aee4E.F <   13r  c              3   j   K   | ]+  }|j                  d       dk(  r|j                  d      sd - yw)r;  r$  r  r   Nr  r  s     r"   r   z.ShotContiLightStep._execute.<locals>.<genexpr>\  s4      'a55?h./0 <r  )r%  	map_contir  
lane_contiplate_authorityr  r  r  )Cr1   r.   r  r  r  rp   r  r  r   r   rw   r  r  r   r   r  r   r   r   r   r  r{  rs   r   r  r   r   r   r   r   ru   rv   r   r   r  r  r/  r   r  rm  r  r  r  r  rl  r  r  r   rt  r   r   r  r9   r:   rt   r{   r   rF   r$  rx   r^  r  valuesru  r  r   sum)er   r  r.   r  r  r  r  classify_cpra  _sp_cp	_sp_plansr  _t_cr  r  r  r  r}  r`  r  r  r   r  r   r  rd  primaryr  r  r  re  lane_pipe_onmap_conti_onrc  scene_save_cpsegr'  _load_assign_any_assign_by_key_lanelane_result
_pt_seedbg_e_si2_shi2r   r  r   _map_lane_tagsr\  r&  rb  
map_resultr/  r   r!   r   plate_select_onr  r  r  r  r  rl  r  r  
_parse_tag_tag_ofclassify_scenes_allr  place_by_scene
_bg_groupsr  eligibleauthority_records_pathauth_sidecarr  _entry_p_si_shir  _conti_pack	_selector_classify_scenes_staging_by_key
_char_refs	_extra_fp_staging_cp_cam_selr   resultstructure_deltar  _map_entriesr  _exempt_tagslane_applicablelane_completedlane_failedro  se                                                                                                        r"   _executezShotContiLightStep._execute  sc   ,	
	

 001DEB##FB/33GR@FB 	 ++,CDl+1r66vrBHb
#l
"! 	  -224 5FB  !}}R(4@b @6+@rv.	",? @:>rxR.I
 5  	
 =D::<> ''(9:@bS_ 	
 112BC$"))&"599(BGM2+&&'78
 )+B&BzRBvvo&%'%8r"ffWb)/R/ff\*;"BC>=A')&)#h')vvm'<'B 0 * NKK*+.u:s>7J
 %&#$ !"0#002!2  001AB(*$"))&"599(BGM2MB&Bff/4:G~')0c"g&	 N	
 5GGT__m^
 +!!4??DOO
	 &&'$//9HDoo '( 	
 H95A
 J78%@%HI 	 H95AC ')< 66|DM$"))&"599*bIORO  WW]+b#&&)ggfo&;KO P ') #3%%t#I..'%"3-+#1w / 
K &//-8>BK
 &++-Br4({+v5y)",R.KD%3793FIaw/0 . I #."3"3"5""5$!Q!!T*quuV}/L "5  "
  %$!c!M"23S<5IJ)* u   &(
"''377"EK  ,,- /'++w - 	J $5;J I(..0
UIIl+'nGB/3AwIAcUm,	 1 H:EBD*,B 
 
 "''377"EK     A Am,-s1\?/CDEE-(.B/     A Am$%(,,SQ}5E1F-GH CC
OH(,,S=1A-BBGH
    )F%%t)I%J )88a((Qj-@ 8   MM$M6%,/E%E"/0FGL1#+9*E!1$2$#2$66#22"668wO !!7F / 5 5 7fZZ- *4 0IC15bIQtfo.	 !8	
 ))+	
'%i0
	 &"''377"EK  44^DK "'R,,VR8>BS"%,)+,,  66-(4FF<(4 m$%Qr,'7&892=,   //1J
 4@3II/0%)!/$$&$'7?,*'224 &*%C%C%E%
. 	**8j+	7 *+aH <'h'-O #))+
+!!T"quuV}'D + 	 
	
 2H<bAC!'')FBl"z"d';FF6Nl2FF8$0(,$%/02RVVG_5JDS4Q * l+ol.KK '  k*	+ 	  ' 
 h'( 	 X&# 
 &!,Y!7D !,D &5D"# &'9 :_ L%&78>I">2[@,,,.
 	
kr"x 
bB
s2   ?Am;&0n,n%<n'A-nn-7n-n r4  )resume)__name__
__module____qualname____doc__r   r   rt   staticmethodru   rx   r   r   r  r   r   r   r   r   r$  r^  r  r   r   r  r  r  r  rM  r$   r"   r6   r6      sW   [Zc Zx
# 
 F F F 
D 
 
& 4S>  DE4S> ENS Xd38n5M "BP 15	aS#Xa cNa d38n-	a
 
aZ k
 k
 S#X	k

 c3hk
 #s(^k
 CH~k
 k
 k
 
c3hk
Zc` ~, #s(^~, cN	~,
  S>~, S#X~, ~, T	?~, CH~~, ~, 
c3h~,@|
S |
S#X |
r$   r6   r4  )!r$  rn   ro   loggingpathlibr   typingr   r   r   r   rq   r   rr   r	   r   r   	getLoggerr!  r   rs   r{   r~   r   r   r   r#   r|  r   r   r*   r4   r6   rM  r$   r"   <module>r*     s        , , + :			8	$  ! 4    )  04GT#s(^,G	#s(^G    %& ! $'  #z
 z
r$   