
    l@j/                       U d Z ddlmZ ddlZddlmZmZmZmZ dZ	dZ
dEdZdEdZd	Zd
ZdZdZeeefZdZdZdZdFdZ	 	 	 	 	 	 dGdZdHdZdd	 	 	 	 	 dIdZdZdZdZeeefZdZdZ eeeh      Z  eddh      Z!dZ"dddddd d!id d"id"eegd#d d"id$g d$d%d&dddd d!id d"id d"id'g d'd%d&d"d(d)dd d"id&d*g d*d%Z#d+e$d,<   dJd-Z%ed.	 	 	 	 	 	 	 dKd/Z&d0Z'd1Z(d2Z)d3Z*d4Z+d5Z,d6Z-d7Z.dddddd d!id d"id"e+e,e-gd#d8g d8d%d&dddd d!id d"id d"id d!id9g d9d%d&dddd d!id d"id d"id:g d:d%d&dddd d!id d"id;d<d=gd%d&d"d(d)d>g d>d%Z/d+e$d?<   dZ0dEd@Z1	 	 	 	 	 	 dLdAZ2	 	 	 	 	 	 dMdBZ3de)dC	 	 	 	 	 	 	 	 	 dNdDZ4y)Ou  W21B-w5 STEP5-B — simplified (CV-readable) floor-plan prompt builder.

Builds a GENERIC, deterministic simplified floor-plan ``t2i_prompt`` from a
floor plan's structured ``numbered_elements`` (the ``floor_plan_prompt`` v6/v7
output). The simplified FP is rendered as an **I2I-reference sidecar** for
``background_render`` — it is NOT the projection-card / edge-judge substrate
(the detailed FP stays that), so the W21B-w5 partition SOT is never disturbed
(STEP5-B boundary lock, Codex + Claude consensus).

Why a simpler FP: the production detailed FP draws every base element (furniture,
decor, dense small numbers, colour zones) which the image model (I2I) struggles
to read — rooms bleed into each other (a bathroom's fixtures float in the open
living area). A thick-walled, enclosed, fixture-only partition diagram lets the
renderer read independent rooms. The simplified FP carries SPATIAL ENCLOSURE
(walls / rooms / openings / essential fixtures); the per-shot CONTENT is supplied
by the zone-respecting background prompt (STEP6-C), so room-defining decorative
furniture is intentionally dropped here.

Absolute-rule compliance:
  * GENERIC — no scenario tokens / room names / proper nouns in this module. The
    only per-FP content is the runtime ``label`` / ``position_hint`` strings,
    carried through verbatim as opaque DATA (never matched on / pattern-parsed).
  * Element selection is by the closed ``base_layer_decision`` enum (the v6/v7
    contract), NOT by any text/substring inspection of labels.
    )annotationsN)AnyDictListOptional1u=  Redraw this detailed floor plan as a SPARSE black-and-white architectural line-art PARTITION DIAGRAM for machine reading. PRESERVE EXACTLY, do not reinterpret: every wall position and room shape, every room location, all door and window openings, and every numbered marker with its EXACT number and position. Do NOT create, duplicate, move, merge, split, add, or renumber any wall, door, or numbered marker — exactly one circle per existing marker number, unchanged. RESTYLE aggressively: draw ALL walls as VERY THICK solid black lines so each room reads as a strongly enclosed cell; pure WHITE background; remove ALL color fills, tints, shading, gradients, and textures; remove EVERY text label, room name, and zone name. Redraw every furniture or fixture as a SINGLE minimal flat primitive icon only (a plain rectangle for a desk/bed/table, a minimal standard symbol for a sink/toilet) — NO interior detail, NO chairs, monitors, copier parts, pillows, cushions, drawers, or decoration. Make the numbered circles large and clearly readable. No 3D, perspective, shadow, or texture.c                     t         S )u6  Return the GENERIC deterministic restyle-edit instruction (v0 production).

    Pure and parameter-free — the per-fp content lives in the detailed FP
    reference image, never in this prompt (no scenario tokens, absolute-rule
    compliant). The step pairs this with ``images.edit(image=detailed_fp)``.
    )RESTYLE_EDIT_PROMPT     b/Users/manta/Documents/Projects/TheRoad-I1/backend/app/modules/pipeline/floor_plan_light_prompt.pybuild_restyle_edit_promptr   D   s
     r   c                     t        j                  t        dz   t        z   j	                  d            j                         dd S )zCStable short hash of the restyle prompt (provenance + cache lever).
utf-8N   )hashlibsha256RESTYLE_PROMPT_VERSIONr
   encode	hexdigestr   r   r   restyle_prompt_hashr   N   s<    >>	$	&)<	<DDWMik#2 r   base_structural_unitbase_openingbase_persistent_fixturebase_persistent_furniturea  Create a square flat top-down architectural FLOOR-PLAN PARTITION DIAGRAM. This is a clean CV-readable schematic for machine reading, NOT a decorated or artistic plan.

WALLS AND ROOMS (most important): draw THICK solid black outer walls and THICK solid black interior partition walls. Each distinct room/area is a fully ENCLOSED cell bounded by walls on all sides, connected to its neighbours ONLY through clearly drawn door openings. Keep wall lines clean and straight. Do NOT merge separate rooms into one open area.a  Style: THICK black walls, thin single-weight black outlines for openings and fixtures, a pure WHITE background, NO colour fill, no pastel shading, no texture, no gradient, no 3D, no perspective, no isometric, no shadow. Do NOT write any text labels, room names, or legend inside the image; do NOT draw camera icons, field-of-view cones, or arrows except one small north arrow in a corner.zDo NOT draw decorative furniture or clutter (sofas, dining tables, chairs, TVs, lamps, wardrobes, framed pictures, bags, rugs, plants). Do NOT draw any story-state cues (blood, bodies, footprints, herbs, cups, coloured circles).c                J    t        | t              rt        | t              s| S d S N)
isinstanceintbool)ns    r   _intr#      s    1c":a+>1HDHr   c           
        |D ci c]  }|g  }}t        | t              s|S | D ]  }t        |t              s|j                  d      }||vr*t	        |j                  d            }|G||   j                  |t        |j                  d      t              r|j                  d      ndt        |j                  d      t              r|j                  d      ndd        |D ]  }||   j                  d         |S c c}w )	zGroup numbered_elements by base_layer_decision (included layers only).

    Reads the closed enum + integer ``number`` + passthrough ``label`` /
    ``position_hint`` only. No text matching.base_layer_decisionnumberlabel position_hint)r&   r'   r)   c                    | d   S Nr&   r   )es    r   <lambda>z!_group_elements.<locals>.<lambda>   s    Qx[r   )key)r   listdictgetr#   appendstrsort)numbered_elementsincluded_layerskgroupsellayernums          r   _group_elementsr<      s    ?N.Noq"uoF.N'."d#,-'266(#$;u(2266'?C(HRVVG_b bff_5s; 'AC
 	  " q	01 M- /Os   
Dc                    g }| D ]6  }|d   rd|d    nd}|d   xs d}|j                  d|d    d| |        8 d	j                  |      S )
Nr)   u    — r(   r'   z(unlabelled)z  r&   z: r   )r2   join)itemsoutitloclbls        r   _render_linesrD      sk    
C/1//Bb)*+k+^

R8~RuSE23  99S>r   F)include_furniturec                   t        t              }|r|j                  t               t	        | t        |            }t        g}|j                  t              xs g }|r|j                  dt        |      z          |j                  t              xs g }|r|j                  dt        |      z          |j                  t              xs g }|r|j                  dt        |      z          |j                  t              xs g }|r|j                  dt        |      z          |j                  t               |j                  d       |j                  t               dj                  |      S )uc  Assemble the GENERIC simplified-FP ``t2i_prompt`` from numbered_elements.

    ``include_furniture`` (default False) keeps the v0 boundary: spatial
    enclosure + essential fixtures only. Set True only for a canary comparison.
    Deterministic and pure — same input → same prompt (image generation is the
    separate, visually-validated step).
    uc   Rooms / areas — draw each as a separate fully enclosed cell, with a LARGE clear numbered circle:
u   Openings — a door is a gap in the wall with a simple thin swing arc; a window is two short parallel lines in a wall. Draw each on the wall of the room it belongs to, with its numbered circle:
u   Essential fixtures — draw each as the simplest possible plan symbol, strictly INSIDE its own room (never floating in another room or the open area), with its numbered circle:
um   Room-defining items — draw each as a single basic rectangle inside its own room, with its numbered circle:
u   Numbered circles must be LARGE, sparse, and clearly readable — one per listed element above, placed inside the room/on the element it marks.z

)r/   _DEFAULT_INCLUDED_LAYERSr2   LAYER_PERSISTENT_FURNITUREr<   tuple	_PREAMBLEr1   LAYER_STRUCTURAL_UNITrD   LAYER_OPENINGLAYER_PERSISTENT_FIXTURE_EXCLUSIONS_STYLE_RULESr>   )	r5   rE   includedr8   partsroomsopeningsfixtures	furnitures	            r   build_simple_fp_promptrV      sU    ,-H23.h@F!{EJJ,-3E-/<U/CD	

 zz-(.BHN H%&	
 zz239rHB H%&	
 

56<"I8:G	:RS	

 
LL	LL	P 
LL;;ur   structural_skeletonessential_fixturemetadata_only   r   state_overlay_plot_cuestate_overlay_transient_objectu+  You turn a detailed apartment floor plan into a CLEAN, CV-READABLE top-down PARTITION DIAGRAM prompt for an image model. The detailed plan is too cluttered for the model to read; your job is to SELECT only what defines the space and write a sparse, room-aware image prompt.

You are given the floor plan's numbered_elements (number, label, category, position_hint, base_layer_decision). For EACH element assign a render_role:
- structural_skeleton: rooms/areas (base_structural_unit) and openings (base_opening). ALWAYS keep ALL of these — they are the spatial skeleton.
- essential_fixture: a fixture/furniture item that DEFINES a room's identity or anchors a camera (e.g. a toilet/sink for a bathroom, a bed for a bedroom, a counter/cooktop for a kitchen, a sofa/TV for a living room). Keep these, drawn as the simplest plan symbol.
- metadata_only: decorative, minor, or duplicate clutter (rugs, plants, framed pictures, small props) AND every story-state overlay (state_overlay_*). DROP these — do not draw them.

Selection must be SPARSE: aim for about 8-12 selected markers total; never exceed what the rooms genuinely need. Keeping every fixture is the mistake to avoid.

Then write room_schematic_prompt — ONE image-generation prompt that:
- draws THICK solid black outer + interior partition walls; each room a fully ENCLOSED cell connected to neighbours ONLY through clearly drawn door openings; explicitly says do NOT merge separate rooms into one open area;
- places each selected essential fixture as the simplest plan symbol STRICTLY inside its own room (never floating in another room);
- marks LARGE clear numbered circles ONLY for the selected markers (use their original numbers), big and sparse;
- pure WHITE background, NO colour/shading/texture/gradient/3D/perspective/shadow, and NO written text labels/room names/legend inside the image.
Describe rooms by their position_hint relationships (which is north/east/etc., what connects to what). Use the given labels only to understand what each element is; do not write them into the image.

Output strict JSON only.objectarraytypeintegerstring)r_   enum)r&   r'   render_rolereason)r_   additionalProperties
propertiesrequired)r_   r?   )r&   r'   rd   <   )r_   	minLength)selected_markersdropped_markersroom_schematic_promptsafety_contractDict[str, Any]LIGHT_FP_SCHEMAc           
        ddl }g }t        | t              r| D ]  }t        |t              st	        |j                  d            }|1|j                  ||j                  d      |j                  d      |j                  d      |j                  d      d        t        |j                  d	|id
      t        dS )u-  Assemble the strict {system, user, schema} bundle for the LLM generator.

    The user payload is the numbered_elements carried through verbatim (number /
    label / category / position_hint / base_layer_decision) — no scenario tokens
    in this module, only the runtime data the model classifies.r   Nr&   r'   categoryr)   r%   )r&   r'   rq   r)   r%   r5   Fensure_asciisystemuserschema)
jsonr   r/   r0   r#   r1   r2   LIGHT_FP_SYSTEMdumpsro   )r5   _jsonelementsr9   r;   s        r    build_light_fp_llm_prompt_bundler}   ]  s     H#T*#Bb$'rvvh'(C{OOFF:.!#!8')vv.C'D  $ "0(;%P! r   )select_soft_targetc           
     F   g }t        | t              s	ddg g dgdS i t        |t              rI|D ]D  }t        |t              st        |j	                  d            }|1|j	                  d      |<   F | j	                  d      xs g D cg c],  }t        |t              rt        |j	                  d            . }}|D ch c]  }||	 }}j                         D 	ch c]  \  }}	|	t        v s| }
}}	t        |
|z
        }|r|j                  d|        t        fd	|D              }|r|j                  d
|        t        |      |kD  r!|j                  dt        |       d| d       | j	                  d      }t        |t              r|nd}t        |      dk  r|j                  d       | xr | xr t        |      dk\  }||t        |      t        d d | j	                  d      xs g D        D              |dS c c}w c c}w c c}	}w )u  Validate the LLM output against the deterministic STRUCTURAL guards.

    ``ok`` reflects STRUCTURAL INTEGRITY ONLY (Codex lock + Claude canary
    correction): every ``base_structural_unit`` / ``base_opening`` element MUST
    be selected (the LLM may not drop the spatial skeleton); no ``state_overlay_*``
    element may be selected; the prompt must be present. The selection COUNT is
    advisory only — it does NOT flip ``ok``, because a too-tight count cap would
    fall back to the cluttered deterministic builder (the very failure mode being
    fixed). Sparsity is driven by the prompt; the count is surfaced as a
    diagnostic so an over-selection is visible without forcing a worse fallback.
    Returns ``{ok, room_schematic_prompt, selected_numbers, dropped_numbers,
    diagnostics}``. ``ok`` false ⇒ the STEP-level caller (floor_plan_light_sidecar)
    skips the light render for that fp and the background consumer keeps the
    DETAILED floor_plan_render PNG (per-fp detailed fallback) — only when the
    skeleton is broken, never just for being verbose. (The deterministic
    ``build_simple_fp_prompt`` remains available as a pure-prompt fallback but the
    wired step uses the detailed-FP fallback path.)Fr(   non-dict LLM output)okrl   selected_numbersdropped_numbersdiagnosticsr&   r%   rj   z'skeleton elements dropped (forbidden): c              3  R   K   | ]  }j                  |      t        v s|   y wr   r1   _ALWAYS_DROP_LAYERS.0r"   layer_by_nums     r   	<genexpr>z+validate_light_fp_output.<locals>.<genexpr>  s)      P aL$4$4Q$7;N$N=s   ''z-state-overlay elements selected (forbidden): z	selected z > soft target uI    (advisory — verbose but rendered; tighten the prompt if visually busy)rl   rh   )room_schematic_prompt too short / missingc              3  $   K   | ]  }|| 
 y wr   r   )r   r"   s     r   r   z+validate_light_fp_output.<locals>.<genexpr>  s#      "
!   s   c              3  p   K   | ].  }t        |t              rt        |j                  d              0 yw)r&   N)r   r0   r#   r1   )r   ms     r   r   z+validate_light_fp_output.<locals>.<genexpr>  s/      0P!a& QUU8_%0Ps   46rk   )r   r0   r/   r#   r1   r?   _MUST_KEEP_LAYERSsortedr2   lenr3   )rawr5   r~   diagsr9   r"   r   selectedselected_numsr:   	must_keepdropped_skeletonoverlay_selectedpromptr   r   s                  @r   validate_light_fp_outputr   {  sd   * Ec4 b$&2 568 	8
 $&L#T*#B"d#)*=&(ff-B&CLO	 $ '',-333Aa 	QUU8_3  
 !):1AMQM:#/#5#5#7V#7xq%5DU;U#7IVi-7856F5GH	J  P P PDEUDVWX
=..M*+?;M:N OW X	Y WW,-F!&#.VBF
6{R@A 		L&6"6	L3v;";LB!'"=1! "
038I0J0Pb0P"
 
  ?
 ;Vs   1HHH'H8H   
         roomdoorwindowu4  You convert a detailed apartment floor plan into a SPARSE, CV-readable top-down PARTITION DIAGRAM prompt for a TEXT-TO-IMAGE model (NO reference image is given). The detailed plan has far too many numbered markers for the model to render cleanly; a SHORT prompt with FEW markers renders far better.

You are given the floor plan's numbered_elements (number, label, category, position_hint, base_layer_decision) and, for each, a camera_use_count: how many shot cameras actually FRAME that element. This is a frequency / importance signal — a HIGH count means cameras show it often (e.g. a TV, or a window/curtain repeatedly framed) and it MUST NOT be silently dropped.

Classify EVERY numbered element into exactly ONE bucket:
- geometry_skeleton: every room/area (base_structural_unit) and every opening (base_opening = door/window). These DEFINE the building shape. They are drawn, but WITHOUT numbered circles — the unnumbered structural shell. Set kind to room, door, or window.
- essential_numbered_markers: the 8-10 fixtures/furniture that DEFINE a room's identity or are framed by cameras (high camera_use_count) — e.g. a toilet/sink for a bathroom, a bed for a bedroom, a counter/cooktop for a kitchen, a sofa/TV for a living room. Keep each element's ORIGINAL number; each appears EXACTLY ONCE; these get the LARGE numbered circles. Echo each element's camera_use_count.
- high_frequency_candidates: any element with a HIGH camera_use_count that you nonetheless DROP. You MUST give a drop_reason — dropping something cameras frame is risky, so justify it.
- metadata_only: decorative / minor / duplicate clutter (rugs, plants, framed pictures, small props) AND every story-state overlay (state_overlay_*). Not drawn.

Aim for 8-10 essential_numbered_markers — NEVER the whole inventory; keeping every fixture is the mistake to avoid; but a high camera_use_count element should almost always be kept.

Then write room_schematic_prompt — ONE SHORT image-generation prompt that:
- draws THICK solid black outer + interior partition walls; each room a fully ENCLOSED cell connected to neighbours ONLY through clearly drawn door openings (a door = a gap in the wall with a thin swing arc; a window = two short parallel lines in the wall); explicitly says do NOT merge separate rooms into one open area;
- MARKER PLACEMENT (critical): EVERY numbered circle sits INSIDE the building outline; a door/window marker sits ON its wall, touching from the inside, NEVER floating outside the building; a fixture marker sits INSIDE its own room, never floating in another room or the open area; EXACTLY ONE circle per number — if an element represents SEVERAL identical items (e.g. multiple chairs, desks, lockers, or cabinets), draw the symbols but place the numbered circle on only ONE representative item and do NOT repeat that number on the others;
- draws each essential fixture as the simplest flat plan symbol strictly inside its own room;
- uses LARGE clear numbered circles ONLY for the essential markers (their ORIGINAL numbers), big and sparse;
- pure WHITE background, NO colour/shading/texture/gradient/3D/perspective/shadow; and the image must contain ZERO letters or words — NO room names, NO text labels, NO legend, NO captions anywhere (e.g. do not write 'kitchen', 'bedroom', 'entrance'); the ONLY characters allowed are the digits inside the numbered marker circles.
Keep it SHORT — describe rooms by their position_hint relationships (which is north/east/etc., what connects to what). Use the given labels only to understand what each element is; do NOT write them into the image.

Output strict JSON only.)r&   r'   kind)r&   r'   rd   camera_use_count)r&   r'   drop_reason)r&   r'   r&   r'   )geometry_skeletonessential_numbered_markershigh_frequency_candidatesrY   rl   FREQ_SELECT_SCHEMAc                     ddl } t        dz   t        z   dz   | j                  t        d      z   }t        j                  |j                  d            j                         dd S )zStable short hash of the NB2 freq-aware selection system prompt + schema.

    Provenance + cache-invalidation lever for the step config_hash. Pure.r   Nr   T)	sort_keysr   r   )	rx   FREQ_SELECT_PROMPT_VERSIONNB2_FREQ_SELECT_SYSTEMrz   r   r   r   r   r   )r{   payloads     r   freq_select_prompt_hashr   t  sa      	#T),BBTI
++(D+
9	:  >>'..12<<>sCCr   c                   i }t        | t              rG| D ]B  }t        |t              st        |j	                  d            }|1|j                  |d       D t        |t              r|D ]  }t        |t              s|j	                  d      }t        |t              s6t               }|D ]=  }t        |      }|||v r|j                  |       |j	                  |d      dz   ||<   ?  |S )u
  Aggregate the per-element camera-framing frequency (importance signal).

    ``camera_use_count[n]`` = the number of ``camera_recommendations`` entries
    whose ``use_numbered_elements`` contains ``n``. This is a pure INTEGER signal
    (how many shot cameras frame the element) — never a label/text inspection
    (absolute-rule compliant). Every integer-numbered element is present (0 when
    no camera frames it). A number repeated inside one camera's
    ``use_numbered_elements`` counts once for that camera.
    r&   r   use_numbered_elements   )r   r/   r0   r#   r1   
setdefaultsetadd)	r5   camera_recommendationscountsr9   r"   camusedseen_in_camitems	            r   compute_camera_use_countsr     s      F#T*#B"d#)*=%%a+	 $
 ($/)Cc4(7723DdD)%KJ9[ 0""JJq!,q0q	  * Mr   c                   ddl }t        |t              r|ni }g }t        | t              r| D ]  }t        |t              st	        |j                  d            }|1|j                  ||j                  d      |j                  d      |j                  d      |j                  d      t        |j                  |d            d        t        |j                  d	|id
      t        dS )u@  Assemble the strict {system, user, schema} bundle for the NB2 selector.

    The user payload is the numbered_elements carried through verbatim, each
    annotated with its integer ``camera_use_count`` (the frequency signal). No
    scenario tokens live in this module — only the runtime data the model
    classifies.r   Nr&   r'   rq   r)   r%   )r&   r'   rq   r)   r%   r   r5   Frr   rt   )rx   r   r0   r/   r#   r1   r2   r    r   rz   r   )r5   camera_use_countsr{   r   r|   r9   r;   s          r   !build_freq_aware_selection_bundler     s     ",->"E2FH#T*#Bb$'rvvh'(C{OOFF:.!#!8')vv.C'D$'

3(:$;  $ )0(;%P$ r   )r   select_hard_capc                    g }t         t              s
ddg g g dgdS i t        |t              rI|D ]D  }t        |t              st        |j	                  d            }|1|j	                  d      |<   F t        |t              r|ni }d fd} |d      }	t         |d	            }
t        |	      }t         |d
            t        fd|D              }|r|j                  d|        |D ch c]	  }|v s| }}t        |      }t        |	      t        |      k7  rBt        |	D ch c]  }|	j                  |      dkD  s| c}      }|j                  d|        |
D ch c]  }j	                  |      t        v r| }}t        |
|z
        }|r|j                  d|        j                         D ch c]  \  }}|t        k(  s| }}}t        ||z
  |z
        }|r|j                  d|        t        fd||
z  D              }|r|j                  d|        t        |      |kD  r"|j                  dt        |       d| d       n7t        |      t        k  r%|j                  dt        |       dt         d       ||z  t        fd|j                         D              }|r|j                  d|         j	                  d      }t        |t              r|nd}t        |      dk  r|j                  d       | xr | xr t        |      dk\  }|||t        |      ||dS c c}w c c}w c c}w c c}}w )u  Validate the NB2 freq-aware selection against the STRUCTURAL guards.

    ``ok`` reflects STRUCTURAL INTEGRITY ONLY (Codex lock #1 — do not over-gate):
    every room (``base_structural_unit``) MUST be drawn (in the geometry skeleton
    or as an essential marker); no ``state_overlay_*`` element may be an essential
    numbered marker; the prompt must be present. The selection COUNT and the
    high-frequency protection are ADVISORY diagnostics — they never flip ``ok``,
    because a too-tight gate would fall back to the cluttered detailed FP (the very
    failure mode being fixed). Returns ``{ok, room_schematic_prompt,
    essential_numbers, skeleton_numbers, unjustified_high_freq, diagnostics}``.
    Fr(   r   )r   rl   essential_numbersskeleton_numbersunjustified_high_freqr   r&   r%   c                    g }j                  |       xs g D ]A  }t        |t              st        |j                  d            }|1|j	                  |       C |S r+   )r1   r   r0   r#   r2   )r.   r@   r   r"   r   s       r   _numsz,validate_freq_aware_selection.<locals>._nums  sU    ''#,$"$A!T"x)=JJqM	 %
 
r   r   r   r   c              3  ,   K   | ]  }|vs|  y wr   r   r   s     r   r   z0validate_freq_aware_selection.<locals>.<genexpr>  s     Q-Q1L;Pq-s   	z+essential markers not in source (dropped): r   z(duplicate essential markers (advisory): zBgeometry_skeleton has non-structural / unknown numbers (ignored): zroom(s) not drawn (forbidden): c              3  P   K   | ]  }j                  |      t        v r|  y wr   r   r   s     r   r   z0validate_freq_aware_selection.<locals>.<genexpr>  s-      70aA"55 	
0s   #&z-state-overlay selected as drawn (forbidden): z
essential z > hard cap u(    (advisory — busy, tighten the prompt)z < target min u!    (advisory — may be too sparse)c              3  j   K   | ]*  \  }}t        |t              r|t        k\  r|vr|vr| , y wr   )r   r    NB2_HIGH_FREQ_MIN_CAMERAS)r   r"   cdrawnhf_justifieds      r   r   z0validate_freq_aware_selection.<locals>.<genexpr>,  s<      #$daa!'@"@UNq4 	
ns   03zBhigh-frequency elements dropped without justification (advisory): rl   rh   r   )r.   r3   returnz	List[int])r   r0   r/   r#   r1   r   r   r2   r   countr   r?   rK   NB2_SELECT_TARGET_MINr3   )r   r5   r   r   r   r9   r"   r   r   essential_rawskeleton_setessential_setunknown_essentialessential_valid_setessential_validdupsskeleton_validskeleton_invalidlrR   rooms_missingoverlay_drawnr   r   r   r   r   r   s   `                        @@@r   validate_freq_aware_selectionr     s   $ Ec4 b%'R)+=R<SU 	U $&L#T*#B"d#)*=&(ff-B&CLO	 $
 #-->"E2F 67Mu012L&Mu89:LQ-QQ9:K9LM	O&3ImqL7H1mI01O
=S//-N-Q=3F3Fq3IA3Mq-NO?vFG  aA"33 	
<   l^;<P "	#
 (--/N/41a18M3MQ/EN5>14GGHM6}oFG  7!L07 7M ;M?K	M ?o-_-.l?:K L6 6	7 
_	 5	5_-.n=R<S T/ /	0  .0E" #lln# 
 P$%'	( WW,-F!&#.VBF
6{R@A

GM 1
Gc&kR6GB!',">2!6 C J O Os*   9	M
M
4MM1 M
MM)r   r3   )r"   r   r   zOptional[int])r5   r   r6   rI   r   zDict[str, List[Dict[str, Any]]])r?   zList[Dict[str, Any]]r   r3   )r5   r   rE   r!   r   r3   )r5   r   r   rn   )r   r   r5   r   r~   r    r   rn   )r5   r   r   r   r   zDict[int, int])r5   r   r   r   r   rn   )
r   r   r5   r   r   r   r   r    r   rn   )5__doc__
__future__r   r   typingr   r   r   r   r   r
   r   r   rK   rL   rM   rH   rG   rJ   rO   rN   r#   r<   rD   rV   RENDER_ROLE_SKELETONRENDER_ROLE_ESSENTIALRENDER_ROLE_METADATALIGHT_FP_RENDER_ROLESLIGHT_FP_SELECT_TARGETLIGHT_FP_SELECT_HARD_CAP	frozensetr   r   ry   ro   __annotations__r}   r   r   NB2_SELECT_TARGET_MAXNB2_SELECT_HARD_CAPr   NB2_GEOMETRY_KIND_ROOMNB2_GEOMETRY_KIND_DOORNB2_GEOMETRY_KIND_WINDOWr   r   r   r   r   r   r   r   r   r   <module>r      s  2 #  , ,"   ( / 4 8   D 
 S I-2$@ $99 9 		9\ - + &      4mDE >!  
 H !  (-%y1$h/,4,.C?E $F%x0 I
   (-%y1$h/%x0
 :	
 +3!D$+vx6HI=@G'# 'T@ 7NN$'NN NT    
    # 7 x !  (-%y1$h/%-.0F082 3 8
   (-%y1$h/%x0)/(;	 N
'
  (-%y1$h/$*H#5
 ?	&
  (-%y1$h/ &w/
 +3!Do8ry@& N @H ! 
D!!47!!H  /2  N ".{	{ { 	{
 { {r   