
    Ljx~                        d Z ddlZddlZddlZddlZddlZddlZddlZddl	m
Z
 ej                  j                  d e e
e      j                               ddlZddlZddlZddlZddlZddlZej8                  dz  Z e
e      j                  dz  ZdZdZ djC                  g d	      Z"d
ddddiddd
dddiddidddgdddddgdZ#djC                  g d      Z$d
dddd
dddiddidddgddidgdZ%d Z&d Z'd Z(d Z)djC                  g d       Z*d
dddd
dddiddidddiddd
dddiddid!d"d#gddd$g d$ddidgdZ+d% Z,d& Z-djC                  g d'      Z.d
ddddiddd
dddiddidddgddd(d)dgdZ/d* Z0djC                  d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;e d<g      Z1d= Z2djC                  g d>      Z3d?Z4d@Z5dA Z6dB Z7djC                  d+dCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRe d<g      Z8dS Z9dT Z:djC                  g dU      Z;dVZ<dWZ=dXZ>dY Z?djC                  g dZ      Z@djC                  g d[      ZAd\ ZBd] ZCdjC                  g d^      ZDdjC                  g d_      ZEdjC                  d`dadbdcdddedfdgdhdidjdkdedldmdndodpeDeEdqdrdsdtdudvdwdxdydzg      ZFd
dddiddid{d|d}gdZGdjC                  g d~      ZHd
dddddididgdZIdjC                  g d      ZJdjC                  g d      ZKdjC                  g d      ZLd ZMd ZNdjC                  g d      ZOdjC                  g d      ZPdZQd ZRd ZSd ZTdZUdjC                  d`daddddedddddddeddmdndodpeDeEdqdrdsddudvdwdxdydzg      ZVdZWdjC                  g d      ZXd ZYd ZZ	 	 ddZ[djC                  g d`dadbdcdddeddddddeddddddddedeDeEdqdsddudvddxdydz      Z\	 	 	 ddZ]djC                  g d      Z^	 	 ddZ_	 	 	 ddZ`djC                  g d`dadddddeddddddddeddmdndodpeDeEdqdrdsddudvdwdxdydz      ZadZb	 	 ddZcdjC                  g ddÑdđdődedƑdǑdȑdedɑdʑdˑd̑d͑dΑdϑdsdБeDdёdґdӑdԑdՑd֑dבdؑdّdڑdۑdܑdݑdޑ      Zdd߄ Zed ZfdjC                  ddg      ZgdjC                  g d      Zhd Zid ZjdjC                  g d      Zkd
ddg ddddg ddddd
ddg ddddidddgdddg ddZlg dZmd ZndjC                  g d      Zod
dddiddidddiddg ddZpddZqdjC                  g d      ZrdZsddZtdZudjC                  g d      Zvd ZwdjC                  g d      ZxdjC                  g d      ZydZzdZ{d Z|d Z}ddZ~djC                  g d       ZdjC                  g d      ZdZd Zd ZddZddZdjC                  g d	      Zeufd
ZdZd Zd ZeudfdZg dZdZdZd Zd Zd
ddg ddddg ddddd
ddg ddddiddidg ddddg ddZd ZdjC                  g d      Zd
dddd
dddiddidddgddidgdZdjC                  ddg      ZdZd  Zd! Zd" Zd#ZdjC                  g d$      Zd% Zd&Zd'Zd( ZdjC                  g d)      ZdjC                  g d*      Zd+Zd, Zd-Zd.Zd/ZdjC                  g d0      Zd
ddddiddd
dddiddiddiddid1g d1dddddgdZd2Zd3 ZdjC                  g d4      Zd
dddidddidddid5g d5dZd
dddidd
dddiddidddgddddid6g d6dZdjC                  g d7      Zdd8Zd9 ZdjC                  g d:      ZdjC                  g d;      Zd< Zd=Zd>Zd?Zd@ZdA ZdB ZdC ZdD ZdE Zi ddFdGdHddIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[dd\d]d^d_d`dadbdcddi dedfdgdhdidjddkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddi ddddddddddddddddddddddddddddddddddddddZd ZddZd Zedk(  r e        yy(  uU  s20 — 번호 마커 블록 다이어그램 → fp 체인 (사용자 지시, 2026-07-05 저녁):

  - 기반 = **s18 이전 코드 그대로**(STYLE_FLAT + lean_structure_lines 산출,
    A⁗ containment 반영본) — s19 공간지각 경로가 아님.
  - **LLM 이 STRUCTURE 줄들에 번호(1..N)를 매기고**, 요소 이름을 전부 번호
    참조로 재작성(placed on block 4 식) — 공간 관계/크기어/개수는 그대로.
    이미지 프롬프트에 요소 이름 노출 0 (이름 중립화는 코드 치환이 아닌 LLM).
  - 번호↔이름 대응은 LLM, 한국어 의미는 layout desc_ko 를 코드 조인(발명 0).
  - 렌더 = **A‴ 최종형 스타일 nb2 1장**: STYLE_FLAT 의 no-text 계약 중 숫자만
    "각 블록에 지정 번호 1개" 로 허용 교체. nb2 라벨 습성이 이름 대신 번호
    마커를 그리는지 실험.
  - **fp 단계(사용자 GO)**: 번호 bd 를 BLOCK REFERENCE 로 삼아 기존 확립 fp
    계약(s16.fp_prompt — 참조만/모사 금지+desc+FACTS+스타일 ref+STYLE_2D)으로
    fp 생성(gpt/nb2). 번호 마커는 기존 계약("annotations, never objects")이
    전파 차단.
사용: .venv/bin/python s20_numbered_bd.py [--only all|llm|image|fp|html]
산출: out/blockset/numbered_bd_nb2.png + numbered_fp_{gpt,nb2}.png,
      plans/numbered_bd_v1.json, numbered.html
    N)Pathblocksetznumbered.htmlzGNo text, letters, numbers, labels, markers, legend or compass anywhere.zEach block shows ONLY its assigned number, drawn once as a small plain dark numeral on (or beside) that block; apart from these numerals there is no other text: no letters, no words, no names, no labels, no legend, no compass anywhere.
)3zEYou are given the STRUCTURE lines of an image-generation prompt for auG   flat schematic block diagram — one element per line, each line naminguE   the element and its spatial relations — plus ELEMENT DATA groundingzeach element.AELEMENT DATA is physical-form grounding ONLY; if any of its linesDstill carry narrative residue (events, actions, usage stories, storyuG   wording), ignore those parts entirely — this diagram concerns spatial(arrangement and structure, nothing else. zATask: assign a number (1..N) to every element line, in a sensiblezEstructural order (large ground/container blocks first, then what sitszBon them, then attached openings and small fixtures). Rewrite everyzline so that:z"- the line STARTS with its number,uF   - element NAMES never appear — when a line refers to another elementz=  (placed on X / on the north edge of X), refer to it by thatzB  element's number instead (e.g. 'placed on block 4, in its centrez	  part').zD- every spatial relation, size word and count stays EXACTLY as givenz-  (one exception: frame-edge context, below).z>- APPEND to each line a short clause describing that element'sz?  characteristic TOP-DOWN footprint/silhouette, grounded in itsuG     ELEMENT DATA — just enough that the drawn shape itself reveals whatzC  the element is (a run of parallel treads, a circle, a slatted lowuD     rectangle, a thin line between two posts...). SHAPE ONLY — neverzD  materials, colours, condition or story; never invent what the dataz  does not support.z>- FRAME-EDGE EXCEPTION: when an element is surrounding contextzC  sitting at the drawing frame's edge (per its position), its givenuB     size words measure only the visible sliver — do NOT keep them;z@  describe instead a full-scale neighbouring mass that continueszD  beyond the frame and is cut off by the drawing edge. It must neverz>  read as a small or thin free-standing block inside the site.zD- A CREATOR CORRECTIONS block may follow the ELEMENT DATA. Apply thezA  SPATIAL facts it states (what attaches to what, where somethingz=  stands, that it is a separate added-on structure...) to theuB     relevant lines — but keep materials/finishes out of the lines:z!  this diagram is structure only.zA- PHYSICAL / LOGICAL SANITY: the result must read as a physicallyuE     plausible real property — every enclosed building needs its entryz@  opening, and circulation must connect all the way (approach ->zB  entrance -> grounds -> building entry / stairs -> upper levels);zB  nothing floats and nothing is sealed off. If the given lines arezC  missing a connection that common sense makes physically necessaryzC  (for example a building with no way in), ADD one minimal line foruB     it — continue the numbering, place it sensibly relative to thez?  existing elements, and add it to the legend with ' (assumed)'zA  after its name. Smallest sensible addition only; never redesignz  what is given.zEAlso output a legend mapping each number to the original element namez!(exactly as written in its line).objectFarraytypestring)r   itemsinteger)numname_enr   r   )r   additionalProperties
propertiesrequired)numbered_structure_enlegendr   r   )z=You rewrite element descriptions for an architectural drawingzCpipeline. You get one real property's elements (name, kind, currentzDone-sentence Korean description, and the source quotes that groundedz)them), plus optional creator corrections.r	   zDThe current descriptions were written from scene texts and may carryz@NARRATIVE: past or one-off events, actions by people or animals,zCusage stories, moments of motion, view/camera wording, or authorialuD   phrasing ('~하게 배치했다'). None of that belongs in a drawingu/   pipeline — it makes image models hallucinate.r	   zCRewrite EVERY element's description as ONE short Korean sentence inzCpresent tense stating only PHYSICAL, VISIBLE facts: what it is, itsuJ   physical form, and its key spatial relation (무엇이 어디에 어떻게u   붙어/놓여 있는지).zC- When a quote describes an event or action, keep only the physicalz@  object or state that exists now because of it; drop the event.zC- No proper names, no story wording, no motion, no time references,z5  no camera/view words, no authorial intent phrasing.z@- Apply the spatial facts of creator corrections where relevant.z?Output every element with its exact given name_en, in the givenzorder.elements)r   desc_kor   c                 2   g }| d   D ]g  }dj                  d |j                  d      xs g D              }|j                  d|d    d|d    d	|j                  d
d       |rd| ndz          i ddj                  |      z   }dj                  t        j                         j                  d      xs g       }|r|d|z   z  }t        j                  dt        |t              }t        j                  d|       t        dt        |d          d       |S )u   desc_ko 정화 패스 — 서사(사건/행위/과거/의도 어투) 제거, 물리·현재형
    한 문장으로 LLM 재작성 (기하/마커/추출 원본 불변, 파생 plan 저장).r   z; c              3   8   K   | ]  }d |d    d|d      yw)[sourcez] quoteN .0vs     s20_numbered_bd.py	<genexpr>z"run_desc_visual.<locals>.<genexpr>   s-      : 7! !H+b75 7s   evidence- r    [kind kind]: r   r	   z
  quotes: z
ELEMENTS:
r   facts_extra

CREATOR CORRECTIONS:
s20_desc_visualdesc_visual_v1zdesc_visual: u   개 재작성)joingetappendS14load_overridesFllmDESC_VISUAL_SYSTEMDESC_VISUAL_SCHEMA	save_planprintlen)layoutlinesequsercorrectionsress          r"   run_desc_visualr@      s,    EJII : !j 1 7R 7: :r!I,wqyk :y"-.0./,qc*R9 	:   499U++D))					!	!-	07R9K,{::
%%!#5t"$CKK #&	M#c*o./}
=>J    c                     t        j                  d      }|d   D ci c]  }|d   |d    }}| d   D cg c]  }|d   |vr|d    }}|r
J d|        |S c c}w c c}w )u]   정화본 매핑 로드 — 누락 요소는 명시 실패(조용한 원본 fallback 금지).r,   r   r   r   u   desc_visual 누락 요소: )r2   	load_plan)r9   r?   r;   dvmissings        r"   desc_visual_maprF      s    
++&
'C.1*o	>o!I,)
$oB	>%+J%7 *%7I,b( |%7G *?5gY??;I	 
?*s
   AAc                 >    dj                  fd| d   D              S )Nr   c           	   3   L   K   | ]  }d |d    d|d    d|d         yw)r%   r   r&   r'   r(   Nr   )r    r;   rD   s     r"   r#   zeldata_lines.<locals>.<genexpr>   s>      %#A Qy\N'!F)C1Y<0@/AB#s   !$r   )r-   )r9   rD   s    `r"   eldata_linesrI      s&    99 %
#% % %rA   c           	         t        j                  |       }t        |        t        |       }d|z   dz   t	        | |      z   }dj                  t        j                         j                  d      xs g       }|r|d|z   z  }t        j                  dt        |t              }|d   D ]  }|j                  |d   d	      |d
<    ||d<   t        j                  d|       t        dt        |d          dt        |d                 |S )NzSTRUCTURE lines:
uU   

ELEMENT DATA (name [kind]: physical form facts — ground each shape clause here):
r   r)   zi

CREATOR CORRECTIONS (apply their SPATIAL facts to the lines; materials do not belong in this diagram):
s20_number_assignr   r      (LLM 최소 보완 요소)r   source_leannumbered_bd_v1z
numbered: r      줄 | legend )S18lean_structure_linesr@   rF   rI   r-   r0   r1   r.   r2   r3   NUMBER_SYSTEMNUMBER_SCHEMAr6   r7   r8   )r9   leanrD   r=   r>   r?   rows          r"   run_llmrV      s   ##F+DF		 B 4'113?3KLD ))					!	!-	07R9K G 	  %%#]D-
HC8}I0LMI CKK #&	Js36789 :3x=)*, -JrA   )z@You analyse the scenes and shots that play at one real property,z?to protect the SPATIAL TRUTH of the elements the camera dependszon.r	   z?This analysis feeds an EXTERIOR-ONLY site diagram. Include onlyzAexterior and boundary elements: grounds, approach routes, stairs,z=terraces, building shells, and boundary openings set in OUTERz@walls (entrance doors, exterior windows). Interior-only elementsz<(rooms, interior thresholds, furniture, curtains) are OUT ofu   scope — skip them entirely.r	   z;From the FULL SCENE TEXTS and ALL SHOTS below, identify theuA   exterior spatial elements that matter to the shots — the routesz9people take, the places the camera frames, the thresholdsu@   crossed — especially CONNECTING structures (stairs, entrances,z?gates, passages between levels). For each one state its spatialz<facts exactly as the scenes use them: what it connects (fromz@where to where), what it attaches to, which side, what faces it.uB   Present-tense physical facts only — no events, no story wording.z?Quote the supporting phrase (exact, original language) for eachzfact.r	   z>Match element names to the given ELEMENT NAMES where possible;z@a critical spatial fact with no matching element may use its ownuA   short GENERIC name — never proper names, never character names,zin the facts either.z=CREATOR CORRECTIONS, when present, override conflicting text.z>Output per element: name_en, why_critical_ko (one short Koreanz=sentence: which shots/actions depend on it), spatial_facts_enzA(1-3 short lines), evidence (source + quote). Order by importancezto the shots. 5-12 elements.)r   r   r   r   )r   why_critical_kospatial_facts_enr$   c                    dj                  d | d   D              }t        j                  |      \  }}dj                  d t        |d   j	                               D              }dj                  t        j                         j                  d      xs g       }d	|z   d
z   |z   dz   |z   }|r|d|z   z  }t        j                  dt        |t              }t        j                  d|       t        dt        |d          d       |S )u   씬/샷 원문 전체 분석 — 샷이 의지하는 공간 요소와 그 공간 사실(연결
    출발/도착·부착 벽·방향, evidence 인용) 추출. 미니멀 재작성이 이 관계를
    왜곡 없이 담도록 하는 보호 입력., c              3   &   K   | ]	  }|d      yw)r   Nr   r    r;   s     r"   r#   z%run_scene_critical.<locals>.<genexpr>2  s     ?,>qa	l,>s   r   

c              3   N   K   | ]  \  }}t        j                  ||        y wN)r2   
shot_block)r    kss      r"   r#   z%run_scene_critical.<locals>.<genexpr>4  s%      G'Etq!Q'Es   #%shotsr   r)   z,ELEMENT NAMES (match these where possible): :

FULL ORIGINAL SCENE TEXTS (every scene at this place):

z+

ALL SHOTS AT THIS PLACE (full content):

z1

CREATOR CORRECTIONS (spatial facts, override):
s20_scene_criticalscene_critical_v1zscene_critical: u   개)r-   S13Xscene_textssortedr   r0   r1   r.   r2   r3   SCENE_CRITICAL_SYSTEMSCENE_CRITICAL_SCHEMAr6   r7   r8   )	r9   reconnamesidxsscenesshot_blocksr>   r=   r?   s	            r"   run_scene_criticalrq   .  s     II?F:,>??E##E*LD&++ G'-eGn.B.B.D'EG GK))					!	!-	07R9K:UB#$ @@ 	D
 G 	 
%%$&;T%'CKK#S)	SZ12#
67JrA   c                      	 t        j                  d      } g }| d   D ]&  }|d   D ]  }|j                  d|d    d|         ( dj	                  |      S # t        $ r Y yw xY w)	Nrf   r	   r   rX   r%   r   : r   )r2   rC   	Exceptionr/   r-   )r?   r:   r;   fcts       r"   scene_critical_blockrv   G  s}    kk-. E_'(CLL2a	l^2cU34 )  99U  s   A 	A$#A$);zCYou are given structural data of one real property: STRUCTURE linesz<(machine-derived, verbose), ELEMENT DATA (physical facts perzCelement), a PLACE DESCRIPTION (storey / vertical composition groundz(truth) and optional CREATOR CORRECTIONS.r	   zCThe verbose lines OVER-SPECIFY: size words, fine compass positions,zAfootprint-shape clauses. Over-specification breeds contradictionszBbetween clauses, and contradictions make image models hallucinate.zDYour job is the opposite: write the MINIMUM a drawing model needs tozCunderstand this structure. What you leave unsaid, the model inventsu   naturally — that is intended.r	   zRules:z:- EXTERIOR-ONLY: the diagram never shows the inside of anyz?  enclosed unit. Boundary openings set in outer walls (entrancez<  doors, exterior windows) are the deepest you go; never addz<  interior rooms, interior thresholds or furniture as lines.z=- GENERIC wording only: never proper names or character namesz"  anywhere in the lines or legend.z7- FIRST line: 'LEVELS (placement logic only): ground ->uB     <building, N storeys> roof terrace -> <what is on it>' — statez<  the storey count from the PLACE DESCRIPTION. This is levelz:  LOGIC, never an instruction to draw height or elevation.zB- Then ONE SHORT line per element: its number, what it is, what itzB  is ON or IN (its host), plus AT MOST one coarse position on thatz@  host ('on the roof terrace, west side' / 'attached to the rearz  wall of the building').zB- SCALE, where it aids structural understanding, is YOURS to judgezA  and include briefly (a word or two in the line): the building'szA  storey count on its own line, an element clearly small or largez?  relative to its host, neighbouring masses' comparable height.z=  Judge from the data given; never invent precise dimensions.u<   - KEEP EVERY element that belongs to the property itself —z@  including its roof-level and ground-level fixtures; never dropzA  them. Only surrounding context (neighbouring masses, the publicz7  road edge) may merge into one single unnumbered line.z@- Phrase every relation as FLAT PLAN-VIEW placement (A is on B /uC     at B's west side / attached to B's rear wall) — never elevationzA  storytelling: no 'rises', 'stands above', 'supports', 'on top'.z>- Beyond that judged scale: NO mechanical size enumeration, NOz=  footprint or shape clauses, NO frame-edge phrasing, NO finez<  compass positions beyond the one coarse position per line.z=- SCENE-CRITICAL elements (listed below when present) are thez=  elements the actual shots depend on: their lines must carryu@     EXACTLY the spatial facts given — connection endpoints (fromuA     where to where), attachment wall/side, what they face — neverz;  simplified away, never distorted. A critical connector (az=  stair, an entrance) always keeps its full connection in itsz  line.z<- PHYSICAL COHERENCE: every enclosed building keeps an entryz?  opening and the circulation connects all the way (approach ->zA  entrance -> grounds -> stairs -> upper levels). If a physicallyz@  necessary connection is missing, add one minimal numbered linez-  and mark its legend name with ' (assumed)'.z@- Apply the spatial facts of CREATOR CORRECTIONS; keep materialsz  out.z?- Number the kept elements 1..K in a sensible structural order.zBlegend: every number you kept, with that element's name_en exactlyz?as given in ELEMENT DATA (or the assumed element's short name).)minimal_lines_enr   rw   c           	         t        |       }t        j                  d      }t        j                  |       }	 t        j                  d       t               }dj                  t        j                         j                  d      xs g       }d|z   dz   t        | |      z   dz   t        j                  |      z   }|r|d|z   z  }|r|d	|z   z  }t        j                  d
t         |t"              }|d   D ]  }	|j                  |	d   d      |	d<    	 t        j                  d      }
|
j                  d      dk7  rt        j$                  d|
       |d   |d   dd}t        j$                  d|       t'        dt)        |d          dt)        |d                 |S # t
        $ r t        | |       Y iw xY w# t
        $ r Y tw xY w)uj  v8~ 미니멀 재작성(사용자 재정의: '무엇 안에 무엇+대략 위치'만, 장소
    요소 전부 유지, 과지정=모순=할루시네이션) — bd(①)/도면(①-2) 공용 최소
    구조 줄. v10: 씬-중요 요소의 공간 사실(왜곡 금지) 주입.
    구본(상세 재작성)은 numbered_bd_v1_maximal 로 백업 후 v1 슬롯 교체.fp_place_descrf   r   r)   u_   STRUCTURE lines (verbose, machine-derived — source data, do not copy their level of detail):
3

ELEMENT DATA (name [kind]: physical form facts):
:

PLACE DESCRIPTION (storeys / composition ground truth):
u~   

SCENE-CRITICAL ELEMENTS (spatial facts the shots depend on — keep these relations EXACT; never simplify or distort them):
r*   s20_minimal_structr   r   rL   r   rN   r   minimal_structnumbered_bd_v1_maximalrw   )r   r   r   z	minimal: r   rO   )rF   r2   rC   rP   rQ   rt   rq   rv   r-   r0   r1   r.   rI   S15
desc_blockr3   MINIMAL_STRUCT_SYSTEMMINIMAL_STRUCT_SCHEMAr6   r7   r8   )r9   rl   rD   descrT   critr>   r=   mresrU   oldr?   s               r"   run_minimalr     s   
 
	 B;;'D##F+D*	'(  !D))					!	!-	07R9K57;<FG 62&' N	N
 nnT"#D  (*./ 	0 ,{::55%'<d&(DH~I0LMI kk*+778 00KK0#6 %));$<(^/?ACKK #&	Ic#5678 93x=)*, -JA  *65)*2  s#   F ?F9 F65F69	GGuD   Draw ONE SCHEMATIC BLOCK DIAGRAM of a real property's layout — thez@kind of flat figure a computer program draws: plain solid-colourz?shapes on a plain light background, uniform thin dark outlines.zAFlat schematic drawing language always: no gradients, no shadows,zno texture, no photorealism.uD   VIEWPOINT — top-down, or AT MOST a gentle axonometric tilted aboutzB30 degrees from vertical (2.5D) so slight height reads. NEVER fullz=3D perspective, never vanishing-point depth, never eye-level,zBnever a facade as the main subject. Any level wording in the linesz=below is placement logic, not an instruction to build tall 3Dzvolumes.z@The lines below give ONLY the placement structure (what is on/inuD   what, roughly where). Everything they leave unsaid — exact shapes,uA   sizes, proportions, spacing — YOU decide, so the property readsz+plausibly; keep every stated relation true.uE   Every building is ONE solid block — never any interior rooms, innerzwalls or furniture.!No people, no props, no vehicles.c                 >    t         dz   dj                  | d         z   S )Nz7

STRUCTURE (containment / support / connection only):
r   r   )STYLE_STRUCT_MINr-   r?   s    r"   bd_prompt_minr     s*    JKii3456 7rA   )uC   MINIMAL SPATIAL STRUCTURE — what is on/in what and roughly where,u@   nothing more. All level wording is placement logic only — planz9view stays primary (a gentle 2.5D axonometric tilt is thezApermitted maximum, never full 3D perspective). Draw each numberedz;element with its number as a small plain marker. Everythingz?unspecified (exact shapes, sizes, proportions, spacing, drawingzAdetail) YOU compose yourself as a believable real site plan; keepzevery stated relation true:zOFlat
orthographic plan view: NO 3D, NO axonometric, NO perspective, no
shadows.zOrthographic
plan view by default; at most a gentle axonometric tilt (about 30
degrees from vertical, 2.5D). NEVER full 3D perspective, no
vanishing-point depth, no shadows.c           	      .   t         j                  }t        |v sJ d       |j                  t        t              }t
        |v sJ d       |j                  t
        t              }dj                  |t        t        dz   dj                  | d         z   g      S )N   STYLE_2D no-text 줄 불일치u!   STYLE_2D 플랫 뷰 줄 불일치r]   r   r   )
r   STYLE_2DSTYLE_2D_NO_TEXTreplaceSTYLE_2D_NUMBEREDSTYLE_2D_FLAT_VIEWSTYLE_2D_VIEW_25Dr-   STYLE_2D_EXTERIOR_NOTEMIN_PLAN_HEADER)r?   styles     r"   plan_prompt_minr     s    LLEu$F&FF$MM*,=>E&K(KK&MM,.?@E;;$3/F+G!HH  rA   c                 J   t        |       }t        |       }	 t        j                  d      }||d<   ||d<   ||d<   ||d<   t        j
                  d|       t        | |       t        j                  d|g t        dz         t        | |       t        j                  d|d	t        dz  
       t        | |       t        j                  d|g t        dz         t        | |       t        j                  d|d	t        dz  
       t        | |       y	# t        $ r i }Y w xY w)u   v8 미니멀 줄로 bd(①) 2장 + 도면(①-2) 2장 — 파일명 유지(구본은
    shell 백업), 스타일 계약만 분기.spatial_promptsnumbered_bd_nb2.pngnumbered_bd_gpt.pngnumbered_plan_gpt.pngnumbered_plan_nb2.pngs20_numbered_bd_nb2out_paths20_numbered_bd_gptNrefsr   s20_numbered_plan_nb2s20_numbered_plan_gpt)
r   r   r2   rC   rt   r6   
build_pageimg_nb2OUTBimg_gpt)r?   ppppromptss       r"   run_minimal_imagesr     s!    	cA		B++/0 &'G!"%&G!"')G#$')G#$KK!7+sAII#Q335sAII#QT335sAII%r2557sAII%r557sA'  s   D D"!D"zAkind of flat figure a computer program draws: strict TOP-DOWN 2D,zCplain solid-colour shapes on a plain light background, uniform thinzAdark outlines. ABSOLUTELY FLAT: no bevels, no edge highlights, nozDgradients, no shadows, no shading, no texture, no perspective, no 3Dzfeel of any kind.z@STRUCTURAL SILHOUETTES: draw every element as the characteristicuC   top-down footprint its line describes — a flat structural outlinezCjust detailed enough that the SHAPE ITSELF reveals what the elementz@is; never flatten it to a generic featureless rectangle when itsz;line says otherwise, and never add fine drafting detail (noz>double-line walls, no hatching, no fixtures inside buildings).zCPURPOSE: structural comprehension only. Every building is ONE solidu=   block — never any interior rooms, inner walls or furniture.zAThe arrangement must read as a physically coherent real property:zCentries, connections and levels all working the way the lines belowz	describe.c                 >    t         dz   dj                  | d         z   S )Nz;

STRUCTURE (relative positions, sizes, footprint shapes):
r   r   )STYLE_STRUCTr-   r   s    r"   image_promptr   E  s*    NOii3456 7rA   c                 p   t        |       }	 t        j                  d      }||d<   ||d<   t        j                  d|       t        | |       t        j                  d|g t        dz         t        | |       t        j                  d|d t        dz         t        | |       y # t        $ r i }Y w xY w)Nr   r   r   r   r   r   r   )	r   r2   rC   rt   r6   r   r   r   r   )r?   r   r   s      r"   	run_imager   K  s    SA++/0 &'G!"%&G!"KK!7+sAII#Q335sAII#QT335sA  s   B' 'B54B5)?The FIRST attached image is a rough BLOCK REFERENCE of one realz>property: it tells you only WHAT exists, each element's NUMBERzBidentity and the APPROXIMATE arrangement. Do NOT trace or copy itsuF   composition, block shapes, proportions or spacing — compose the sitezDplan yourself so the place reads as a real, believable property thatz?satisfies the numbered structure below. Its fill colours encodez?height layers only. Keep the SAME numbers on the SAME elements.u   BLOCK REFERENCE (what exists + approximate arrangement; its numerals identify the elements) — never copy its shapes, proportions or spacing; carry the SAME number over to the SAME element as a small plain marker.zCno text, no letters, no numbers, no markers, no legend,
no compass.zeach element carries ONLY its assigned number, drawn once as a small
plain dark numeral on (or beside) it; apart from these numerals no text,
no letters, no words, no other markers, no legend, no compass.c           	      >   t        j                  d      }t        j                  }t        |v sJ d       |j                  t        t              }dj                  t        t        j                  |      ddj                  | d         z   t        j                  |g      S )uZ   (보류 — 사용자 철회) fp 번호 마커 버전. 이력 보존용, 현재 미사용.ry   r   r]   zvNUMBERED SPATIAL STRUCTURE (same numbers as the block reference; draw each element's number as a small marker on it):
r   r   )r2   rC   r   r   r   r   r   r-   FP_NUM_REF_NOTEr   STYLE_REF_NOTE)r?   r   r   s      r"   fp_prompt_numberedr   u  s    ;;'DLLEu$F&FF$MM*,=>E;;t	B
))C/0
1	2 	  rA   )r   z;property: it tells you only WHAT exists and the APPROXIMATEz@arrangement. Do NOT trace or copy its composition, block shapes,u@   proportions or spacing — compose the site plan yourself so thezCplace reads as a real, believable property that satisfies the factszAbelow. Its fill colours encode height layers only. Any letters oru3   numerals on it are annotations — never draw them.)uE   Draw the plan VERY DETAILED — real working-drawing density, so thatz@every element visually reads as WHAT IT IS from its plan symbolsz@alone (there are no labels or numbers to help). Use the standardz!plan vocabulary per element type:c                 D   t        j                  d      }t        j                  d      }dj                  t        j                  |      t        j
                  |d      t        dz   t        j                  |      z   t        j                  t        j                  g      S )up  fp 최종(사용자 재정의): 번호/텍스트 표기 0(원 no-text 계약 복귀) +
    **매우 상세** — 각 요소가 도면 기호만으로 실물로 읽히게. 상세 어휘=
    KIND_DETAIL_RULES(kind 스키마 일반 규칙, layout 실재 kind 데이터 주도).
    ★bd 참조 없음(사용자 지시 '참조 없이') — 배치=FACTS 텍스트가 SOT.blockset_layout_v2ry   r]   F)idsr   )r2   rC   r-   r   r   facts_blockFP_DETAIL_NOTE_HEADr0   kind_detail_linesr   r   rl   r9   r   s      r"   fp_prompt_detailedr     sy    
 [[-.F;;'D;;tE*d"S%:%:6%BB  rA   c                    t        |      }	 t        j                  d      }||d<   ||d<   t        j                  d|       t        j                  |      }|rt
        j                  |fgng }t        | |       t        j                  d||t        dz         t        | |       t        j                  d||r|gndt        dz         t        | |       y# t        $ r i }Y w xY w)	u   fp — bd 이미지 참조 없음(텍스트 FACTS 가 배치 SOT), 이미지는
    드래프팅 스타일 ref 1장만. 무번호·무텍스트·매우 상세(자기설명).r   numbered_fp_gpt.pngnumbered_fp_nb2.pngs20_numbered_fp_nb2r   s20_numbered_fp_gptNr   )r   r2   rC   rt   r6   r0   	indoor_fpNB2_STYLE_LABELr   r   r   r   )r?   rl   pfr   fp_stylerefs_nb2s         r"   run_fpr     s     
E	"B++/0 &(G!"%'G!"KK!7+}}U#H4<$$h/0"HsBII#R335sBII#R!)H:t335 sB  s   C C&%C&)z@- PRESENT VISUAL STATE ONLY: everything you write must be what auC     camera would see standing there right now — colours, materials,z>  age, weathering, look-and-feel; you may add modest realisticzC  detail of that visual kind. NEVER narrate past or one-off events,z;  actions, apparitions or story moments the production dataz?  mentions; keep only the ordinary visible present state such az  fact implies, or drop it,)z?- SURROUNDINGS ARE FREE: neighbouring buildings and surroundingz<  context appear in the attached drawing only as placeholderuB     blocks marking that something stands there — never render themz?  as bare box-like concrete masses. Invent believable, ordinaryz>  surroundings of the same neighbourhood character at your ownz=  judgement (real buildings with real roofs, windows, utilityz@  clutter, street texture). Only the property itself must followz"  the drawing's structure exactly,z=You write ONE image-generation prompt (English) for the finalzAphotorealistic stage of a location pipeline. The image model willz?receive your prompt plus ONE attached simple line-art STRUCTUREzASKETCH of a real property, drawn from a slightly elevated obliquez:view so relative heights, storeys and levels read clearly.r	   zBThe sketch is the single source of truth for WHAT exists, WHERE itz?sits and HOW HIGH everything is. Therefore your prompt must NOTzAre-describe, list or count the layout, its elements, positions oru>   heights — beyond telling the model the attached drawing is az@structure sketch to be translated into real built volumes, neverz)copied as line graphics or drawing style.z3Your prompt covers only what the sketch cannot say:uC   - the place must read as a REAL, LIVED-IN property — inhabited byzC  ordinary residents (weathering, everyday traces; decide the feel,uD     let the model improvise the specifics — do NOT enumerate a fixedz  list of objects),z?- unpeopled; no readable text or signage anywhere in the image,uF   - nothing story-specific — only what any such real place would show,zA- true materials of the regional building type per the productionzE  data below (the sketch's bare lines carry NO material information),zD- one believable camera (your choice) and ordinary neutral daylight,z  documentary tone.z.Write 90-160 words of direct imperative prose.zCA creator-correction block, when present, overrides any conflictingzplace data.zDphoto_prompt_ko: the same prompt in Korean (for the human reviewer).)photo_prompt_enphoto_prompt_kor   r   )0z?You are given NUMBERED STRUCTURE lines written for a flat blockzCdiagram (block-language shape clauses), ELEMENT DATA grounding eachz>element, and a PLACE DESCRIPTION (storeys / composition groundztruth).r   r   uF   wording), ignore those parts entirely — a site plan concerns spatialr   r	   zAReorganise and rewrite them as a SPATIALLY STRUCTURED descriptionuD   for a REAL top-down architectural SITE PLAN — NOT a flat list. Thez>reader must see the containment structure at a glance, like anzoutline:r	   uB   - FIRST line: the overall vertical build in one sentence — statez8  the building's storey count explicitly (from the PLACEz?  DESCRIPTION; estimate only if unstated), then what open levelz-  sits on top of it, and what stands on that.z@- THEN one short section header line per space, ordered from thezB  ground up (ground level around the building -> the building massz>  and its facade -> the open roof level -> what stands on thatz@  roof -> the top unit and its openings -> surrounding context),z@  each followed by indented '- ' lines for the numbered elementsz>  that belong INSIDE that space. Every element appears exactlyz)  once, under the space that contains it.z@- every element line keeps its NUMBER and its spatial relations,z?  and carries a roof-plan shape clause (true footprint outline,z=  roof edges/parapets, tread runs, base rings, leaf-and-swinguC     openings...) grounded in its ELEMENT DATA — never invent beyondz  it.zB- JUDGE the right drawing weight for each element by its role, thez@  way a real site plan does: the property's own elements read atz@  site-plan density, while surrounding context like neighbouringz,  buildings stays simple, brief and subdued.zB- FRAME-EDGE SIZE RULE: size words in the given lines measure onlyz?  what is VISIBLE inside the drawing frame. Surrounding contextz>  sitting at the frame edge (per its position) is in reality azB  FULL-SCALE building whose mass continues beyond the frame and isuB     CUT OFF by the drawing edge — DROP its given size words (thin/z@  small/medium) and rewrite it that way; it must never read as az4  small or thin free-standing block inside the site.zC- apply the SPATIAL facts of any creator corrections present in thez>  data (attachments, added-on structures); keep materials out.u@   - refer to elements by their numbers only — do not reintroducez  element names into the lines,uE   - drawing shapes only — never materials, colours, condition, story.z>Output: plan_structure_en = the structured text as an array ofz@lines (header lines + indented element lines, in reading order).plan_structure_en)z=FULL FIDELITY EVERYWHERE: draw every element, including everyuE   neighbouring building, at the same real site-plan drawing density —zDactual roof-plan outlines, roof edges and parapets, rooftop featuresz>as described below. Nothing is a simplified placeholder block.)uD   EXTERIOR ONLY: this is an OUTDOOR site plan seen from above — showzBonly the exterior: ground areas, building outer shells, roof-levelzBsurfaces and outdoor fixtures. NEVER draw any interior room, inneruD   wall, partition or furniture of any enclosed unit — every enclosedz=volume stays sealed (outer walls and boundary openings only).)zDDraw it in real site-plan drawing density, so every element reads aszBwhat it is from its plan symbols. Use the standard plan vocabularyzper element type:c                     t         j                  }t        |v sJ d       |j                  t        t              }dj                  |t        ddj                  |      z   g      S )u  실외 전용 도면형 번호 다이어그램 v2(사용자 정정: 'bd/fp 중간물' 해소)
    — STYLE_2D(도면 계약, no-text→지정 번호 허용) + 실외 강조 + 간략화 금지
    + LLM 이 roof-plan 수준으로 재작성한 번호 STRUCTURE.r   r]   u   SPATIALLY STRUCTURED SITE-PLAN CONTENT — vertical build first, then each space with the numbered elements it contains (draw each element's number as a small plain marker on it):
r   )r   r   r   r   r   r-   r   )r?   
plan_linesr   s      r"   plan_promptr   R  sh     LLEu$F&FF$MM*,=>E;;	C ))J
	   rA   c                 H   t        j                  d      }t        j                  d      }t        |      }dj                  t	        j
                         j                  d      xs g       }ddj                  | d         z   dz   t        ||      z   dz   t        j                  |      z   }|r|d	|z   z  }t        j                  d
t        |t              }t        j                  d|       t        | |d         }	 t        j                  d      }	||	d<   ||	d<   t        j                  d|	       t!        |        t        j"                  d|g t$        dz         t!        |        t        j&                  d|dt$        dz         t!        |        y# t        $ r i }	Y w xY w)u   도면형 번호 bd — LLM 이 공간 계층으로 구조화 재작성(층수 명시+공간별
    섹션+소속 요소, 사용자 지시 "시각적 공간적 구조화") → gpt/nb2 둘 다.r   ry   r   r)   zNUMBERED STRUCTURE lines:
r   rz   r{   r*   s20_plan_rewritenumbered_plan_rewriter   r   r   r   r   r   r   Nr   )r2   rC   rF   r-   r0   r1   r.   rI   r   r   r3   PLAN_REWRITE_SYSTEMPLAN_REWRITE_SCHEMAr6   r   rt   r   r   r   r   )
r?   rl   r9   r   rD   r>   r=   rewr   r   s
             r"   run_planr   c  s    [[-.F;;'D		 B))					!	!-	07R9K)ii3456FG 62&' N	N
 nnT"#D ,{::
%%"$7#%CKK'-	S#12	3B++/0 (*G#$')G#$KK!7+ sOII%r2557sOII%r557sO  s   <F F! F!)zBThe FIRST attached image is a flat TOP-DOWN BLOCK REFERENCE of theBsame property: use it only for WHAT exists and WHERE things sit inu@   plan. Its numerals are annotations — never draw them. Its flatuE   colours encode height layers only; the layer order is given below —z:translate those layers into clearly visible built heights.)uF   Draw ONE SIMPLE LINE SKETCH of the property's structure — clean thinzCdark lines on plain white, like a quick architect's massing sketch.zEViewpoint: slightly elevated three-quarter oblique view (tilted aboutuC   30 degrees down from vertical) so RELATIVE HEIGHTS read clearly —zBwhich volume rises above which, how many storeys the building has,zBwhat sits on top of what, and how the stair climbs between levels.z>LINES ONLY: no colours, no fills, no shading, no materials, noztexture, no photorealism.u>   SIMPLE: massing outlines, level edges and openings only — noz>drafting detail, no double-line walls, no furniture, never anyzinterior of enclosed units.>No text, letters, numbers, labels, markers, legend or compass.r   u   TOP-DOWN BLOCK REFERENCE (what exists + plan arrangement; numerals are annotations — draw none of them; flat colours encode height layers only).c                 Z    t        | d   d       }ddj                  d |D              z   S )Nlayersc                     | d   S )N
rel_heightr   )ls    r"   <lambda>zheight_lines.<locals>.<lambda>  s    <rA   keyzHEIGHT LAYERS (low to high): z -> c              3   :   K   | ]  }|d     d|d   dd  yw)r   z (h=r   g)Nr   r    r   s     r"   r#   zheight_lines.<locals>.<genexpr>  s0      (#&a y\N$qq.AC#&   )ri   r-   )r9   lays     r"   height_linesr     s:    
!'@
AC+kk (#&( (( )rA   c                     t        j                  d      }t        j                  d      }dj                  t        t	        j
                  |      t        |      t        g      S )u\   선 스케치 = bd 배치 + 높이 레이어 + 층수 설명(desc) → 사선 매싱 선화.r   ry   r]   )r2   rC   r-   SKETCH_REF_NOTEr   r   r   SKETCH_STYLEr   s      r"   sketch_promptr     sO    [[-.F;;'D;;tV	  rA   c                    t        |      }	 t        j                  d      }||d<   ||d<   t        j                  d|       t
        dz  }t        |        t        j                  d|t        |fgt
        dz         t        |        t        j                  d||gt
        dz         t        |        y	# t        $ r i }Y w xY w)
u^   bd → 선 스케치 (실사가 fp 높낮이를 오해 → 높이가 보이는 중간 표현).r   numbered_sketch_gpt.pngnumbered_sketch_nb2.pngr   s20_numbered_sketch_nb2r   s20_numbered_sketch_gptr   N)
r   r2   rC   rt   r6   r   r   r   NB2_SKETCH_BD_LABELr   )r?   rl   psr   bds        r"   
run_sketchr     s    	u	B++/0 *,G%&)+G%&KK!7+	%	%BsOII'/BB.G-H779sOII'2$779sO  s   B5 5CCu   STRUCTURE SKETCH (spatial + height ground truth) — translate its volumes, levels and storeys into real photographic construction; never copy its line style; no text anywhere.zAreceive your prompt plus ONE attached top-down architectural SITEz@PLAN drawing of a real property. Small numeral markers on it arezannotations only.zAThe plan is the single source of truth for WHAT exists and WHERE.z=Therefore your prompt must NOT re-describe, list or count theuD   layout, its elements or their positions — beyond telling the modelz?the attached drawing is a plan to be translated into real builtz=volumes, and that its numerals, annotations, flat colours andz/graphics must NEVER be reproduced in the image.z1Your prompt covers only what the plan cannot say:zA  data below (the plan's flat drawing colours are NOT materials),u   SITE PLAN (spatial ground truth) — translate to real photographic volumes; its numerals are annotations, never draw them; never copy its drawing style or flat colours; no text anywhere.)zAThe FIRST attached image is a top-down SITE-PLAN REFERENCE of ther   uB   plan. Its numerals are annotations — never draw them. The heightuB   layer order is given below — translate those levels into clearlyzvisible built heights.c                    t        j                         }dj                  |j                  d      xs g       }dj                  |j                  d      xs g       }dt        j                  |       z   }|r|d|z   z  }|r|d|z   z  }|S )Nr   photo_appearancer)   !PLACE DATA (production members):
=

CREATOR CORRECTIONS (override any conflicting place data):
,

REAL-WORLD APPEARANCE (production owner):
r0   r1   r-   r.   	loc_lines)rl   ov
appearancer>   r=   s        r"   _photo_author_userr     s    				B266"45;<J))BFF=17R8K/#--2FFD *+ 	,AJNNKrA   c                    t        j                  dt        t        |      t              }t        j
                  d|       |d   }t        dz  }	 t        j                  d      }||d<   ||d<   t        j
                  d|       t        |        t        j                  d||gt        dz  	       t        |        t        j                  d
|t        |fgt        dz         t        |        y# t        $ r i }Y w xY w)uX   [경로 A] ①-2 도면(plan_gpt)을 공간 SOT 로 실사 직행 — 저작 LLM 별도.s20_plan_photo_authorplan_photo_promptr   r   r   plan_photo_gpt.pngplan_photo_nb2.pngs20_plan_photo_gptr   s20_plan_photo_nb2r   N)r2   r3   PHOTO_AUTHOR_SYSTEM_PLANr   PHOTO_AUTHOR_SCHEMAr6   r   rC   rt   r   r   r   NB2_PHOTO_PLAN_LABEL)r?   rl   par   srcr   s         r"   run_photo_from_planr    s    	
&(@!%(*=
?BKK#R(
A
(
(C++/0 %&G !$%G !KK!7+sOII"ASE224sOII"A)=s(C'D224sO  s   C. .C<;C<r   c                    t        j                  d      }t        j                  d      }dj                  t        t	        j
                  |      t        |      t        g      }t        |z  }|j                         s
J d|        	 t        j                  d      }||| d<   ||| d<   t        j                  d|       t        |        t        j                  d| d	|t        |fgt        | dz  
       t        |        t        j                  d| d||gt        | dz         t        |        y# t        $ r i }Y w xY w)u   [경로 B-1] ①-2 도면 → 선 스케치 (기존 스케치 계약 재사용).
    src_name/out_prefix 로 참조 도면(gpt/nb2 산출)만 교체하는 A/B 지원.r   ry   r]   u   참조 도면 없음: r   _gpt.png_nb2.pngs20__nb2r   _gptr   N)r2   rC   r-   PLAN_SKETCH_REF_NOTEr   r   r   r   r   existsrt   r6   r   r   r   r   	r?   rl   src_name
out_prefixr9   r   r   r  r   s	            r"   run_sketch_from_planr  (  sE    [[-.F;;'D	tV	 
B /C::<71#77<++/0 (*Gzl(#$')Gzl(#$KK!7+sOIIZL%r-@#,F+GH557sOIIZL%rH557sO     D; ;E	E	zDThe sketch is the single source of truth for WHAT is built, WHERE ituD   sits and HOW HIGH everything is — never re-describe, list or countz>that. But the final image must NOT look like the sketch merelyuB   photographed: it is a standing FILM LOCATION — a complete, real,zinhabited place between scenes.zAStudy the FULL ORIGINAL SCENE TEXTS below to understand who liveszChere and how they live. From that understanding, ADD to your promptz>the incidental, everyday side-elements such a life would leaveuD   around this place — your own judgement, grounded in the scenes; wezCgive you no fixed list. Exclude anything that belongs to a specificzCscene's one-off events: no characters, no dramatic or horror props,uC   no story moments — only the everyday standing state of the place.zAlso cover:z?  data (the sketch's bare lines carry NO material information),z/Write 120-220 words of direct imperative prose.plan_sketch_gpt.pngc                    |rt        j                  d      }n_t        j                  |      \  }}t	        |      dz   |z   }t        j
                  dt        |t              }t        j                  d|       |d   }	t        |z  }
|
j                         s
J d|
        	 t        j                  d      }|	|| d<   |	|| d<   t        j                  d|       t        |        t        j                  d	| d
|	|
gt        | dz         t        |        t        j                  d	| d|	t        |
fgt        | dz         t        |        y# t        $ r i }Y w xY w)u  [경로 B-2 v2] plan_sketch → 실사 — 저작 LLM 이 씬 원문 전체를
    분석해 이 장소의 삶이 남길 부수 생활 요소를 스스로 추가(사용자 지시:
    '사람 사는 것처럼, 하드코딩 금지, 씬을 알아서 분석'). 스케치=구조 SOT,
    빈 무대 복사 금지. reuse_prompt=True: 저장된 저작 프롬프트 재사용
    (스케치 소스만 바꾸는 A/B 의 변인 격리).plansketch_photo_promptrd   s20_plansketch_photo_authorr      참조 스케치 없음: r   r  r  r  r  r   r  r   N)r2   rC   rg   rh   r   r3   PHOTO_AUTHOR_SYSTEM_SCENEr	  r6   r   r  rt   r   r   r   NB2_PHOTO_SKETCH_LABEL)r?   rl   r  r  reuse_promptr  rn   ro   r=   r   r  r   s               r"   run_photo_from_plansketchr#  j  sq    [[23''.f"5)!'( UU02K,.	-r2
A
/C::<:4SE::<++/0 ()Gzl(#$'(Gzl(#$KK!7+sOIIZL%quH557sOIIZL%q,BC+H*IH557sO  s   !E E"!E")uC   Draw ONE DETAILED LINE SKETCH of the property's structure — cleanz=thin dark lines on plain white, like an architect's developedzBmassing sketch. Viewpoint: slightly elevated three-quarter obliquez=view (tilted about 30 degrees down from vertical) so RELATIVEuA   HEIGHTS read clearly — which volume rises above which, how manyz?storeys the building has, what sits on top of what, and how thezstair climbs between levels.z=MORE DETAIL than a plain massing sketch: draw each structuraluD   element with its characteristic built form in lines — stair treadszCand railing lines, parapet and roof edges, door and window openingszBwith simple frames, fixture outlines with their stands or supportsu2   — enough that every element reads as what it is.zASTILL LINES ONLY: no colours, no fills, no shading, no materials,zBno texture, no photorealism. Never any interior of enclosed units.r   r   r   c                    t        j                  d      }t        j                  d      }dj                  t        t	        j
                  |      t        |      t        g      }t        |z  }|j                         s
J d|        	 t        j                  d      }||| d<   ||| d<   t        j                  d|       t        |        t        j                  d| d	|t        |fgt        | dz  
       t        |        t        j                  d| d||gt        | dz         t        |        y# t        $ r i }Y w xY w)u   [경로 C-1] ① bd → 상세 선 스케치 (사용자: '조금 더 상세히').
    src_name/out_prefix 로 bd 엔진(nb2/gpt 산출) A/B 지원.r   ry   r]      참조 bd 없음: r   r  r  r  r  r   r  r   N)r2   rC   r-   r   r   r   r   SKETCH_STYLE_DETAILEDr   r  rt   r6   r   r   r   r   r  s	            r"   run_bd_sketchr'    sE    [[-.F;;'D	tV	 
B /C::<3-cU33<++/0 (*Gzl(#$')Gzl(#$KK!7+sOIIZL%r-@#,F+GH557sOIIZL%rH557sO  r  bd_sketch_gpt.pngc                    |rt        j                  d      }n?t        j                  dt        t	        |      t
              }t        j                  d|       |d   }t        |z  }|j                         s
J d|        	 t        j                  d      }||| d<   ||| d<   t        j                  d|       t        |        t        j                  d| d	||gt        | dz  
       t        |        t        j                  d| d|t        |fgt        | dz         t        |        y# t        $ r i }Y w xY w)u   [경로 C-2] 상세 스케치(gpt) → 실사 (저작=기존 스케치 전제 시스템).
    reuse_prompt=True: 저장된 저작 동일본 재사용(변인=스케치 계보만).bdsketch_photo_prompts20_bdsketch_photo_authorr   r  r   r  r  r  r  r   r  r   N)r2   rC   r3   PHOTO_AUTHOR_SYSTEMr   r	  r6   r   r  rt   r   r   r   r!  	r?   rl   r  r  r"  r  r   r  r   s	            r"   run_photo_from_bdsketchr.    sE   
 [[01UU.0C%e,.AC	+R0
A
/C::<:4SE::<++/0 ()Gzl(#$'(Gzl(#$KK!7+sOIIZL%quH557sOIIZL%q,BC+H*IH557sO     D4 4EEzAreceive your prompt plus ONE attached flat top-down BLOCK DIAGRAMz?of a real property. Small numeral markers on it are annotationsuA   only, and its flat fill colours encode height layers — they arez!NOT materials or surface colours.z=The diagram is the single source of truth for WHAT exists andz@WHERE. Therefore your prompt must NOT re-describe, list or countuB   the layout, its elements or their positions — beyond telling thezBmodel the attached drawing is a placement diagram to be translatedz;into real built volumes (its height-layer colours into realz?heights), and that its numerals, flat colours and graphics mustz!NEVER be reproduced in the image.z4Your prompt covers only what the diagram cannot say:zD  data below (the diagram's flat drawing colours are NOT materials),u   BLOCK DIAGRAM (spatial ground truth) — translate to real photographic volumes; its flat colours encode height layers only, never materials; its numerals are annotations, never draw them; never copy its drawing style; no text anywhere.c                    |rt        j                  d      }n?t        j                  dt        t	        |      t
              }t        j                  d|       |d   }t        |z  }|j                         s
J d|        	 t        j                  d      }||| d<   ||| d<   t        j                  d|       t        |        t        j                  d| d	||gt        | dz  
       t        |        t        j                  d| d|t        |fgt        | dz         t        |        y# t        $ r i }Y w xY w)u   [경로 D] ① bd → 실사 직행 (저작 LLM 별도).
    reuse_prompt=True: 저장된 저작 동일본 재사용(변인=bd 엔진만).bd_photo_prompts20_bd_photo_authorr   r%  r   r  r  r  r  r   r  r   N)r2   rC   r3   PHOTO_AUTHOR_SYSTEM_BDr   r	  r6   r   r  rt   r   r   r   NB2_PHOTO_BD_LABELr-  s	            r"   run_photo_from_bdr5  	  sE    [[*+UU(*@%e,.AC	%r*
A
/C::<3-cU33<++/0 ()Gzl(#$'(Gzl(#$KK!7+sOIIZL%quH557sOIIZL%q,>+D*EH557sO  r/  z5You write ONE image-generation prompt (English) for az?photorealistic location image. There is NO reference image thisuB   time: your prompt is the model's ONLY source — it must carry thez STRUCTURE and the LOOK together.z=You get the property's minimal structure lines (containment /zBsupport / connection, coarse positions, judged scale), place data,z8and production-owner corrections / appearance overrides.zYour prompt must:uA   - state the structure compactly in plain visual language — whatzA  contains or carries what, roughly where, the storey count. Keepz:  it as LEAN as the given lines: over-specification breedsz8  contradictions and hallucination; trust the model withuB     everything unstated. The lines' numbers are identifiers only —z;  never mention numbers, markers or diagrams in the prompt,z  data,z@- surroundings: invent believable ordinary neighbourhood contextz<  (real low-rise buildings, roofs, windows, utility clutter,u=     street texture) at your own judgement — only the propertyz%  itself follows the structure lines,z@- the place must read as REAL and LIVED-IN (weathering, everydayz>  traces; decide the feel, let the model improvise specifics),z2- unpeopled; no readable text or signage anywhere,z:- one believable camera (your choice) and ordinary neutralz  daylight, documentary tone.z/Write 120-200 words of direct imperative prose.z7A creator-correction block, when present, overrides anyzconflicting place data.z9photo_prompt_ko: the same prompt in Korean (for the humanz
reviewer).c                 F   t        j                         }dj                  |j                  d      xs g       }dj                  |j                  d      xs g       }ddj                  | d         z   dz   t        j                  |      z   }|r|d|z   z  }|r|d|z   z  }|S )	Nr   r   r)   z,MINIMAL STRUCTURE (the property to depict):
r   z#

PLACE DATA (production members):
r   r   r   )r?   rl   r   r   r>   r=   s         r"   _textonly_userr7  K  s    				B266"45;<J))BFF=17R8K;ii3456679<u9MND  *+ 	,AJNNKrA   c                    t        j                  dt        t        | |      t              }t        j
                  d|       |d   }	 t        j                  d      }||d<   ||d<   t        j
                  d|       t        |        t        j                  d|dt        dz  	       t        |        t        j                  d
|g t        dz         t        |        y# t        $ r i }Y w xY w)ub   [경로 E] 무참조 T2I 실사 — 저작 프롬프트가 구조+룩 전부 (이미지 참조 0).s20_textonly_photo_authortextonly_photo_promptr   r   textonly_photo_gpt.pngtextonly_photo_nb2.pngs20_textonly_photo_gptNr   s20_textonly_photo_nb2r   )r2   r3   PHOTO_AUTHOR_SYSTEM_TEXTONLYr7  r	  r6   rC   rt   r   r   r   r   r?   rl   r  r   r   s        r"   run_photo_textonlyrA  Z  s    	
*,Hc5)+>
@BKK',
A++/0 )*G$%()G$%KK!7+sOII&668sOII&2668sO  s   C C,+C,)z@- camera: an elevated three-quarter view from roughly 45 degreesz@  above, off to one side of the property, so one side facade andz>  the roof level read together and the whole property fits thez5  frame; ordinary neutral daylight, documentary tone.c                 4   t         }t        |v sJ d       |j                  t        t              }t	        j
                  d|t        | |      t              }t	        j                  d|       |d   }	 t	        j                  d      }||d<   ||d<   t	        j                  d|       t        |        t	        j                  d|g t        dz  	       t        |        t	        j                  d
|g t        dz  	       t        |        y# t        $ r i }Y w xY w)u   [경로 E-2] 무참조 T2I 실사, 카메라=측면 45도 상공 (사용자 지시) —
    저작 카메라 계약 줄만 교체, nb2 2장(같은 프롬프트, 변동 확인).u    TEXTONLY 카메라 줄 불일치s20_textonly45_photo_authortextonly45_photo_promptr   r   textonly45_photo_nb2_a.pngtextonly45_photo_nb2_b.pngs20_textonly45_photo_nb2_ar   s20_textonly45_photo_nb2_bN)r?  TEXTONLY_CAM_DEFAULTr   TEXTONLY_CAM_45r2   r3   r7  r	  r6   rC   rt   r   r   r   )r?   rl   systemr  r   r   s         r"   run_photo_textonly45rL  |  s    *F6)M+MM)^^0/BF	
,fc5)+>
@BKK)2.
A++/0 -.G(),-G()KK!7+sOII*Ar::<sOII*Ar::<sO  s   2D	 	DDc                    t        j                  d      }|d   }	 t        j                  d      }||d<   ||d<   t        j                  d|       t	        |        t        j
                  d|dt        dz         t	        |        t        j
                  d	|dt        dz         t	        |        y# t        $ r i }Y w xY w)
u   [경로 E-2 gpt] 45° 부감 무참조 T2I — ⑬-2와 동일 저작본 재사용,
    gpt-image-2 2장(같은 프롬프트, 변동 확인).rD  r   r   textonly45_photo_gpt_a.pngtextonly45_photo_gpt_b.pngs20_textonly45_photo_gpt_aNr   s20_textonly45_photo_gpt_b)r2   rC   rt   r6   r   r   r   r@  s        r"   run_photo_textonly45_gptrR    s     
.	/B
A++/0 -.G(),-G()KK!7+sOII*AD::<sOII*AD::<sO  s   B3 3C C)z<You are given ONE image-generation prompt and FOUR candidatez@images, labelled A, B, C, D in the order attached, all generatedzfrom that exact prompt.z@Pick the ONE candidate that most faithfully realises the prompt.z=Judge ONLY fidelity to the prompt: its stated structure (whatz?contains or carries what, counts, connections, placements), thez?camera it asks for, materials and state, and its exclusions (noz;people, no readable text). Ignore generic aesthetic appeal.z>Check every candidate against the prompt point by point beforez5deciding; base every verdict only on what is visible.z<Output: winner, ranking best-to-worst, and a one-line Koreanz8verdict per candidate citing the decisive prompt points.)ABCD)r   enum)label
verdict_korX  rY  )winnerrankingverdicts))rS  rE  )rT  rF  )rU  rN  )rV  rO  c           
         t        j                  d      }dd|d   z   dg}t        D ]d  \  }}t        |z  }|j	                         s
J d|        |j                  dd| dd       |j                  t        j                  |             f i }d	D ]J  \  }}t        j                  |t        |t        |
      ||<   t        d| d||   d    d||   d           L t        j                  d|       t        |        |S )u   ⑬-2 4장(nb2 a/b + gpt a/b)을 GPT VLM/Gemini VLM 각각이 프롬프트
    충실도로 판정 — 같은 멀티모달 입력, 모델만 분기.rD  textz;THE PROMPT (all four candidates were generated from this):
r   r   r^     후보 이미지 없음: 
Candidate :))gpts20_judge45_gpt)
gemini-pros20_judge45_geminimodelzjudge45[
]: winner=rZ  	 ranking=r[  judge45_results)r2   rC   JUDGE45_CANDIDATESr   r  r/   png_data_urlr3   JUDGE45_SYSTEMJUDGE45_SCHEMAr7   r6   r   )	r?   r  partsrX  fnfoutrh  tags	            r"   run_judge45ru    s     
.	/B(*,->*?@B CE (	r2Ixxz:6qc::zf
5'.CDEQ^^A&'	 (
 C=
sUU3~!&(E
z#e*X*>)?#e*Y/02 	3	= KK!3'sOJrA   )z<You are given ONE photograph of a real property. Examine thez>exterior staircase in it as a PHYSICAL CONSTRUCTION and answerz?strictly from what is visible: could a person actually climb itz-from the ground level to the level it serves?zCheck point by point:z?- where it starts: is the bottom step reachable from the groundz
  or yard,z?- flight continuity: no gaps, no floating or detached segments,z9  no impossible overlapping geometry, landings connected,z.- tread spacing and slope: plausibly walkable,z=- the top: does it actually arrive at the upper level (onto az/  landing or over the parapet in a usable way),z- railing/support continuity.zclimbable: overall yes/no.z>verdict_ko: one short Korean paragraph stating the conclusion.z<issues_ko: each visible physical problem as one short Koreanzline (empty array if none).boolean)	climbablerY  	issues_korE  c                 z   t         |z  }|j                         s
J d|        dddt        j                  |      g}d|i}dD ]S  \  }}t        j                  |t
        |t        |      ||<   t        d| d	||   d
    dt        ||   d                 U t        j                  d|       t        |        |S )u\   특정 이미지의 외부 계단 등반 가능성(물리 정합) — GPT/Gemini VLM 교차.u   대상 이미지 없음: r^  z/Photograph to examine (its exterior staircase):r_  target))rc  s20_stair_check_gpt)re  s20_stair_check_geminirg  zstair_check[z]: climbable=rw   issues=rx  stair_check_results)r   r  r2   rm  r3   STAIR_CHECK_SYSTEMSTAIR_CHECK_SCHEMAr7   r8   r6   r   )r?   rz  rr  rp  rs  rh  rt  s          r"   run_stair_checkr    s    vA88:621#66:GI^^A E V
CA
sUU3 2E-U<E
UG=UK()#c%j6M2N1OQ 	R	A KK%s+sOJrA   )zBEdit this photograph. The exterior metal staircase on the buildingz@is structurally impossible: flights overlap, connections betweenz?runs and landings are broken, the bottom run does not reach thez,ground, and railings pass through structure.z?REDRAW THE STAIRCASE ONLY, as ONE physically climbable retrofitz?steel stair: continuous flights with even open treads, landingsz;that actually connect each run, the bottom run reaching thezAground / yard level, the top run arriving at the rooftop landing,z@railings and support posts continuous and never intersecting anyz;structure. Keep its rusty, added-on steel character and itszposition against the same wall.uB   PRESERVE EVERYTHING ELSE EXACTLY as in the original photograph —z>buildings, roof objects, yard, surroundings, lighting, camera,z.framing. No people, no readable text anywhere.ul   PHOTOGRAPH TO EDIT — fix ONLY its exterior staircase as the prompt says; preserve everything else exactly.c                    t         |z  }|j                         s
J d|        t        }	 t        j                  d      }||d<   ||d<   t        j                  d|       t        |        t        j                  d|t        |fgt         dz         t        |        t        j                  d||gt         dz         t        |        y	# t
        $ r i }Y w xY w)
u   [⑬-3] 계단 물리 결함 i2i 수정 (사용자 판정: 중간 끊김=등반 불가) —
    같은 원본+같은 편집 계약으로 gpt edit / nb2 i2i 각 1장.   원본 없음: r   stairfix_gpt.pngstairfix_nb2.pngs20_stairfix_nb2r   s20_stairfix_gptr   N)r   r  STAIR_FIX_PROMPTr2   rC   rt   r6   r   r   NB2_STAIR_FIX_LABELr   )r?   rz  r  r   r   s        r"   run_stair_fixr  <  s     -C::<0?3%00<A++/0 #$G"#GKK!7+sOII !':C&@%A002sOII !3%002sO  s   C
 
CCr  )u>   The attached image is a PHOTOGRAPH of one real property — itz=replaces the structure lines: EXTRACT the placement structurez?(what contains or carries what, roughly where, how the exteriorz?stair connects the levels) from the photograph itself, and stayz=faithful to its actual arrangement. Permanent structure only:z/ignore people, loose objects and movable props.c                      t         } t        | v sJ d       | j                  t        t              } d}d}|| v sJ d       | j                  ||      } d}d}|| v sJ d       | j                  ||      } t        dz   | z   S )	u  [⑭-1] 기존 bd 계약(STYLE_STRUCT_MIN) 그대로 재사용 — 소스 참조만
    구조 줄→첨부 사진으로 치환(사용자 지시 '기존 프롬프트+참조 문구만'),
    번호 줄→무텍스트 줄(역방향엔 번호 정체성 없음).u%   STYLE_STRUCT_MIN 번호 줄 불일치zeAny level wording in the lines
below is placement logic, not an instruction to build tall 3D
volumes.znAny level difference read from the
photograph is placement logic, not an instruction to build tall 3D
volumes.u(   STYLE_STRUCT_MIN 레벨 문구 불일치u   The lines below give ONLY the placement structure (what is on/in
what, roughly where). Everything they leave unsaid — exact shapes,
sizes, proportions, spacing — YOU decide, so the property reads
plausibly; keep every stated relation true.u   The attached photograph gives the placement structure (what is on/in
what, roughly where). Everything beyond that placement — exact shapes,
sizes, proportions, spacing — YOU decide, so the property reads
plausibly; keep every extracted relation true.u(   STYLE_STRUCT_MIN 소스 문구 불일치r]   )r   NUMBERED_LINEr   NO_TEXT_LINEREV_BD_SRC_NOTE)r   old1new1old2new2s        r"   rev_bd_promptr  `  s     EE!J#JJ!MM-6E=DDD5=DDD=MM$%ED
(D
 5=DDD=MM$%EV#e++rA   )z8The attached image is a PHOTOGRAPH of one real property.z;TRANSLATE its permanent structural layout into the top-downu;   architectural SITE PLAN described below — faithful to thez8photograph's actual arrangement: positions, connections,z?boundary openings, and the exterior stair route between levels.z:Permanent structure only: ignore people, loose objects andzmovable props.)z<The FIRST attached image is a top-down SITE PLAN of one realz>property: use it as the layout ground truth. Translate it intoz@the line sketch described below, judging plausible built heightsz>from the plan's own cues (storey rhythm of openings, the stairz#run between levels, parapet lines).u   PHOTOGRAPH (layout source) — extract its permanent structural layout only; draw the diagram the prompt describes, not a photo.uc   SITE PLAN (layout ground truth) — translate to the sketch the prompt describes; no text anywhere.c                    t         t        z  }|j                         s
J d|        t               }	 t	        j
                  d      }||d<   ||d<   t	        j                  d|       t        |        t	        j                  d|t        |fgt         dz         t        |        t	        j                  d||gt         dz         t        |        y	# t        $ r i }Y w xY w)
uI   [⑭-1] 실사 → bd 역추출 (gpt/nb2) — 기존 bd 계약 재사용.r  r   rev_bd_gpt.pngrev_bd_nb2.pngs20_rev_bd_nb2r   s20_rev_bd_gptr   N)r   REV_SRCr  r  r2   rC   rt   r6   r   r   NB2_REV_PHOTO_LABELr   r?   r  r   r   s       r"   
run_rev_bdr    s    
.C::<0?3%00<A++/0 !"G !GKK!7+sOII%8#$>#?..0sOII..0sO  s   C C C c                    t         t        z  }|j                         s
J d|        dj                  t        t
        t        j                  g      }	 t        j                  d      }||d<   ||d<   t        j                  d|       t        |        t        j                  d|t        |fgt         dz         t        |        t        j                  d||gt         dz  	       t        |        y
# t        $ r i }Y w xY w)u<   [⑭-2] 실사 → fp(사이트 플랜) 역추출 (gpt/nb2).r  r]   r   rev_fp_gpt.pngrev_fp_nb2.pngs20_rev_fp_nb2r   s20_rev_fp_gptr   N)r   r  r  r-   REV_FP_NOTEr   r   r   r2   rC   rt   r6   r   r   r  r   r  s       r"   
run_rev_fpr    s    
.C::<0?3%00<["8#,,GHA++/0 !"G !GKK!7+sOII%8#$>#?..0sOII..0sO  s   C2 2D ?D r  c                    t         |z  }|j                         s
J d|        dj                  t        t        g      }	 t        j                  d      }||d<   ||d<   t        j                  d|       t        |        t        j                  d|t        |fgt         dz         t        |        t        j                  d||gt         dz  	       t        |        y
# t        $ r i }Y w xY w)uT   [⑭-3] 역추출 fp → 선 스케치 (텍스트 주입 0 — 이미지 계보만).u   참조 fp 없음: r]   r   rev_sketch_gpt.pngrev_sketch_nb2.pngs20_rev_sketch_nb2r   s20_rev_sketch_gptr   N)r   r  r-   REV_SKETCH_NOTEr   r2   rC   rt   r6   r   r   NB2_REV_FP_LABELr   r?   r  r  r   r   s        r"   run_rev_sketchr    s    
/C::<3-cU33<_l34A++/0 %&G !$%G !KK!7+sOII"A)93(?'@224sOII"ASE224sO  s    C C-,C-)zAThe attached image is the SAME property's schematic block diagramz=(top-down). REDRAW the SAME layout with the viewing directionz@ROTATED 90 DEGREES TO THE RIGHT (clockwise): every element keepsuA   its true relative position and size — only the view rotates, asz)if the plan sheet were turned 90 degrees.)z=The attached image is the SAME property's top-down SITE PLAN.z<REDRAW the SAME layout with the viewing direction ROTATED 90z>DEGREES TO THE RIGHT (clockwise): every element keeps its trueu?   relative position and size — only the view rotates, as if thez"plan sheet were turned 90 degrees.uz   SOURCE DIAGRAM (same property) — redraw the same layout rotated 90 degrees clockwise; keep every relative position true.c                      t               } t        | v sJ d       | j                  t        t              } d| v sJ d       | j                  dd      } d| v sJ d       | j                  dd      } | S )u   기존 rev_bd 프롬프트(=STYLE_STRUCT_MIN 재사용본) 내용 유지 —
    참조 노트만 회전 지시로 교체, 사진 어휘→첨부 이미지.u   REV_BD_SRC_NOTE 불일치zread from the
photographu"   photograph 레벨 문구 불일치zread from the
attached imagezThe attached photograph givesu"   photograph 소스 문구 불일치zThe attached image gives)r  r  r   ROT90_NOTE_BD)r   s    r"   rot90_bd_promptr    s     	Aa<!<<			/=1A&!+Q-QQ+			-/NOA*a/U1UU/			13MNAHrA   c                  V    dj                  t        t        t        j                  g      S )uV   기존 rev_fp 프롬프트(STYLE_2D+실외 계약) 내용 유지 — 노트만 교체.r]   )r-   ROT90_NOTE_FPr   r   r   r   rA   r"   rot90_fp_promptr    s    ;;'=s||LMMrA   r  c                    t         |z  }|j                         s
J d|        t               }	 t        j                  d      }||d<   ||d<   t        j                  d|       t        |        t        j                  d|t        |fgt         dz         t        |        t        j                  d||gt         dz         t        |        y	# t
        $ r i }Y w xY w)
u+   [⑮-1] bd 90° 회전 재작도 (gpt/nb2).   참조 없음: r   rot90_bd_gpt.pngrot90_bd_nb2.pngs20_rot90_bd_nb2r   s20_rot90_bd_gptr   N)r   r  r  r2   rC   rt   r6   r   r   NB2_ROT90_LABELr   r  s        r"   run_rot90_bdr        
/C::<0?3%00<A++/0 #$G"#GKK!7+sOII !&<%=002sOII !3%002sO     C CCr  c                    t         |z  }|j                         s
J d|        t               }	 t        j                  d      }||d<   ||d<   t        j                  d|       t        |        t        j                  d|t        |fgt         dz         t        |        t        j                  d||gt         dz         t        |        y	# t
        $ r i }Y w xY w)
u+   [⑮-2] fp 90° 회전 재작도 (gpt/nb2).r  r   rot90_fp_gpt.pngrot90_fp_nb2.pngs20_rot90_fp_nb2r   s20_rot90_fp_gptr   N)r   r  r  r2   rC   rt   r6   r   r   r  r   r  s        r"   run_rot90_fpr    r  r  )zBSTRICT VERTICAL TOP-DOWN ONLY: this drawing is a TRUE ORTHOGRAPHICu?   PLAN seen from DIRECTLY ABOVE — absolutely NO 3D, NO 2.5D, NOz>axonometric or oblique tilt of any kind, no facades, no volumez:sides visible; every element appears only as its pure planz?geometry (roof outlines, ground shapes, openings set in walls).c                    t         |z  }|j                         s
J d|        dj                  t        t        t
        t        j                  g      }	 t        j                  d      }||d<   ||d<   t        j                  d|       t        |        t        j                  d|t        |fgt         dz         t        |        t        j                  d||gt         dz  	       t        |        y
# t        $ r i }Y w xY w)u   [⑯] 실사 → 완전 수직 fp (사용자: '절대 3D/2.5D 말고 완전 수직 도면')
    — 기존 fp 계약(STYLE_2D) 그대로 + 수직 강조 노트만 추가.r  r]   r   fpflat_gpt.pngfpflat_nb2.pngs20_fpflat_nb2r   s20_fpflat_gptr   N)r   r  r-   r  FPFLAT_VERTICAL_NOTEr   r   r   r2   rC   rt   r6   r   r   r  r   r  s        r"   
run_fpflatr  0  s     /C::<0?3%00<["6+S\\; 	<A++/0 !"G !GKK!7+sOII%8#$>#?..0sOII..0sO  s   C3 3D Dzeach listed element carries ONLY its assigned letter, drawn once
as a small plain CIRCLED LETTER marker on (or beside) it; apart
from these circled letters no text, no words, no numbers, no other
markers, no legend, no compass.c           	         g }| d   D ]  }t        j                  d|      }|rxdt        |j                  d            cxk  rdk  rUn nR|j	                  t
        j                  t        |j                  d            dz
      d|j                  d              |j	                  |        | d   D cg c]7  }d|d   cxk  rdk  r'n n$t        |t
        j                  |d   dz
     	      9 }}||fS c c}w )
u   v12 미니멀 줄 머리 번호→알파벳 재라벨 (결정론 형식 변환, 의미 불변 —
    사용자: 한 글자 26자까지, 판독 용이). legend 도 같은 매핑.r   z^(\d+)[.\s]\s*(.*)$      .    r   r   )letter)rematchintgroupr/   r   ascii_uppercasedict)r?   rs  lnmrr   s         r"   alpha_structr  N  s     C)*HH+R0c!''!*o++JJ&00QWWQZ11DEF G771:,( ) JJrN + 8}=$!QuX(;(; 1V33AeHqLAB$  =;=s   5<C7c           	          t        |       \  }}t        j                  }t        |v sJ d       |j	                  t        t
              }dj                  t        t        t        ddj                  |      z   |g      S )u   [⑯-2] 완전 수직 fp + 원형 알파벳 위치 마커 — ⑯ 계약 유지, no-text
    줄만 '지정 원형 알파벳만 허용'으로 교체, 알파벳 구조 줄 주입.r   r]   uy   KEY ELEMENTS (letters are identifiers only — mark each listed element's POSITION on the plan with its circled letter):
r   )
r  r   r   r   r   STYLE_2D_CIRCLEDr-   r  r  r   )r?   r:   _r   s       r"   fpflat_marked_promptr  ^  s|     C HE1LLEu$F&FF$MM*,<=E;;	F
))E
	 	  rA   fpflat_marked_gpt.pngc                 ~   t         |z  }|j                         s
J d|        t        |       }	 t        j                  d      }|||<   t        j                  d|       t        |        t        j                  dt        |      j                   ||gt         |z         t        |        y# t
        $ r i }Y vw xY w)u   [⑯-2] 실사 → 완전 수직 fp + 원형 알파벳 마커 — gpt-image-2 1장만.
    (src_name/out_name 파라미터화 — TOP 체인 재사용, 계약 동일)r  r   r  r   N)r   r  r  r2   rC   rt   r6   r   r   r   stem)r?   r  out_namer  r   r   s         r"   run_fpflat_markedr  p  s     /C::<0?3%00<S!A++/0 GHKK!7+sOIIT(^(()*ASEh(sO  s   B. .B<;B<))rS  ztop_photo_nb2_a.png)rT  ztop_photo_nb2_b.png)rU  ztop_photo_nb2_c.pngztop_photo_fixed_nb2.pngztop_fpflat_marked_gpt.pngc                    t        j                  d      }|d   }	 t        j                  d      }t        D ]
  \  }}|||<    t        j                  d|       t        |        t        D ]A  \  }}t        j                  d|j                          |g t        |z         t        |        C y# t        $ r i }Y w xY w)u   [⓪-1] 장소 실사 nb2 3장 — ⑬-2 저작본(45° 부감, 장소 전체=골목·마당·
    빌라·계단·옥상 포함) **그대로 재사용**(신규 저작 0), 변인=샘플링만.rD  r   r   s20_top_photo_r   N)	r2   rC   rt   TOP_CANDIDATESr6   r   r   lowerr   )r?   r  r   r   r  rq  labs          r"   run_top_photosr    s     
.	/B
A++/0  2  KK!7+sO!R			N399;-0!R"9	&3 "  s   B0 0B>=B>c                  t    t         } g d}|D ](  \  }}|| v sJ d|dd         | j                  ||      } * | S )uJ   judge45 계약 최소 치환: 후보 4→3 + 후보별 0-10 점수 추가.))z.ONE image-generation prompt and FOUR candidatez/ONE image-generation prompt and THREE candidate)z)labelled A, B, C, D in the order attachedz&labelled A, B, C in the order attached)zuOutput: winner, ranking best-to-worst, and a one-line Korean
verdict per candidate citing the decisive prompt points.zOutput: winner, ranking best-to-worst, an integer fidelity
score 0-10 per candidate, and a one-line Korean verdict per
candidate citing the decisive prompt points.u   judge45 계약 줄 불일치: N(   )rn  r   )rb   subsr   news       r"   _topjudge_systemr    sT    A
D SaxD9#cr(DDxIIc3  HrA   )rS  rT  rU  )rX  scorerY  c           
         t        j                  d      }dd|d   z   dg}t        D ]d  \  }}t        |z  }|j	                         s
J d|        |j                  dd| dd       |j                  t        j                  |             f t               }i d	D ]F  \  }}t        j                  |||t        |
      |<   t        d| d|   d    d|   d           H i }	t        D ]  \  }
t        fddD              |	<    t        |	j                               }|	j                         D cg c]  \  }}||k(  s| }}}d   d   t        |fd      }dt!        t              |	|t!        t              |   d}t        j"                  d|       t        d|	 d|        t%        |        |S c c}}w )u   [⓪-2] 3후보를 GPT VLM/Gemini VLM 각각 점수(0-10) — 합산 최고 1장 선택
    (동점=Gemini 순위 우선: 물리 결함 감지 Gemini 우세 판정 지식).rD  r^  z<THE PROMPT (all three candidates were generated from this):
r   r_  r`  ra  rb  ))rc  s20_top_judge_gpt)re  s20_top_judge_geminirg  z
top_judge[ri  rZ  rj  r[  c              3   R   K   | ]  }t        fd |   d   D                 yw)c              3   :   K   | ]  }|d    k(  s|d     yw)rX  r  Nr   )r    r!   r  s     r"   r#   z*run_top_judge.<locals>.<genexpr>.<genexpr>  s#     O%9QwZ3=N7%9s   
r\  N)next)r    r  judger  s     r"   r#   z run_top_judge.<locals>.<genexpr>  s-      ,* OU1Xj%9OO*s   $')rc  re  re  c                 2    | v rj                  |       S dS )Nc   )index)r  gem_ranks    r"   r   zrun_top_judge.<locals>.<lambda>  s%    Xo *2)< *.+-*.rA   r   )prompt_plan
candidatesr  totalsselectedselected_filetop_place_v1ztop_judge: totals=z
 selected=)r2   rC   r  r   r  r/   rm  r  r3   TOPJUDGE_SCHEMAr7   summaxvaluesr   minr  r6   r   )r?   r  rp  rX  rq  rr  rK  rh  rt  r  r  bestr  ttiedr  planr  r  s               `    @@r"   run_top_judger	    s    
.	/B(*,->*?@B CE $	r2Ixxz:6qc::zf
5'.CDEQ^^A&'	 $
 FE?
suuS&%Ne
5'E%L,B+C%,y124 	5?
 F Q ,*, ,s ! v}}D$lln:nFCT	CnD:\"9-H4 . /H4~.(!.1(;=D KK%	vhj

;<sOK ;s   =GG)z<You are given the image-generation prompt and ONE photographz:generated from it. List what is WRONG with the photograph:z:- fidelity: any visible deviation from the prompt's statedz@  structure (what contains or carries what, counts, connections,z7  placements), its camera, materials and state, and itsz+  exclusions (no people, no readable text),z@- physical coherence: any construction that could not physicallyz=  work in reality (broken, floating or overlapping structure,z+  unreachable routes, impossible geometry).z:Base every finding only on what is visible. Ignore genericzaesthetic taste.z=issues: each finding as issue_ko (one short Korean line) plusz:fix_en (ONE imperative English edit instruction that fixesz>exactly that finding while changing nothing else). Empty arrayzif nothing is wrong.issues)issue_kofix_enr  r  z?Edit this photograph. Fix ONLY the issues listed below, each inz0place, changing nothing else about the property:u^   PHOTOGRAPH TO EDIT — fix ONLY the issues the prompt lists; preserve everything else exactly.c                  \    d} | t         v sJ d       t         t         j                  |       d S )uT   STAIR_FIX_PROMPT 의 보존 계약 꼬리를 그대로 재사용 (검증된 계약).z PRESERVE EVERYTHING ELSE EXACTLYu   STAIR_FIX 보존 줄 불일치N)r  r  r   s    r"   _preserve_tailr  '  s6    
,C""D$DD",2237899rA   c                 :   t        j                  d      }t        |d   z  }|j                         s
J d|        t        j                  |d         }dd|d   z   ddd	dt        j                  |      g}i }d
D ]J  \  }}t        j
                  |t        |t        |      ||<   t        d| dt        ||   d                 L ||d<   dD 	cg c]  \  }}||   d   D ]  }	d| d|	d      }
}}}	|
s;|d   |d<   d|d<   t        j                  d|       t        d       t        |        |S dj                  t        ddj                  |
      z   t               g      }||d<   t        |d<   t        j                  d|       	 t        j                  d      }||t        <   t        j                  d|       t        |        t        j"                  d|t$        |fgt        t        z         t        |        |S c c}	}}w # t         $ r i }Y vw xY w)u   [⓪-3] 선택본에 GPT/Gemini VLM 결함 질문 → 취합(코드 조립, 양쪽 fix_en
    전부·중복 판단 없음) → nb2 i2i 수정 1장. 결함 0이면 수정 생략.r  r  u   선택본 없음: r  r^  z5THE PROMPT (the photograph was generated from this):
r   r_  zPhotograph to examine:))rc  s20_top_critique_gpt)re  s20_top_critique_geminirg  ztop_critique[z
]: issues=r
  critique)rc  zGPT VLM)re  z
Gemini VLMz- (z) r  
fixed_fileTfix_skippedu?   top_fix: 결함 0 — 수정 생략, 선택본 그대로 사용r]   zISSUES TO FIX:
r   
fix_promptr   s20_top_photo_fixedr   )r2   rC   r   r  rm  r3   TOP_CRITIQUE_SYSTEMTOP_CRITIQUE_SCHEMAr7   r8   r6   r   r-   TOP_FIX_HEADr  	TOP_FIXEDrt   r   NB2_TOP_FIX_LABEL)r?   r  r  r  rp  r  rh  rt  titlei	fix_linesr   r   s                r"   run_top_fixr   .  s`    ;;~&D
o&
&C::<3-cU33<	
T-(	)B#%'(9%:;= &>?^^C 	"E
 HB
s%%%8% 35BeW %Xe_X678: 	;	B  D&D5&D\UE"5/(3Q ugR(}- 4 .&D  5 !/2\"]	ND)OP3\'$))I*>>#%' 	(A D"DKK%++/0 GIKK!7+sOII#Q*;S)A(Bi')sOK75&  s   "HH HHc                    t        j                  d      }t        |d   z  }|j                         s
J d|        t	        |       }	 t        j                  d      }||t        <   t        j                  d|       t        |        t        j                  d||gt        t        z         t        |        y# t
        $ r i }Y hw xY w)u   [⓪-4] 수정본 기반 ⑯-2 계약(v3: 수직 노트 v2+입면 접기 금지) —
    gpt i2 1장 (사진→수직 재투영은 gpt 전담).r  r  r  r   s20_top_fpflat_marked_gptr   N)
r2   rC   r   r  fpflat_marked_prompt_v3rt   TOP_FPr6   r   r   )r?   r  r  r   r   s        r"   
run_top_fpr%  `  s     ;;~&D
l#
#C::<0?3%00<$A++/0 GFOKK!7+sOII)1C5f}&sO  s   B8 8CCztop_fpflat_marked_nb2.png)zAOUTPUT MEDIUM: a flat 2D architectural SITE-PLAN DRAWING on plainuA   drawing paper — NOT a photograph, NOT a rendering of the scene.?The attached photograph is ONLY a source of layout information;<   do NOT reproduce or imitate its camera angle or its look —;RE-PROJECT everything to a TRUE ORTHOGRAPHIC PLAN seen from1DIRECTLY ABOVE (90 degrees, straight-down nadir).z@Absolutely NO 3D of any kind: no perspective, no foreshortening,z@no axonometric or oblique tilt, no facades, no wall surfaces, nou@   volume sides, no cast shadows, no photographic texture — everyz>element appears ONLY as its pure plan geometry (roof outlines,z=ground shapes, openings marked in wall lines) in uniform flatz"fills and clean drafting linework.c                 j    t        |       }t        |v sJ d       |j                  t        t              S )uH   ⑯-2 계약에서 수직 노트만 v2 로 치환 (나머지 동일본).u   FPFLAT 수직 노트 불일치)r  r  r   FPFLAT_VERTICAL_NOTE_V2r?   r   s     r"   fpflat_marked_prompt_v2r-    s3    S!A1$F&FF$99)+BCCrA   ux   KEY ELEMENTS (letters are identifiers only — mark each listed element's POSITION on the plan with its circled letter):u  KEY ELEMENTS (letters are identifiers only — mark each listed element's POSITION on the plan with its circled letter). Elements that face sideways and are not visible from directly above (windows or doors set in walls) appear ONLY as their opening symbols on the wall line, with the circled letter beside that symbol — NEVER fold or draw any facade or elevation into the plan to show them:c                 j    t        |       }t        |v sJ d       |j                  t        t              S )u[   v2 + 측면 요소=벽선 기호 마킹·입면 접기 금지 (KEY ELEMENTS 헤더 치환).u   KEY ELEMENTS 헤더 불일치)r-  KEY_ELEMENTS_HEADr   KEY_ELEMENTS_HEAD_V3r,  s     r"   r#  r#    s3    $A!B#BB!99&(<==rA   )z6The attached image is already a straight-down TOP-DOWNz>architectural SITE PLAN of one real property. REDRAW it in theuA   drafting language described below — keep its viewpoint, layout,z@proportions, boundary openings, stair position and every circledz@letter marker exactly where they are; do not add, move or removez	elements.)r&  r'  r(  r)  zIKeep the TRUE ORTHOGRAPHIC straight-down view of the attached plan draft.c                     t        |       }t        |v sJ d       |j                  t        t              }t        |v sJ d       |j                  t        t
              S )uV   nb2 용 v3 — 소스가 사진이 아니라 수직 도면 초안일 때의 치환본.   REV_FP_NOTE 불일치   v2 사진 조항 불일치)r#  r  r   REV_PLAN_NOTE_V2_PHOTO_CLAUSE_V2_PLAN_CLAUSEr,  s     r"   fpflat_marked_prompt_v3_planrefr7    sV    $A!444			+}-Aq >">> 99%77rA   u   SITE-PLAN DRAFT (layout ground truth) — redraw it in clean drafting language, SAME straight-down top-down view, keeping every circled letter marker in place; never tilt into 3D.ztop_fpflat_read_gpt.pngztop_fpflat_read_nb2.png)z?You are given ONE photograph of a real property and the list ofzits known element names.z9READ the photograph like a surveyor and write its spatialu4   structure as text — one line per element, grammar:z<'N. <element name>, <containment> + one approximate positionz=(e.g. "on the roof terrace, rear-left") + what it attaches orzconnects to'.z?Plan-placement language ONLY (positions on the ground plane; noz:elevation wording such as rises/stands above/on top of thez$facade). Visible present state only.z5Every position MUST come from what is visible in THISu9   photograph — not from typical buildings, not from priorz?knowledge. Include short scale judgements that aid plan readingz3(storey count, notably small or large vs its host).z<First line: 'LEVELS (placement logic only): ...' summarisingz8the vertical stack. Then one 'Context:' line for unnamedz>neighbouring masses. If an element is not visible, still writez>its line, set visible=false in its legend row, and place it byz,the best visible cue using inferred wording.uJ   legend rows: num, name_en, desc_ko(사진에서 읽은 위치를 한국어u   한 줄로), visible.)r   r   r   visiblezYDraw a TRUE ORTHOGRAPHIC PLAN seen from DIRECTLY ABOVE
(90 degrees, straight-down nadir).c                     t        |       }t        |v sJ d       |j                  t        dz   d      }t        |v sJ d       |j                  t        t              S )uY   무참조 T2I 용 v3 — 첨부 이미지가 없으므로 사진 관련 조항만 제거.r2  r]   r	   r3  )r#  r  r   r5  _READ_VERTICAL_CLAUSE)res2r   s     r"   fpflat_marked_prompt_readr<  	  s\    %A!444			+&+Aq >">> 99%'<==rA   )z<You are given a PHOTOGRAPH of a real property and a top-downz5SITE PLAN that claims to represent the same property.>Compare them like a surveyor, only on spatial arrangement: for>each major element (building masses, yard, gate, alley, stair,=rooftop structures and fixtures) check position, containment,4attachment wall/side, connections and relative size.z>match: overall does the plan represent the photograph's actualz8arrangement (yes only if no major element is misplaced)?:issues_ko: each concrete mismatch as one short Korean linez>(element + how the plan differs from the photograph). Empty ifz-none. verdict_ko: one-line Korean conclusion.)r  rx  rY  )r  r
  rY  )z<issues: each concrete mismatch as issue_ko (one short Koreanz=line) plus fix_en (ONE imperative English drawing instructionz=that fixes exactly that mismatch in the plan). Empty if none.c                    t        j                  d      }t        |d   z  }|j                         s
J d|        t        j                  d      }|t           }t
        j                  dt              }|t
        k7  sJ d       t        t        z  }|j                  d      xs g }t        d|dz         D ]k  }	d	d
dt        j                  |      d	ddt        j                  |      g}
t        j                  d|	 ||
t        d      }|	|j                  |d}|j                  |       ||d<   t        j                  d|       t!        d|	 d|j                   d|d    dt#        |d                 t%        |        |d   r nTdj'                  d |d   D              }|dz   |z   }d|	 d}|||<   t        j                  d|       ||d<   t        j                  d|       t        j(                  d|	 |dt        |z         t        |z  }t%        |        n d	d
dt        j                  |      d	ddt        j                  |      g}
t        j                  d ||
t        d      }|j                  |dz   |j                  |d!d"       ||d<   t        j                  d|       t!        d#|j                   d|d    dt#        |d                 t%        |        |S )$u   [⓪-4d] 교정 루프 — Gemini 검증 issues→CORRECTIONS 되먹임 재작도,
    match=YES 까지 bounded 반복 (gpt 계보만). 수렴 여부가 이 경로의 결론.top_fpread_v1r      수정본 없음: r   rA  u   verify 계약 치환 실패
iterationsr  r^  Photograph:r_  Site plan to verify:s20_top_fp_loop_verify_re  rg  roundimgverifyzloop[z	] verify(	): match=r  r}  r
  r   c              3   ,   K   | ]  }d |d      ywr%   r  Nr   r    xs     r"   r#   z"run_top_fp_loop.<locals>.<genexpr>f	  s     A[2ak]+[   um   

CORRECTIONS — a previous attempt of this plan got the points below wrong; draw them correctly this time:
top_fpflat_read_gpt_itz.pngnext_imgs20_top_fpflat_read_gpt_itNr   s20_top_fp_loop_verify_finalT)rJ  rK  rL  finalzloop[final] verify()r2   rC   r   r  TOP_FP_READTOP_FP_VERIFY_SYSTEMr   TOP_FP_VERIFY2_TAILr.   rangerm  r3   TOP_FP_VERIFY2_SCHEMAnamer/   r6   r7   r8   r   r-   r   )r?   	max_itersrpr  r   base_promptrK  curitersr  vpartsr!   reccorrr   r  s                   r"   run_top_fp_looprf  G	  s    
_	%B
H
C::<3-cU33<kk+,G+&K!))DF ))H+HH)

CFF< &BE1i!m$]3Q^^C5H%;<NN3

 EE+A3/'|=#((a8S <	OR(aS	#((9QwZLQx[)*, 	-3W:yyAQx[AAEEGKL ,A3d3	%w/"J	OR(			.qc2AD(?	,Xo3; %B ]3Q^^C5H%;<NN3

 EE0&&'|=y1}SXX#% 	& <	OR(#CHH:YqzlQx[)*, 	-sOIrA   c           	         t        j                  d      }t        |d   z  }t        |d   d       }t        |d   z  }|j	                         s
J d|        dj                  d	 |d
   d   D              }dj                  dd|z   dg      }d}	 t        j                  d      }|||<   t        j                  d|       t        |        t        j                  d||gt        |z         t        |        t        j                  dt              }	dddt        j                  |      dddt        j                  t        |z        g}
t        j                  d|	|
t        d      }|d   j!                  d|||d   d       t        j                  d|       t#        d|d    d t%        |d          d!|d    d"       t        |        |S # t        $ r i }Y 7w xY w)#u   [⓪-4e] whack-a-mole 대응 — 루프 중 최소 이슈본에 **i2i edit** 로 해당
    이슈만 수정(⑬-3 stairfix 보존 패턴: 재작도 아님), 재검증.rC  r   rE  c                 $    t        | d   d         S )NrL  r
  )r8   )its    r"   r   z!run_top_fp_edit.<locals>.<lambda>	  s    c"X,x"89rA   r   rK  u   대상 도면 없음: r   c              3   ,   K   | ]  }d |d      ywrO  r   rP  s     r"   r#   z"run_top_fp_edit.<locals>.<genexpr>	  s     K2JQ1X;-(2JrR  rL  r
  r]   [Edit this architectural site-plan DRAWING. Fix ONLY the points listed below, each in place:CORRECTIONS:
   PRESERVE EVERYTHING ELSE EXACTLY as in the attached drawing — same straight-down plan view, same layout, same drafting style, same circled letter markers in their places. Apart from the circled letters no text anywhere.ztop_fpflat_read_gpt_edit.pngr   s20_top_fpflat_read_gpt_editr   rA  r^  rF  r_  rG  s20_top_fp_edit_verifyre  rg  z	edit(i2i)rJ  rK  rL  edited_fromzedit verify: match=r  r}  z (edited_from=r   )r2   rC   r   r  r  r-   rt   r6   r   r   rY  r   rZ  rm  r3   r\  r/   r7   r8   )r?   r_  	src_photor  src_imgfixesr   r  r   rK  rc  r!   s               r"   run_top_fp_editru  	  s    
_	%Br(|#Ir,9;DT%[ G>>?5gY??IIK$x.2JKKE	(5 	6	 	A .H++/0 GHKK!7+sOII,awih(sO!))DF /	1J!78	th'F
 	
&#<	9A|k('(eF GKK$	'
|8C(4D3E4;-q* +sOI1  s   G GG)r=  r>  r?  r@  )z@Compare them like a surveyor, only on spatial arrangement of thez:major elements (building masses, yard, gate, alley, stair,z!rooftop structures and fixtures).z<Judge ONLY relational topology: containment, adjacency, whatz9sits between what, which wall/side OF ITS HOST an elementz,attaches to, connections, and relative size.u@   NEVER use absolute left/right/top/bottom of either image — thez>plan's orientation may be rotated relative to the photograph'sz?viewpoint. First infer the plan's orientation from unmistakablez<anchors (alley, entry gate, exterior stair), state it in thez2verdict, then compare all relations in that frame.c                 <  
 t        j                  d      }t        |d   z  
t        |d   d   d   z  }t        j	                  dt
              t        v sJ d       j	                  t        t              
fd} ||d	      }|d   j                  d
|j                  |d       t        j                  d|       t        d|j                   d|d    dt        |d                 t        |        |d   s|d   rdj                  d |d   D              }dj                  dd|z   dg      }d}	 t        j                  d      }|||<   t        j                  d|       t        j                   d||gt        |z         t        |         |t        |z  d      }	|d   j                  d||	|j                  d       t        j                  d|       t        d| d|	d    dt        |	d                 t        |        |S # t        $ r i }Y w xY w)u   [⓪-4f] 최종 판정 — 위상 기준 검증으로 최신 도면 재검증, 실이슈면
    i2i edit 1회 더 → 재검증. 이 경로(사진→읽기→작도→검증→edit 교정)의
    수렴 여부 결론.rC  r   rE  rK  rA     verify 비교 조항 불일치c                     dddt        j                        dddt        j                  |       g}t        j                  ||t        d      S Nr^  rF  r_  rG  re  rg  r2   rm  r3   r\  )rK  rt  rc  rr  rK  s      r"   _verifyz!run_top_fp_final.<locals>._verify	  sR    ]3NN9%%;<NN3	
 uuS&&*?') 	)rA   s20_top_fp_topo_verifyztopo-verifyrI  ztopo verify(rM  r  r}  r
  r   c              3   ,   K   | ]  }d |d      ywrO  r   rP  s     r"   r#   z#run_top_fp_final.<locals>.<genexpr>	  s     BkBq{m,krR  r]   rk  rl  rm  ztop_fpflat_read_gpt_edit2.pngr   s20_top_fpflat_read_gpt_edit2r   s20_top_fp_topo_verify2zedit2(i2i)+topo-verifyrp  ztopo verify2()r2   rC   r   rY  r   rZ  _VERIFY_CMP_OLD_VERIFY_CMP_TOPOr/   r]  r6   r7   r8   r   r-   rt   r   )r?   r_  ra  r|  r!   rt  r   r  r   v2rr  rK  s             @@r"   run_top_fp_finalr  	  s0    
_	%Br(|#I
L!"%e,
,C!))DF f$F&FF$^^O-=>F) 	-.A|mCHH'(* +KK$	L
)AgJ<S8%&( )sOW:!H+		BakBBKK3u$:	
  3	kk"34G 	%w/			11C5(?	,3TH_&?@
<*B(0B03!: 	; 	
OR(hZyGR\*+- 	.sOI  	G	s   8H HHztop_pair_photo1_nb2.pngztop_pair_fp1_gpt.pngu  SITE PLAN — the LAYOUT authority for this property: follow ONLY its arrangement (positions, orientations, relative sizes, connections of the property's elements). Do NOT imitate its diagram style, flat colours or circled letters; no markers, no diagram look anywhere in the photograph.u   PREVIOUS PHOTOGRAPH of the same property — the APPEARANCE authority: match its materials, textures, lighting, camera angle, neighborhood character and overall look. Where its layout disagrees with the SITE PLAN, the SITE PLAN wins.c           	         t        j                  d      }t        |d   z  }t        t        z  }|j	                         r|j	                         sJ d       t        j                  d      }|d   }|j
                  |j
                  dd}	 t        j                  d      }||t        <   t        j                  d|       t        j                  d|       t        |        t        j                  d	|t        |ft        |fgt        t        z  
       t        |        t        j                  dt              t         v sJ d       j                  t         t"              t        t        z  fd} ||d      }	|	|d<   t        j                  d|       t%        d|	d    dt'        |	d                 t        |        |	d   s|	d   rdj)                  d |	d   D              }
dj)                  dd|
z   dg      }||t*        <   t        j                  d|       t        j,                  d||gt        t*        z         t        |         |t        t*        z  d      }t*        |d<   ||d<   t%        d|d    dt'        |d                 n|j
                  |d<   d |d!<   t        j                  d|       t        |        |S # t        $ r i }Y 5w xY w)"u
  [⓪-5] 1왕복 상호 수렴 — photo₁=nb2([fp₀+photo₀] 라벨 분리, 기존 45°
    저작 프롬프트 재사용) → 위상 검증(fp₀ vs photo₁) → fp₀ i2i edit 정정
    (fp₁) → 최종 위상 검증. 산출=정합된 (photo₁, fp₁) 쌍.r  r  u   photo₀/fp₀ 없음rD  r   )photo0fp0photo_prompt_planr   top_pair_v1s20_top_pair_photo1r   rA  rx  c                     dddt        j                        dddt        j                  |       g}t        j                  ||t        d      S rz  r{  )plan_imgrt  rc  photo1rK  s      r"   r|  zrun_top_pair.<locals>._verifyA
  sR    ]3NN6"%;<NN8$	
 uuS&&*?') 	)rA   s20_top_pair_verify_fp0verify_fp0_photo1z"pair verify(fp0 vs photo1): match=r  r}  r
  r   c              3   ,   K   | ]  }d |d      ywrO  r   rP  s     r"   r#   zrun_top_pair.<locals>.<genexpr>R
  s     ClBq{m,lrR  r]   rk  rl  rm  s20_top_pair_fp1r   s20_top_pair_verify_fp1fp1verify_fp1_photo1z"pair verify(fp1 vs photo1): match=Tfp1_no_edit)r2   rC   r   rX  r  r]  rt   TOP_PAIR_PHOTO1r6   r   r   NB2_PAIR_FP_LABELNB2_PAIR_PHOTO_LABELrY  r   rZ  r  r  r7   r8   r-   TOP_PAIR_FP1r   )r?   r  r  r  r  p_photopairr   r|  v1rt  p_fixr  r  rK  s                @@r"   run_top_pairr  !
  s    ;;~&DD&&F

C==?szz|D-DD+	
.	/B"#Gkk#((!:<D++/0  'GOKK!7+KKt$sOII#W!3'*>)GHo-/ sO!))DF f$F&FF$^^O-=>FO#F) 
/	0B "D	KKt$	.r'{mSH&') *sOg;2h<		CblCC3u$:	
  !&	%w/			$e3%,.	03TL(*CD"U$& !22g;-R\*+- 	. hhU"]KKt$sOKy  s   K	 	KKc                    t        j                  d      }t        |d   z  }|j                         s
J d|        t	        |       \  }}dj                  d |D              }dd|z   ddd	dt        j                  |      g}t        j                  d
t        |t              }|d   |d}t        j                  d|       t        dt        |d          dt        d |d   D                      t        |      }		 t        j                  d      }
|	|
t         <   |	|
t"        <   t        j                  d|
       t%        |        t        j&                  d|	dt        t         z         t%        |        t        j(                  d|	g t        t"        z         t%        |        i }dt         fdt"        ffD ]  \  }}dddt        j                  |      dddt        j                  t        |z        g}t        j                  d| t*        |t,        d      ||<   t        d| d ||   d!    d"t        ||   d#                  ||d$<   t        j                  d|       t%        |        |S # t        $ r i }
Y kw xY w)%u   [⓪-4c] 사진→VLM 공간 읽기(텍스트)→무참조 T2I 도면(gpt/nb2)→Gemini
    정합 검증. 요소 이름만 주입(위치 서술은 구본 미주입 — 사진에서만).r  r  rD  r   c              3   6   K   | ]  }|d     d|d      yw)r   r  r   Nr   r    r  s     r"   r#   z"run_top_fp_read.<locals>.<genexpr>u
  s$     GY5
"Qy\N3Ys   r^  zKNOWN ELEMENT NAMES:
r_  zPhotograph to survey:s20_top_fp_read)r   readbackrC  z	fp_read: r   u   줄, 비가시=c              3   ,   K   | ]  }|d    r	d  yw)r8  r  Nr   r  s     r"   r#   z"run_top_fp_read.<locals>.<genexpr>
  s     C.qa	l.s   
r   r   s20_top_fpflat_read_gptNr   s20_top_fpflat_read_nb2r   rc  nb2rF  rG  s20_top_fp_verify_re  rg  z
fp_verify[z	]: match=r  r}  rx  rL  )r2   rC   r   r  r  r-   rm  r3   TOP_FP_READ_SYSTEMTOP_FP_READ_SCHEMAr6   r7   r8   r  r<  rt   rX  TOP_FP_READ_NB2r   r   r   rY  TOP_FP_VERIFY_SCHEMA)r?   r  r  r  	alpha_legrm   rp  r  	read_planr   r   rL  rX  rq  rc  s                  r"   run_top_fp_readr  n
  s~    ;;~&D
l#
#C::<3-cU33<$LAyIIGYGGE!9E!AB!89	sE
 uu&(:E')H-8DIKK+	Ic(#:;<=_CHX.CCDF G!(+A++/0 GK GOKK!7+sOII'k)+sOII'Bo-/sOFk*UO,DE	r]3Q^^C5H%;<NN4"9%

  25':2F2,Hu 	
5'6%=+A*BVE];789; 	< F !IhKK+sO7  s   =I/ /I>=I>c                 v   t         t        z  }|j                         s
J d|        t        |       }	 t	        j
                  d      }||t        <   t	        j                  d|       t        |        t	        j                  d|t        |fgt         t        z         t        |        y# t        $ r i }Y nw xY w)u   [⓪-4b] nb2 — 처방(a): 참조=45° 사진이 아니라 **이미 수직인 gpt 도면**
    (nb2 는 참조 기하를 유지하는 습성 → 역이용해 재작도만), 계약=v3 도면
    소스 치환본.u(   gpt 수직 도면 없음(⓪-4 먼저): r   s20_top_fpflat_marked_nb2r   N)r   r$  r  r7  r2   rC   rt   
TOP_FP_NB2r6   r   r   NB2_PLAN_REDRAW_LABELr  s       r"   run_top_fp_nb2r  
  s     -C::<ICC5II<',A++/0 GJKK!7+sOII)10Es/K.Lj(*sO  s   B* *B87B8c                    t        j                         }dj                  |j                  d      xs g       }dj                  |j                  d      xs g       }dt        j                  |      z   }|r|d|z   z  }|r|d|z   z  }t        j                  dt        |t              }t        j                  d|       |d	   }t        d
z  }	 t        j                  d      }	||	d<   ||	d<   t        j                  d|	       t        |        t        j                  d||gt        dz         t        |        t        j                  d|t         |fgt        dz         t        |        y# t        $ r i }	Y w xY w)u`  실사 = 선 스케치(공간+높이 SOT) + LLM 저작 프롬프트 (사용자 재정의:
    실사가 fp 의 높낮이를 오해 → 높이가 보이는 스케치로 교체) — 구조/높이
    재나열 금지, '실제 사는 곳처럼'의 문구는 LLM 저작. 데이터 주입=장소 멤버
    + CREATOR CORRECTIONS + photo_appearance override.r   r   r)   r   r   r   s20_photo_authornumbered_photo_promptr   r   r   numbered_photo_gpt.pngnumbered_photo_nb2.pngs20_numbered_photo_gptr   s20_numbered_photo_nb2r   N)r0   r1   r-   r.   r   r2   r3   r,  r	  r6   r   rC   rt   r   r   r   r!  )
r?   rl   r   r   r>   r=   r  r   sk_pngr   s
             r"   	run_photor  
  st   
 
			B266"45;<J))BFF=17R8K/#--2FFD *+ 	,AJNN	
!#6"
$BKK',
A--F++/0 )*G$%()G$%KK!7+sOII&668sOII&&/0668 sO  s   E- -E;:E;c                 >    t        j                  t        |             S r_   )html_modescapestr)r  s    r"   _escr  
  s    ??3q6""rA   u   ① bd (nb2)r   u   ① bd (gpt)u   ①-2 도면 (gpt)r   u   ①-2 도면 (nb2)r   u   ④ 스케치 (gpt)r   u   ④ 스케치 (nb2)r  u   ⑤ 실사 (gpt)r  u   ⑤ 실사 (nb2)r   u   ⑥ fp (gpt)r   u   ⑥ fp (nb2)r  u   ⑦ 실사 (gpt)r  u   ⑦ 실사 (nb2)u   ⑧ 스케치 (gpt)plan_sketch_nb2.pngu   ⑧ 스케치 (nb2)plan_sketch_nb2src_gpt.pngu(   ⑧-2 스케치 (gpt, nb2 도면 기반)plan_sketch_nb2src_nb2.pngu(   ⑧-2 스케치 (nb2, nb2 도면 기반)plansketch_photo_gpt.pngu   ⑨ 실사 (gpt)plansketch_photo_nb2.pngu   ⑨ 실사 (nb2)plansketch_photo_nb2src_gpt.pngu.   ⑨-2 실사 (gpt, ⑧-2 gpt 스케치 기반)plansketch_photo_nb2src_nb2.pngu.   ⑨-2 실사 (nb2, ⑧-2 gpt 스케치 기반)u-   ⑩ 상세 스케치 (gpt, ① bd nb2 기반)bd_sketch_nb2.pngu-   ⑩ 상세 스케치 (nb2, ① bd nb2 기반)bdsketch_photo_gpt.pngu*   ⑪ 실사 (gpt, ⑩ gpt 스케치 기반)bdsketch_photo_nb2.pngu*   ⑪ 실사 (nb2, ⑩ gpt 스케치 기반)bd_photo_gpt.pngu*   ⑫ 실사 직행 (gpt, ① bd nb2 기반)bd_photo_nb2.pngu*   ⑫ 실사 직행 (nb2, ① bd nb2 기반)bd_sketch_gptsrc_gpt.pngu/   ⑩-2 상세 스케치 (gpt, ① bd gpt 기반)bd_sketch_gptsrc_nb2.pngu/   ⑩-2 상세 스케치 (nb2, ① bd gpt 기반)bdsketch_photo_gptsrc_gpt.pngu.   ⑪-2 실사 (gpt, ⑩-2 gpt 스케치 기반)bdsketch_photo_gptsrc_nb2.pngu.   ⑪-2 실사 (nb2, ⑩-2 gpt 스케치 기반)bd_photo_gptsrc_gpt.pngu,   ⑫-2 실사 직행 (gpt, ① bd gpt 기반)bd_photo_gptsrc_nb2.pngu,   ⑫-2 실사 직행 (nb2, ① bd gpt 기반)r;  u/   ⑬ 무참조 T2I 실사 (gpt, 프롬프트만)r<  u/   ⑬ 무참조 T2I 실사 (nb2, 프롬프트만)u(   ⑬-2 무참조 T2I 45° 부감 (nb2, a)rF  u(   ⑬-2 무참조 T2I 45° 부감 (nb2, b)rN  u(   ⑬-2 무참조 T2I 45° 부감 (gpt, a)rO  u(   ⑬-2 무참조 T2I 45° 부감 (gpt, b)r  u'   ⑬-3 계단 수정 i2i (gpt, A 편집)u'   ⑬-3 계단 수정 i2i (nb2, A 편집)r  u'   ⑭-1 역방향 bd (gpt, 실사 기반)u'   ⑭-1 역방향 bd (nb2, 실사 기반)u'   ⑭-2 역방향 fp (gpt, 실사 기반)u'   ⑭-2 역방향 fp (nb2, 실사 기반)r  u4   ⑭-3 역방향 스케치 (gpt, ⑭-2 gpt fp 기반)r  u4   ⑭-3 역방향 스케치 (nb2, ⑭-2 gpt fp 기반)r  u,   ⑮-1 bd 90° 회전 (gpt, ⑭-1 nb2 기반)r  u,   ⑮-1 bd 90° 회전 (nb2, ⑭-1 nb2 기반)r  u,   ⑮-2 fp 90° 회전 (gpt, ⑭-2 nb2 기반)r  u,   ⑮-2 fp 90° 회전 (nb2, ⑭-2 nb2 기반)r  u)   ⑯ 완전 수직 fp (gpt, 실사 기반)u)   ⑯ 완전 수직 fp (nb2, 실사 기반)u/   ⑯-2 수직 fp + 원형 알파벳 마커 (gpt)u/   실내 fp (production 자산 — 스타일 ref))r  r  zfp_l04_rooftop_room_main.pngc                     i } 	 t        t        t              j                  dz        D ]  }t	        j
                  |      }|j                  d      dk(  s-|j                  d      s?|j                  d      rQ|j                  d      xs g D cg c]  }t        |      j                   c}| t        |d         j                  <    	 | S c c}w # t        $ r Y | S w xY w)u^   runlog 에서 산출 파일별 실전송 참조 이미지 목록 (마지막 실생성 기준).zrunlog.jsonlr'   rK  rs  skipr   )	openr   __file__parentjsonloadsr.   r]  rt   )r  linedr  s       r"   	_refs_mapr    s    
Ah..?@D

4 AuuV}%!%%,quuV}45EE&M4GR4G*J4Ga +/q',,4G*J$qx.%%& A H	*J Hs6   AC C (C :C C-C C 	C C c                   ćŇƇǇȗ dj                  d t        | d   d       D              }dj                  d | d   D              }t               ƈfdĈfd	} |d
      \  }} |d      \  }}d}	 |d      \  }
} |d      \  }} |d      \  }} |d      \  }} |d      \  }} |d      \  }} |d      \  }} |d      \  }}	 t        j                  d      }d|v }	|	xr | }d|v }|xr |xr | } |d      \  }} |d      \  } }! |d      \  }"}# |d      \  }$}% |d      \  }&}' |d      \  }(}) |d      \  }*}+ |d      \  },}- |d      \  }.}/ |d      \  }0}1 |d       \  }2}3 |d!      \  }4}5 |d"      \  }6}7 |d#      \  }8}9 |d$      \  }:}; |d%      \  }<}= |d&      \  }>}? |d'      \  }@}A |d(      \  }B}C |d)      \  }D}E |d*      \  }F}G |d+      \  }H}I |d,      \  }J}K |d-      \  }L}M |d.      \  }N}O |d/      \  }P}Q |d0      \  }R}S |d1      \  }T}U |d2      \  }V}W |d3      \  }X}Y |d4      \  }Z}[ |d5      \  }\}] |d6      \  }^}_ |d7      \  }`}a |d8      \  }b}c |d9      \  }d}e |d:      \  }f}g |d;      \  }h}i |d<      \  }j}k |d=      \  }l}m |d>      \  }n}o |d?      \  }p}q |d@      \  }r}si g }tt        D ]&  \  }u ||u      \  }v}w|vȉ<   tj                  |w       (  |t              \  }x}y |t              \  }z}{ |t              \  }|}} |t              \  }~} |t              \  }} |t              \  }}	 t        |       \  }}dj                  dA |D              }dB| dC}d|v }|xr |xr | }d|v }|xr |xr | }d|v xr |xr |! xs d|v xr |#xr |% xs d|v xr |'xr |) xs d|v xr |/xr |1 xs| d |v xr |3xr |5 xsl d"|v xr |7xr |9 xs\ d$|v xr |;xr |= xsL d&|v xr |?xr A xs< d(|v xr Cxr E xs, d*|v xr Gxr I xs d,|v xr Kxr M xs d.|v xr Oxr Q xs d0|v xr Sxr U xs d2|v xr Wxr Y xs d4|v xr [xr ] xs d6|v xr _xr a xs d8|v xr cxr e xs d:|v xr gxr i xs d<|v xr kxr m xs d>|v xr oxr q xs d@|v xr s xsz t        dD   dE   |v xr t        t       xs\ t        |v xr y xsM t        |v xr { xs> t        |v xr } xs/ t        |v xr xr  xs t        |v xr  xs d|v xr |+xr |- }dF } |dGdH      } |dIdJ      } |dKdL      } |dMdN      } |dOdP      } |dQdR      }d}	 t        j                  dS      }g }dTD ]^  \  }}|   }dj                  dU |dV   D              }|j                  dW| dX|dY   rdZnd[ d\t!        d]          d^rd_ d`ndz          ` j#                  da      }|rdbt!               dcnd}ddt!        j#                  ded             dfdj                  |      z   |z   dgz   }d}	 t        j                  dh      }t%        t&              g }dTD ]l  \  }}|   }dj                  fdi|dj   D              }j                  dW| dk|dl    dmt!        |dl             dndoj                  |dp          dq| dC       n drdj                        z   dgz   }d}t        dD   dE   |v }d }	 t        j                  ds      }srbxs i j#                  dt      dj                  ǈfdut        D              }d}rj#                  dv      rg }dTD ][  \  }}dv   |   }dj                  dw |dj   D              }j                  dW| dx|dl    dydoj                  |dp          dz| dC	       ] j#                  d{i       }d|dj                        z   d}z   d~j                  d |j)                         D              z   dǛ dz   }d}rj#                  d      rg }dTD ]T  \  }}d   |   d   }dj                  d |D              }|j                  dW| dt+        |       d|rd_ d`ndz          V j#                  d      rdnd}ddj                  |      z   |z   dgz   }d}	 t        j                  d      }|d   }dj                  d |d   D              }d}|j#                  d      xs g D ]  }|d   } ||d         \  }}dj                  d |d   D              }d|d    |j#                  d      rdnd dt!        d          dd   rdZnd[ d dt!        d]          rd_ d`ndz   j#                  d      rdt!        d          d^ndz   dz   z  } d}dD ]t  \  }}j#                  d      xs i j#                        }|s-dj                  d dV   D              }dW d|d   rdZnd[ dt!        d]          d^rd_ d`ndz   z  }v d~ d d dt!        t-        d      j                  d                dxs d d d}d}	 t        j                  d      }|j#                  d      r |d         \  }}nd} |d         \  }} ||d         \  }}d}dD ]a  \  }}j#                  |      }|sdj                  d d   D              }dW d|d   rdZnd[ dt!        d]          d^rd_ d`ndz   z  }c j#                  d      rdz  }d d d d dxs d d}d d d dx dz d| d d d d}d}	 t        j                  d      }dj                  d |d   D              }d| dC} ddū      }|r|s
|ssssdnd}dj                  dǄ t        |j)                               D              xs |rdt!        |       dɝnd}t.        j1                  dj                  g dʑ dˑ d̑| d| d͑|
 d| dΑ| dϑ dБ| dё| d| dґ dӑ| d| dԑ dӑ| d|  dՑ|" d|$ d֑|& d|( dב dӑ|* d|, dؑ|. d|0 dّ|2 d|4 dڑ dӑ|6 d|8 dۑ dӑ|: d|< dܑ|> d@ dݑB dD dޑF dH dߑ dӑJ dL d dӑN dP dR dT d d dV dX dZ d\ d^ d` db dd df dh dj dl dn dp dr d d| d| d|Û d      d       t3        dt.                y # t
        $ r i }Y w xY w# t
        $ r d}Y 
uw xY w# t
        $ r Y w xY w# t
        $ r Y w xY w# t
        $ r Y w xY w# t
        $ r Y w xY w# t
        $ r Y w xY w# t
        $ r Y qw xY w)Nr	   c           
   3   j   K   | ]+  }d |d    dt        |d          dt        |d          d - yw)<tr><td>r   	</td><td>r   r   
</td></tr>Nr  r  s     r"   r#   zbuild_page.<locals>.<genexpr>&  sN      @ ?A 1U8*Id1Y<&8%9 :AiL!"*	.>s   13r   c                     | d   S )Nr   r   )r  s    r"   r   zbuild_page.<locals>.<lambda>)  s    QuXrA   r   c              3   :   K   | ]  }d t        |       d  yw<li></li>Nr  r   s     r"   r#   zbuild_page.<locals>.<genexpr>*  s%      ;9 47)5)9r   r   c                     j                  |       }|y|sydj                  d |D              }dt        |       dS )Nr	   u)    · <b>참조 없음(프롬프트만)</b>rZ   c              3   H   K   | ]  }t         j                  ||        y wr_   )GALLERY_NAMESr.   r  s     r"   r#   z2build_page.<locals>._refs_label.<locals>.<genexpr>4  s     @4a-++Aq14s    "u    · <b>참조: </b>)r.   r-   r  )fnamer   rm   refs_maps      r"   _refs_labelzbuild_page.<locals>._refs_label.  sF    ||E"<>		@4@@ eT22rA   c                    t         | z  }|j                         rit        j                  j                  |j	                         j
                        }d|  dt        |j                                d|  d|dd |        ddfS d	d
|  dz   dfS )Nz<img src='out/blockset/z?v=z'><p class='cap'> (z%H:%M:%Sr   </p>Tu/   <div class='pending'>생성 대기/중…</div>z<p class='cap'>F)r   r  datetimefromtimestampstatst_mtimer  	timestamp)r  rr  tsr  s      r"   _cellzbuild_page.<locals>._cell7  s    5L88:""001B1BCB-eWCBLLN8K7L M&&+WBr(m1"5)*$0267 7 A t,-.34 	4rA   r   r   Fr   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  r  r  r  r  r  r;  r<  rE  rF  rN  rO  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  c              3      K   | ]8  }d |d    dt        |d          dt        |j                  dd             d : yw)r  r  r  r   r   r	   r  N)r  r.   r  s     r"   r#   zbuild_page.<locals>.<genexpr>  sU         q{m9T!I,-?,@ Ai,-.j:s   >A uN   <table><tr><th>문자</th><th>요소 (EN)</th><th>의미 (정화본)</th></tr>z</table>r   r  c           	          	 t        j                  |      }d|  dt        |d          dt        |d          dS # t        $ r Y yw xY w)uR   저작 프롬프트 노트 — KO 번역 + 영문 원본(실전송) 함께 게시.r	   z<div class='note'><b>u    (한국어 번역):</b><br>r   u:   <details><summary>영문 원본 (실전송)</summary><pre>r   z</pre></details></div>)r2   rC   rt   r  )r  	plan_namer  s      r"   _author_notez build_page.<locals>._author_note  si    	Y'B (w.J,-./L,-.//EG 	H  		s   ; 	AAu   LLM 저작 실사 프롬프트r  u)   [경로 A] LLM 저작 실사 프롬프트r  u+   [경로 C-2] LLM 저작 실사 프롬프트r*  u)   [경로 D] LLM 저작 실사 프롬프트r1  u0   [경로 E] LLM 저작 무참조 T2I 프롬프트r:  u@   [경로 E-2] LLM 저작 무참조 T2I 프롬프트 (45° 부감)rD  r~  r  c              3   :   K   | ]  }d t        |       d  ywr  r  r    r  s     r"   r#   zbuild_page.<locals>.<genexpr>       KNqtDG9E2Nr   rx  z<p><b>u%   </b> — 올라갈 수 있는가: <b>rw  YESNOz</b><br>rY  r  z<ul>z</ul>user_verdict_kou   <p style='color:#a00'><b>★ z</b></p>uM   <div class='note'><b>계단 등반 가능성 검증 (VLM 교차) — 대상: rz  r  z</div>rk  c           
   3   r   K   | ].  }d |d    dt        |d             dt        |d          d 0 yw)r  rX  r  z
)</td><td>rY  r  Nr  )r    r  r  s     r"   r#   zbuild_page.<locals>.<genexpr>  sS      ( 'A 1W:,bc!G*o)>(? @AlO,-Z9&s   47r\  u   </b> — 선택: <b>rZ  r  u   )</b>, 순위: z > r[  u7   </p><table><tr><th>후보</th><th>판정 (KO)</th></tr>us   <div class='note'><b>⑬-2 프롬프트 충실도 판정 (VLM 교차)</b> — A=nb2 a / B=nb2 b / C=gpt a / D=gpt br  r  c              3   N   K   | ]  \  }}d |k(  rdnd |    d| d  yw)z<div>u#   <p class=selbadge>★ 선택됨</p>r	   u   <p class='cap'><b>후보 z</b></p></div>Nr   )r    r  r  sel	top_cellss      r"   r#   zbuild_page.<locals>.<genexpr>  sF      * )Q SCZ9RP~7uNL(s   "%r  c           
   3   X   K   | ]"  }d |d    d|d    dt        |d          d $ yw)r  rX  r  r  rY  r  Nr  r  s     r"   r#   zbuild_page.<locals>.<genexpr>  sH      , + qzl)AgJ< @,01=*   (*u   </b> — winner: <b>u   </b>, 순위: uL   </p><table><tr><th>후보</th><th>점수(0-10)</th><th>판정 (KO)</th></tr>r  u7   <div class='note'><b>⓪-2 VLM 교차 점수 판정</b>u   <p><b>합산:</b> z / c              3   0   K   | ]  \  }}| d |   yw)=Nr   )r    r  r  s      r"   r#   zbuild_page.<locals>.<genexpr>   s     Gfc1uAaS\s   u    → <b>선택 = u0   </b> (동점 시 Gemini 순위 우선)</p></div>r  r
  c              3   @   K   | ]  }d t        |d          d  ywr  r  r  Nr  r   s     r"   r#   zbuild_page.<locals>.<genexpr>)  s+      .&,  $D:$7#8>&,   u   </b> — 결함 u   건</p>r  uH   <p><b>결함 0 — i2i 수정 생략, 선택본 그대로 사용</b></p>u   <div class='note'><b>⓪-3 결함 질문 (VLM 교차, 대상=선택본) — 취합=양쪽 fix 지시 전부 나열(판단 개입 0)</b>rC  r  c              3   |   K   | ]4  }d |d    dt        |d          |d   rdnd dt        |d          d 6 y	w)
r  r   r  r   r8  r	   u"    <i>(사진 비가시·추정)</i>r   r  Nr  r  s     r"   r#   zbuild_page.<locals>.<genexpr>7  s_      ' &A 1U8*Id1Y<.@-A92+OP QAiL)**6 &s   :<rE  rL  rK  c              3   @   K   | ]  }d t        |d          d  ywr  r  rP  s     r"   r#   zbuild_page.<locals>.<genexpr>@  +      3&1  $D:$7#8>&1r  u   <h2>⓪-4d 교정 루프 round rJ  rW  u	    (최종)u    — 검증 대상: u    → 정합: <b>r  z </b></h2><div class='grid'><div>z</div><div class='note'>rT  u(   <p>→ CORRECTIONS 되먹여 재작도: z</div></div>))rc  zT2I gpt)r  zT2I nb2c              3   :   K   | ]  }d t        |       d  ywr  r  r   s     r"   r#   zbuild_page.<locals>.<genexpr>S  r  r   u   </b> — 정합: <b>u   </b> · u  
<h2>⓪-4c 경로 재설계 — 사진→VLM 공간 읽기(텍스트)→<b>무참조 T2I</b> 도면
(i2i 재투영 폐기: "사진을 보고 그려라"→"사진을 읽고, 읽은 것을 그려라")
→ Gemini VLM 도면↔사진 정합 검증</h2>
<div class='grid'>
<div>u7   <p class='cap'><b>무참조 T2I gpt</b></p></div>
<div>u  <p class='cap'><b>무참조 T2I nb2</b></p></div>
</div>
<details><summary>VLM 이 사진에서 읽은 공간 구조 (측량 줄 — 위치는 사진
에서만, 요소 이름만 주입)</summary>
<table><tr><th>#</th><th>요소</th><th>사진에서 읽은 위치 (KO)</th></tr>
z</table>
<pre>
   uU   </pre></details>
<div class='note'><b>Gemini VLM 정합 검증 (도면 vs 사진)</b>u    — 대기z</div>
r   r  r  u.   <div class='pending'>fp 정정 대기…</div>r  r  ))r  u#   위상 검증 ① fp₀ vs photo₁)r  u;   위상 검증 ② fp₁(edit 정정) vs photo₁ — 최종c              3   @   K   | ]  }d t        |d          d  ywr  r  rP  s     r"   r#   zbuild_page.<locals>.<genexpr>|  r  r  r  u<   <p><b>fp 정정 불필요 — fp₀ 그대로 확정</b></p>ut  
<div class='pairchain'>
<h1 style='margin-top:0'>⓪-5 상호 수렴 왕복 — 측량 포기, 정합 방향 반전
(사용자 아이디어)</h1>
<div class='note'>photo₀(선택·수정본)+fp₀(읽기→그리기본) →
<b>photo₁=nb2 재생성</b>(참조 관할 분리: fp₀=배치 SOT / photo₀=재질·룩
SOT, 충돌 시 fp 우선, 프롬프트=기존 45° 저작본) → 위상 검증 → 잔여
어긋남은 <b>fp₀ 를 i2i edit 정정</b>(fp₁) → 최종 위상 검증. 개방 재귀
금지(1왕복) — 산출=정합된 (photo₁, fp₁) 쌍.</div>
<h2>입력 쌍 → 산출 쌍</h2>
<div class='grid'>
<div>u?   <p class='cap'><b>입력 photo₀</b> (룩 SOT)</p></div>
<div>uY   <p class='cap'><b>입력 fp₀</b> (배치 SOT)</p></div>
</div>
<div class='grid'>
<div>ua   <p class='cap'><b>산출 photo₁</b> — fp 배치를
따라 재생성된 실사</p></div>
<div>u   <p class='cap'><b>산출 fp₁</b> — photo₁ 기준 정정된
도면</p></div>
</div>
<div class='note'><b>위상 검증 (Gemini)</b>z</div>
</div>
u(  
<div class='topchain'>
<h1 style='margin-top:0'>⓪ TOP 체인 — 장소 실사 3롤 → VLM 점수 선택 →
결함 취합 i2i 수정 → 수직 fp+원형 알파벳 마커</h1>
<div class='note'>⓪-1 프롬프트=⑬-2 저작본(45° 부감, 장소 전체=골목·대문·
마당·빌라·외부 계단·옥상) <b>그대로 재사용</b>(신규 저작 0) — nb2 무참조
T2I 3롤(변인=샘플링만) → ⓪-2 GPT/Gemini VLM 각 0-10 점수 합산 최고 1장
선택 → ⓪-3 양쪽 VLM에 "잘못된 부분" 질문 → 코드 취합(양쪽 fix 지시 전부)
→ nb2 i2i 수정 → ⓪-4 수정본 기반 <b>⑯-2 계약 동일본</b>으로 완전 수직
fp+원형 알파벳(A~P) 마커 gpt i2 1장.</div>
<h2>⓪-1 후보 3롤 (nb2, 무참조 T2I — 같은 프롬프트)</h2>
<div class='grid3'>u  
<h2>⓪-3 수정본 (nb2 i2i — 취합된 결함만 수정, 나머지 보존 계약=⑬-3 재사용)
과 ⓪-4 수직 fp+알파벳 마커 (⑯-2 계약 동일본, 원본만 수정본으로 교체 —
gpt i2 / nb2 i2i 엔진 대조)</h2>
<div class='grid3'>
<div>z</div>
<div>u   <p class='cap'><b>⓪-4 gpt i2 (v3: 사진→수직 재투영,
입면 접기 금지) — ★사용자 판정: 기하 오류(i2i 재투영 한계)</b></p></div>
<div>u   <p class='cap'><b>⓪-4b nb2 i2i (v3: 참조=⓪-4 gpt
수직 도면 — gpt 필사라 비교 무의미, 경로 폐기)</b></p>
</div>
</div>
z
</div>
zC
<hr style='border:none;border-top:4px double #bbb;margin:34px 0'>
rf   c              3      K   | ]]  }d t        |d          dt        |d          ddj                  d |d   D               ddj                  d |d	   D               d
	 _ yw)r  r   r  rW   z<br>c              3   2   K   | ]  }t        |        y wr_   r  rP  s     r"   r#   z'build_page.<locals>.<genexpr>.<genexpr>  s     F0E1tAw0Es   rX   z</td><td class='cap'>c              3   \   K   | ]$  }t        |d          dz   t        |d         z    & yw)r   rs   r   Nr  r   s     r"   r#   z'build_page.<locals>.<genexpr>.<genexpr>  s0     *n`m[\4(+<t+Cd1W:FV+V`ms   *,r$   r  N)r  r-   r\   s     r"   r#   zbuild_page.<locals>.<genexpr>  s      %
 $	 tAiL)* ++,-. /;;F2D0EFFG H%{{*n`abl`m*nnooy{ $s   A#A%r   u   <h2>②-2 씬-중요 요소 분석 (LLM, 씬/샷 원문 전체 — 미니멀 재작성에 '관계 왜곡 금지'로 주입)</h2><table><tr><th>요소</th><th>왜 중요한가 (KO)</th><th>공간 사실 (실전송)</th><th>근거 인용</th></tr>u@   [경로 B-2 v2] 씬 분석 기반 LLM 저작 실사 프롬프트r  z(<meta http-equiv='refresh' content='30'>c              3   X   K   | ]"  \  }}d t        |       dt        |       d $ yw)z<details><summary>z</summary><pre></pre></details>Nr  )r    ra   r!   s      r"   r#   zbuild_page.<locals>.<genexpr>  s4      20DAq T!WI_T!WI=MN0r
  u7   <details><summary>실전송 프롬프트</summary><pre>r  z&<!doctype html><meta charset='utf-8'>
u  
<title>s20 번호 마커 블록 다이어그램</title>
<style>
body{font-family:system-ui,'Apple SD Gothic Neo',sans-serif;margin:24px;
background:#fafafa;color:#222;max-width:1400px}
h1{font-size:21px} h2{font-size:16px;margin-top:26px;border-bottom:2px solid
#ddd;padding-bottom:4px}
img{width:100%;display:block;background:#fff;border:1px solid #ddd;padding:8px}
.cap{font-size:12px;color:#555}
table{border-collapse:collapse;font-size:13.5px;background:#fff;width:100%}
td,th{border:1px solid #e0e0e0;padding:5px 9px;vertical-align:top}
ul{font-size:12.5px;color:#556;background:#fff;border:1px solid #e0e0e0;
padding:10px 26px}
.grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
pre{white-space:pre-wrap;background:#f4f4f4;padding:10px;font-size:12px}
.pending{display:flex;align-items:center;justify-content:center;height:300px;
color:#999;background:repeating-linear-gradient(45deg,#f4f4f4,#f4f4f4 12px,
#fcfcfc 12px,#fcfcfc 24px)}
.note{background:#fff8e6;border:1px solid #eeddaa;padding:10px 14px;
font-size:13.5px}
.topchain{background:#eef6ee;border:3px solid #2e7d32;border-radius:8px;
padding:16px 18px;margin-bottom:8px}
.topchain h2{border-bottom-color:#bcd6bc}
.pairchain{background:#eef2f8;border:3px solid #1565c0;border-radius:8px;
padding:16px 18px;margin:14px 0 8px}
.pairchain h2{border-bottom-color:#bcd0e8}
.grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}
.selbadge{background:#2e7d32;color:#fff;display:inline-block;
padding:2px 10px;font-size:12px;font-weight:700;border-radius:4px;
margin:0 0 4px}
</style>
u<  
<h1>s20 — 번호 마커 블록 다이어그램 (A‴ 최종형 nb2 × LLM 번호 매김)</h1>
<div class='note'>기반=<b>s18 이전 코드 그대로</b>(STYLE_FLAT+lean, A⁗ containment
반영). LLM 이 STRUCTURE 줄들에 번호를 매기고 이름을 전부 번호 참조로 재작성 →
스타일 계약의 no-text 를 "지정 번호 1개만 허용"으로 교체해 nb2 1장 생성.
번호 의미는 아래 범례(한국어=desc_visual 정화본 — 물리·현재형만, 서사/과거
제거).</div>
<h2>① 번호 블록 다이어그램 (nb2/gpt) — ★v10 미니멀: 소속+대략 위치만
지정(장소 요소 전부 유지·주변만 병합, 크기어/형태절 0), 씬-중요 요소 관계
왜곡 금지(②-2 주입), 뷰=탑다운~2.5D 축측(풀 3D 금지), 물리 정합 유지</h2>
<div class='grid'>
<div>uc  </div>
</div>
<h2>①-2 실외 도면형 번호 다이어그램 (gpt/nb2) — 진짜 도면 어휘(사이트 플랜),
실외 전용(내부 방/구획 절대 금지), 번호 마커 유지; ★v10 미니멀=①과 같은 최소
구조 줄 공유(씬-중요 관계 보호), 뷰=도면~2.5D 축측 허용, 디테일=모델 재량</h2>
<div class='grid'>
<div>u  </div>
</div>
<h2>② 번호 범례 (num ↔ 요소 — 한국어=desc_visual 정화본: 물리·현재형만,
사건/과거/행위 서사 제거)</h2>
<table><tr><th>번호</th><th>요소 (EN)</th><th>의미 (물리 서술 — desc_visual
정화본)</th></tr>
z	</table>
uH   
<h2>③ LLM 이 재작성한 STRUCTURE 줄 (실전송 원문)</h2>
<ul>u   </ul>
<h2>④ (구) bd 기반 선 스케치 — 기반=numbered_bd_nb2 (사선 매싱 선화, 높낮이/
층수 가독용; ★구 bd 산출 — 새 bd 기준 아님)</h2>
<div class='grid'>
<div>uw   </div>
</div>
<h2>⑤ (구) 스케치 기반 실사 — 기반=numbered_sketch_gpt (④의 산출; ★구 체인)</h2>
z
<div class='grid'>
<div>uf   </div>
</div>
<h2>⑦ [경로 A] ①-2 도면 → 실사 직행 — 기반=numbered_plan_gpt.png</h2>
u   </div>
</div>
<h2>⑧ [경로 B-1] ①-2 도면 → 선 스케치 — 기반=numbered_plan_gpt.png
(사선 매싱 선화, 높이 레이어 텍스트 주입)</h2>
<div class='grid'>
<div>u   </div>
</div>
<h2>⑧-2 [경로 B-1 대조] ①-2 <b>nb2 도면</b> 기반 → 선 스케치 — 기반=
numbered_plan_nb2.png (같은 프롬프트 계약, 참조 도면만 nb2 산출로 교체)</h2>
<div class='grid'>
<div>u/  </div>
</div>
<h2>⑨ [경로 B-2 v2] 스케치 → 실사 — 기반=plan_sketch_gpt.png (⑧의 산출;
실사 프롬프트=<b>씬 원문 전체 분석 저작</b> — 사는 사람의 삶에 맞는 일상 요소를
LLM 이 추가, 일회성 사건/극적 소품 제외, 빈 무대 복사 금지)</h2>
u  </div>
</div>
<h2>⑨-2 [경로 B-2 대조] ⑧-2 <b>gpt 스케치</b>(nb2 도면 기반) → 실사 —
기반=plan_sketch_nb2src_gpt.png (실사 저작 프롬프트=⑨와 <b>동일본 재사용</b>,
참조 스케치만 교체한 변인 격리 A/B)</h2>
<div class='grid'>
<div>u+  </div>
</div>
<h2>⑩ [경로 C-1] ① bd(nb2) → <b>상세</b> 선 스케치 — 기반=numbered_bd_nb2.png
(사용자 지시 "조금 더 상세히": 디딤판·난간·파라펫·개구부 프레임·설비 지지대
까지 선으로, 여전히 선화·무텍스트)</h2>
<div class='grid'>
<div>ui   </div>
</div>
<h2>⑪ [경로 C-2] ⑩ <b>gpt 스케치</b> → 실사 — 기반=bd_sketch_gpt.png</h2>
u   </div>
</div>
<h2>⑫ [경로 D] ① bd(nb2) → 실사 <b>직행</b> — 기반=numbered_bd_nb2.png
(높이 레이어 색=실제 높이로 번역 지시)</h2>
u   </div>
</div>
<h2>⑩-2 [경로 C-1 대조] ① bd <b>gpt</b> → 상세 선 스케치 — 기반=
numbered_bd_gpt.png (⑩과 같은 계약, bd 엔진만 교체한 변인 격리 A/B)</h2>
<div class='grid'>
<div>u=  </div>
</div>
<h2>⑪-2 [경로 C-2 대조] ⑩-2 <b>gpt 스케치</b> → 실사 — 기반=
bd_sketch_gptsrc_gpt.png (실사 저작=신규: <b>주변 자유 창작</b> 조항 —
참조의 이웃 박스는 자리 표시자일 뿐, 주변 시설은 모델이 실제 동네답게 채움)</h2>
<div class='grid'>
<div>u   </div>
</div>
<h2>⑫-2 [경로 D 대조] ① bd <b>gpt</b> → 실사 직행 — 기반=numbered_bd_gpt.png
(실사 저작=신규: <b>주변 자유 창작</b> 조항 반영)</h2>
<div class='grid'>
<div>u  </div>
</div>
<h2>⑬ [경로 E] <b>무참조 T2I</b> 실사 — 이미지 참조 0, LLM 저작 프롬프트가
구조(v12 미니멀 줄)+실물 룩 전부 담음 (번호/다이어그램 언급 금지, 주변 자유
창작, 시각적 현재 상태만)</h2>
u   </div>
</div>
<h2>⑬-2 [경로 E-2] 무참조 T2I 실사, 카메라=<b>측면 45° 상공</b> — nb2/gpt
각 2장 (전부 같은 저작 프롬프트=변동 확인; 카메라 계약 줄만 교체한 재저작)</h2>
u{  
<h2>⑬-3 계단 수정 i2i — 원본=A(textonly45_photo_nb2_a.png), 편집 계약=
"계단만 물리적으로 오를 수 있게 다시 그려라(연속 flight·랜딩 연결·지면
접지·옥상 착지·난간 정합, 녹슨 증축 철계단 성격 유지), 나머지 전부 보존"
(사용자 판정: 원본 계단=중간 끊김 등반 불가)</h2>
<div class='grid'>
<div>u  </div>
</div>
<h2>⑭-1 [역방향] 실사 → bd — 원본=stairfix_nb2.png (★기존 bd 계약
STYLE_STRUCT_MIN 그대로 재사용, 소스 참조만 구조 줄→첨부 사진으로 치환;
무텍스트, 텍스트 주입 0=이미지 계보만)</h2>
<div class='grid'>
<div>u   </div>
</div>
<h2>⑭-2 [역방향] 실사 → fp — 원본=stairfix_nb2.png (사진 배치를 사이트 플랜
도면 어휘로 번역, 실외 전용·무텍스트)</h2>
<div class='grid'>
<div>u   </div>
</div>
<h2>⑭-3 [역방향] ⑭-2 fp(gpt) → 선 스케치 — 높이는 도면 단서(개구부 리듬·
계단 런·파라펫)에서 추정 (텍스트 주입 0)</h2>
<div class='grid'>
<div>u   </div>
</div>
<h2>⑮-1 카메라 90° 우회전 재작도 — bd, 원본=rev_bd_nb2.png (기존 bd 계약
내용 유지, 노트만 "같은 배치·시야만 시계방향 90° 회전"으로 교체)</h2>
<div class='grid'>
<div>u   </div>
</div>
<h2>⑮-2 카메라 90° 우회전 재작도 — fp, 원본=rev_fp_nb2.png (기존 fp 계약
내용 유지, 노트만 교체)</h2>
<div class='grid'>
<div>u   </div>
</div>
<h2>⑯ 완전 수직 fp — 원본=stairfix_nb2.png (기존 fp 계약 유지 + ★완전 수직
orthographic 강조: 3D/2.5D/축측 절대 금지, 입면·볼륨 측면 불가시, 순수 평면
기하만)</h2>
<div class='grid'>
<div>u/  </div>
</div>
<h2>⑯-2 수직 fp + <b>원형 알파벳 위치 마커</b> — 원본=stairfix_nb2.png,
gpt i2 1장 (⑯ 계약 유지, no-text→지정 원형 알파벳만 허용; 요소 지칭=번호→
알파벳 A~P 결정론 재라벨 — 한 글자 26자 판독 용이)</h2>
<div class='grid'>
<div>u   </div>
</div>
<h2>⑥ fp — bd 참조 없음(배치=FACTS 텍스트 SOT, 이미지=드래프팅 스타일 ref
1장만; 무번호·무텍스트·매우 상세)</h2>
<div class='grid'>
<div>zutf-8)encodingzpage -> )r-   ri   r  r2   rC   rt   r  r/   r  r$  r  rX  r  r  r  allr  r.   r  rl  r   r8   chrPAGE
write_textr7   )r?   promptrowsr:   r  cellbd_donebdg_cellbdg_donebd_gpt_requestedpl_gpt_cellq1pl_nb2_cellq2sk_gpt_cells1sk_nb2_cells2fp_nb2_celld1fp_gpt_celld2ph_gpt_cellp1ph_nb2_cellp2plan_promptspending_bd_gptplan_requestedpending_planpa_gpt_cella1pa_nb2_cella2ps_gpt_cellb1ps_nb2_cellb2ps2_gpt_celle1ps2_nb2_celle2pp_gpt_cellc1pp_nb2_cellc2pp2_gpt_cellg1pp2_nb2_cellg2bs_gpt_cellh1bs_nb2_cellh2bsp_gpt_celli1bsp_nb2_celli2bp_gpt_cellj1bp_nb2_cellj2bs2_gpt_cellk1bs2_nb2_cellk2bsp2_gpt_cellm1bsp2_nb2_cellm2bp2_gpt_celln1bp2_nb2_celln2tx_gpt_cello1tx_nb2_cello2tx45_a_cellq1xtx45_b_cellq2xtx45g_a_cellr1xtx45g_b_cellr2xsf_gpt_cells1xsf_nb2_cells2xrb_gpt_cellt1xrb_nb2_cellt2xrf_gpt_cellu1xrf_nb2_cellu2xrs_gpt_cellv1xrs_nb2_cellv2xr9b_gpt_cellw1xr9b_nb2_cellw2xr9f_gpt_cellx1xr9f_nb2_cellx2xff_gpt_celly1xff_nb2_celly2xffm_gpt_cellz1xtop_donerq  coktopfix_celltfx
topfp_celltfptopfp_nb2_celltfp2topfpr_gpt_celltfr1topfpr_nb2_celltfr2pair_photo1_celltpp1r  r  
alpha_rowsalpha_leg_htmlsketch_requestedpending_sketchphoto_requestedpending_photopending_chainsr  photo_author_htmlplan_photo_author_htmlbdsketch_photo_author_htmlbd_photo_author_htmltextonly_photo_author_htmltextonly45_photo_author_html
stair_htmlscrh  r  jr
  uvuser_rowjudge45_htmljrsecr!   top_htmltop_requestedtop_plan
cand_cells
judge_htmlsecsr  crit_top_htmllifixnotetopfpread_htmlr_  rbrrows	loop_htmlri  ic_okvrowsrX  
pair_blockprfp1_cell_p1p0_cell_p2fp0_cell_p3pv_htmlr   	crit_htmlcr	crit_rowsscene_photo_author_htmlrefreshpromr  r  r  r  r  s                                                                                                                                                                                                       @@@@@r"   r   r   %  sc   77 @ H+=>@ @D GG ; !89; ;E{H34 /0MD'45Hh34OK34OK56OK56OK12OK12OK45OK45OK{{#45 -<%6h,N,<N!529"oL01OK01OK12OK12OK9:L"9:L"67OK67OK>?L">?L"/0OK/0OK56L"56L"./OK./OK78L"78L"=>M2=>M267L"67L"45OK45OK9:K9:K:;L#:;L#/0K/0K-.K-.K-.K-.K12K12K01L#01L#01L#01L#-.K-.K56L#IH!Rb	2	# " Y'KFmOJ ,ND!+.OT!/2OT"?3d	#C(9WW      
==GLR 1L@%9ryb/N.,>O#7RYBM		-	Aryb/ 	L!\1E29"o	L(L8L")_	L .=  YB		L
  </CO	L %4HbiR	L ,.B	r?	L ',6J	r?	L ,|;  YB	L &5Iryb/	L %4HbiR	L )L8 "[S!	L )L8 "[S!!	L" ,.D3D#	L$ ,Bckc1B%	L& ,Bckc1B'	L( !L0F#+#5F)	L* ,.D3D+	L, ,.D3D-	L. ,Bckc1B/	L0 $|3?C1	L2 1a L0FX5F3	L4 %1c'5	L6 l".3w7	L8 ,&3t89	L: <'?$,?;	L< |+8D=	L> ',6J	r?A B	H %(*AC)35HJ!-57N"P'35FH!-:<S"U#/J!$#  J[[./ALE55	AWWKAkNKKFKK   !+uD9,()/ ,2T&'r;<	A VV%& 4DH:XF! 	 \BFF8R()*$024''$-@BJK 	 L[[*+%&ALE55	A ( :( (A JJ3AhK=T#ak*+, -JJq|,- .FFGSRSA=ggcl%& 	 H"1%a(L8MH;;~. ~2"":.WW * )* *
 
W-D!?uW%e,GG , z], , UG#7(} E  %

1Y< 89 :001s(<=!? \\(B/FI''$- &' **GGGH &cU + 	  Z0D!?u!*-e4X>WW .&,. .fUG+;CK=P35bT/2? @!? &.\\-%@"FH 579wwt}EGNO  ((M 6	_-BJBGG ' H	' 'E
 Ivvl+1r1xL5	*CWW 3&'k3 35bk]&(ffWo{2> ?RY( )$%gJ5D9 :..0T 2))-ao)>(?A ,.bT'27 &&,:/0624	6 %
%&	 2" E HuVVH%+007WWKAkNKKF5' *!*+G*$ ?x!!L/2349 24tB4u-= > !I"
   
  
3r7<<23456 7EEJ FE
 N& 
0	]+Bvve} %bi 0#K H.LGS!"U),MHcGU
U FF3KWW 3&'k3 3fUG ,#,-gJ5D"A#AlO45T; 46bT/2? @U vvm$YY Y Z   Z 0 180H=/I J)J2 <    
 ] \        9> I[[,-GG %
 
^% %	L k	# 	 +J!# ^L+M+  8  77 2<--/02 2 . % B$v,	*,	 	
 	OO ` `  `	`
`@ 

A`@A`V VW`VW`X ZY`XY`d ]e`de`f ]g`fg`r s`rs`t u`tu`x Gy`xy`@ ]A`@A`B ]C`BC`H  I`HI`L ]M`LM`N ]O`NO`T  U`TU`X ]Y`XY`Z ][`Z[`d ]e`de`f ]g`fg`p ^q`pq`r ^s`rs`|  }`|}`@ ]A`@A`B ]C`BC`N ^O`NO`P ^Q`PQ`\ ]]`\]`^ ]_`^_`d  e`de`h ^i`hi`j ^k`jk`r  s`rs`v ]w`vw`x ]y`xy`B ^C`BC`D ^E`DE`P _Q`PQ`R _S`RS`\ ^]`\]`^ ^_`^_`h  i`hi`l ]m`lm`n ]o`no`v  w`vw`z ]{`z{`| ]}`|}`~ ^`~`@ ^A`@A`D E`DE`F G`FG`R ]S`RS`T ]U`TU`` ]a``a`b ]c`bc`l ]m`lm`n ]o`no`x ]y`xy`z ]{`z{`D ^E`DE`F ^G`FG`P ^Q`PQ`R ^S`RS`^ ]_`^_`` ]a``a`l ^m`lm`n o`no`x ]y`xy`z ]{`z{`~ `~`@ A  `B 
HTF
Y  J  f  .    J  		d  		`  s   w$ #,w6 %Cx =B.x >x( <F6x8 5C'y =6y $w32w36xx	xx	x%$x%(	x54x58	yy	yy	y%$y%c                     t        j                         } | j                  ddg d       | j                         }t	        j
                  d      }|j                  dk(  rXt        |t	        j                               }t        |t        |             t        |       t	        j                  dddd	       y |j                  d
v rt        |      }nt	        j
                  d      }	 t        |      }t        ||       |j                  dv rt!        |       |j                  dk(  rt#        |t	        j                                |j                  dv rt%        |t	        j                                |j                  dk(  rt'        |t	        j                                |j                  dv rt)        |t	        j                                |j                  dk(  rt+        |t	        j                                |j                  dk(  rt-        |t	        j                                |j                  dk(  r!t-        |t	        j                         dd       |j                  dk(  rt/        |t	        j                                |j                  dk(  r"t/        |t	        j                         ddd       |j                  dk(  rt1        |t	        j                                |j                  dk(  rt3        |t	        j                                |j                  dk(  rt5        |t	        j                                |j                  d k(  r!t1        |t	        j                         d!d"       |j                  d#k(  r"t3        |t	        j                         d$d%d&       |j                  d'k(  r"t5        |t	        j                         d!d(d&       |j                  d)k(  rt7        |t	        j                                |j                  d*k(  rt9        |t	        j                                |j                  d+k(  rt;        |t	        j                                |j                  d,k(  rt=        |       |j                  d-k(  rt?        |       |j                  d.k(  rtA        |       |j                  d/k(  rtC        |       |j                  d0k(  rtE        |       |j                  d1k(  rtG        |       |j                  d2k(  rtI        |       |j                  d3k(  rtK        |       |j                  d4k(  rtM        |       |j                  d5k(  rtO        |       |j                  d6v rtQ        |       |j                  d7v rtS        |       |j                  d8v rtU        |       |j                  d9v rtW        |       |j                  d:k(  rtY        |       |j                  d;k(  rt[        |       |j                  d<k(  rt]        |       |j                  d=k(  rt_        |       |j                  d>k(  rta        |       |j                  d?k(  rtc        |       t	        j                  dd|j                  d	       y # t        $ r d }Y w xY w)@Nz--onlyr  ),r  r3   imager  sketchfpphoto	planphoto
plansketchplansketch_nb2srcplansketchphotoplansketchphoto_nb2srcminimalbdsketchbdsketchphotobdphotobdsketch_gptsrcbdsketchphoto_gptsrcbdphoto_gptsrc	textphototextphoto45textphoto45_gptjudge45
staircheckstairfixrevbdrevfp	revsketchrot90bdrot90fpfpflatfpflatmarkedtoptopphototopjudgetopfixtopfptopfpnb2	topfpread	topfploop	topfpedit
topfpfinaltoppairhtml)defaultchoicesr   r  stages20_numbered_bd)r'   r   done)r  r3   rN   )r  r  r  )r  r  r  )r  r  r  r  r  r   plan_sketch_nb2src)r  r  r  r  r  plansketch_photo_nb2srcT)r  r  r"  r  r  r  r  r   bd_sketch_gptsrcr  r  bdsketch_photo_gptsrcFr  bd_photo_gptsrcr  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  r  )2argparseArgumentParseradd_argument
parse_argsr2   rC   onlyr   
load_reconr   r   r   runlogrV   r   rt   r   r   r   r   r  r  r  r#  r'  r.  r5  rA  rL  rR  ru  r  r  r  r  r  r  r  r  r  r  r	  r   r%  r  r  rf  ru  r  r  )apargsr9   r?   r   s        r"   mainr    s   		 	 	"BOOHeK  L ==?D[[-.FyyI&!,,.13c*+3	',=#% 	&yyN"fokk*+c" sFyy$$#yyFalln%yy%%3'yyDsALLN#yy$$#q||~&yyKC0yyL S!,,.1yy''S!,,.&=(<	> yy%%!#q||~6yy,,!#q||~+G-F/3	5 yyJc1<<>*yyO#Q\\^4yyI#q||~.yy%%c1<<>4!3	5 yy**Q\\^)C+B-2	4 yy$$#q||~#8%6',	. yyK3/yyM!S!,,.1yy%% alln5yyICyyL yyJcyyG3yyG3yyKsyyISyyISyyH3yyN"#yy''syy''cyy%%Cyy$$3yyJsyyKyyKyyKyyL yyISHHg(9499MN}  s   'Y9 9ZZ__main__)r   plan_sketch)r  plansketch_photoF)r   	bd_sketch)r(  bdsketch_photoF)r   bd_photoF)rE  )r  )r  )r  )r  r_   )__doc__r  r  r  r  r  r  r   syspathlibr   pathinsertr  r  r  
forest_libr2   s13_blockset_v2rg   s14_blockgenr0   s15_fp_redor   s16_nb2_chainS16s18_blocks_leanrP   OUTr   r  r  r  r-   rR   rS   r4   r5   r@   rF   rI   rV   rj   rk   rq   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   r   NB2_FP_BLOCKS_NUM_LABELr   r   r   FP_PLAIN_REF_NOTEr   r   r   PHOTO_VISUAL_ONLYPHOTO_SURROUNDINGS_FREEr,  r	  r   r   PLAN_FIDELITY_NOTEr   PLAN_DETAIL_HEADr   r   r   r   r   r   r   r   r!  r  r
  r  r   r  r  r   r#  r&  r'  r.  r3  r4  r5  r?  r7  rA  rI  rJ  rL  rR  rn  ro  rl  ru  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  r  r  r  r  r  r  r$  r  r  r   r	  r  r  r  r  r  r   r%  r  r+  r-  r/  r0  r#  r4  r5  r6  r7  r  rX  r  r  r  r:  r<  rY  r  r\  rZ  rf  ru  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  __name__r   rA   r"   <module>r,     s  &     	  
  3tH~,,- .      uuzH~.$O
 		 4 4n !*1,2H+="?  (-"I. &1 #I.
  )(3'. YY    4 ! (- &1 &1 '	2
 # *,%0 		  #   F ! (- &1(.'9183982D)F !($,49+18*<*0();+ *27(;"!$=+
: A! H2	 		 <# < ~ !%,7IJ (-"I. &1 #I.
 $X.% ,*Z 99JFEG"JHCHCFJG1K''  .7 )) 	 	6 + 
: yyJGIGJFIIFADICGI'' .7$ ))   + G " II    ii !   . II    )) 	% 	  iiCGEG@HEGDF/9IIJELGKJ4IJ=!  D !"H-"H- #$56  ii 1! 1 h !g8JK %%  YY      $   99   "#L ))   yy  " )	*4   99CGGFGCJEC57IIJELGGJ4IJ=&  D< 
 yy "  
. /F$1< !II !'C!'G!' F!' H	!'
 A!' !' K!' K!' E!' I!' &!' !' H!' J!' E!'  K!!'" J#!'$ J%!'& J'!'( )!'* +!', -!'. /!'0 F1!'2 H3!'4 F5!'6 K7!'8 9!': 6;!'< J=!'> ?!'@ KA!' ! H 4I);+0"J 		 #  ( (=(< 2E'7).<  !$C!$G!$ H!$ F	!$
 H!$ (!$ !$ D!$ G!$ I!$ I!$ B!$ F!$ (!$ !$  ;!!$" J#!$$ J%!$& K'!$( )!$* +!$, -!$. F/!$0 M1!$2 H3!$4 K5!$6 K7!$8 9!$: 5;!$< J=!$> ?!$@ KA!$ ! H7  ,A:?:  $yy "*;"*E"* I"* '	"*
 "* D"* I"* ?"* "* "* H"* H"* A"* ?"* I"*  B!"*" H#"*$ %"*& '"*( G)"** C+"*, D-"*. ,/"*0 G1"*2 E3"*4 95"*6 A7"*8 $9"*: 6;"*< >="*> ?"*@ @A"*B C"* "  J, yy@#"   ))  4*     !#-AB#&.&:<=  (-&.&:<#)8"4
 %l3	
& 2-2 0 YY    * !i(x(%0BC
 9	 & 99   $6 
0 ))  ,6 ii   ))  H + 
**. 		   		  @ 

N
** yy "   % .+  $ %,6.
 &		$&* !#_=#&.HJ  (-&.H$i0#)8"4
 =	
	$ 2+2$N ii !  & ! (-!' 2%x0 (2
 
# ( yyE6 ) 
:/d& )

 )) %   D@ 
 > 		   99   +8A  (+YY    2 !*1,2H+="?  (-"I. &1 &1 &	2	 E

$ )(3+ 0F > yy "   !)$%0BCx(
 5	  !)$ (-!' 2%x0 (2
 x(  2' , ii !  <~.b ))   99   ;D ,%0 @ JZ1h&!H#7>7>7 17 1	7
 47 47 07 07 >7 >7 ,7 ,7 07 07 !"L7  !"L!7"  2#7$  2%7& &'W'7( &'W)7* H+7, H-7. J/70 J172 D374 D576  Q778  Q97: $%U;7< $%U=7> M?7@ MA7B OC7D OE7F !"LG7H !"LI7J !"LK7L !"LM7N AO7P AQ7R ?S7T ?U7V ?W7X ?Y7Z P[7\ P]7^ F_7` Fa7b Fc7d Fe7f Ag7h BN$Um7tU
p}O@ zF rA   