Ë
    Š‰ŒjR]  ã                  ó@   — d Z ddlmZ dddddœZdd„Zdd„Zdd	œdd
„Zy)uÀ  
The EVENT configuration â†’ feed meta overlay, in one place.

The competition's own presentation â€” which venue and which WORLD (photoreal vs the stylised water
plane), the boat class, the fleet's hull livery, whether there are RC vessels, the start-sequence
length â€” is `event_config` data, and the renderer reads it off the feed meta. Two producers derive
that meta: the store-backed one (`serve_v3_live.apply_event_config`, reading the config out of the
database) and the REST one (`rest_source`, reading it over `/v3/manage/events/{id}/config`), and
they must land on the SAME meta or the same race looks like two different productions depending on
where the producer happens to run.

It did. The REST path built its meta from scratch and never applied the event config at all, so a
producer run with `--follow --read-base` â€” the deployment the whole live operation is built on,
render PC or cloud â€” rendered a bare stylised sea on an event whose config asks for the photoreal
venue. Verified on the field-practice broadcast 2026-08-01: `meta.world` was absent and the scene
came up as flat water with no buildings.

`integrations` (secret refs) are NEVER copied into meta â€” they are server-side only.
é    )ÚannotationsÚstartÚfinish)Ú
start_portÚ
start_stbdÚfinish_portÚfinish_stbdc                óÄ  — t        | t        «      sydt        | j                  dd«      «      i}	 t	        dt        dt        | j                  dd«      «      «      «      |d<   t	        dt        d	t        | j                  d
d«      «      «      «      |d
<   i }dD �]v  }t        | j                  d«      t        «      r$| j                  d«      xs i j                  |«      nd}t        |t        «      sŒZt        |j                  dd«      «      j                  «       }|dvrŒˆd|i}|j                  d«      }|rt        |«      |d<   dD ]m  \  }}	|j                  |«      }
t        |
t        t        f«      sŒ.t        |
«      |	k(  sŒ=	 |
D �cg c]  }t        |«      ‘Œ }}t        d„ |D «       «      sŒi|||<   Œo 	 d|v r%t	        dt        dt        |d   «      «      «      |d<   d|v r%t	        dt        dt        |d   «      «      «      |d<   |||<   �Œy |sy||d<   |S # t        t        f$ r Y yw xY wc c}w # t        t        f$ r Y �Œw xY w# t        t        f$ r Y �ŒÆw xY w)a~  Sanitize the event's visual line-detector controls before they reach browser clients.

    Camera calibration is event data, while detector profiles are a closed renderer capability.
    Keeping that boundary here prevents an arbitrary stored document from expanding the detector's
    work area, cadence or hold time beyond the limits the on-air browser source was tested for.
    NÚenabledFg      ð?g      @Ú	sampleFpsé   r   iî  Ú	maxHoldMsi^  )r   r   ÚrolesÚdetectorÚ >   ÚredÚblueÚgreenÚyellowÚ	checkeredÚ	darklightÚ	redorangeÚ
targetRole))Úanchoré   )Úsearchr   )Ú	targetBoxr   )Ú
targetSizer   c              3  ó<   K  — | ]  }d |cxk  xr dk  nc –— Œ y­w)r   é   N© )Ú.0Úitems     ú=/srv/vr/releases/25f455cc4e75/v3/broadcast/live/event_meta.pyú	<genexpr>z,_line_camera_overlay_meta.<locals>.<genexpr>F   s   è ø€ Ò7¨$�q˜D–~ A—~�~Ñ7ùs   ‚ÚminConfidenceg      à?g\�Âõ(\ï?Ú	minPixelsé   i   )Ú
isinstanceÚdictÚboolÚgetÚmaxÚminÚfloatÚintÚ	TypeErrorÚ
ValueErrorÚstrÚlowerÚlistÚtupleÚlenÚall)ÚrawÚoutr   ÚnameÚvaluer   ÚroleÚtargetÚkeyÚlengthÚdeclaredr#   Únumss                r$   Ú_line_camera_overlay_metarC   "   se  € ô �cœ4Ô ØØ”d˜3Ÿ7™7 9¨eÓ4Ó5Ð
6€CðÜ˜s¤C¨¬U°3·7±7¸;ÈÓ3JÓ-KÓ$LÓMˆˆKÑÜ˜q¤# c¬3¨s¯w©w°{ÀCÓ/HÓ+IÓ"JÓKˆˆKÑð €EØ#ó ˆÜ6@ÀÇÁÈÓAQÔSWÔ6X�—‘˜Ó!Ò' R×,Ñ,¨TÔ2Ð^bˆÜ˜%¤Ô&ØÜ�u—y‘y ¨RÓ0Ó1×7Ñ7Ó9ˆØð )ñ )àØ˜HÐ%ˆØ—‘˜<Ó(ˆÙÜ!$ V£ˆD�Ñð/ò 		%‰KˆC�à—y‘y “~ˆHÜ˜(¤T¬5 MÕ2´s¸8³}ÈÓ7NðØ4<Ö=¨DœE $�KÐ=�DÐ=ô Ñ7°$Ô7Õ7Ø $�D˜’Ið		%ð	Ø %Ñ'Ü(+¨B´°C¼¸uÀ_Ñ?UÓ9VÓ0WÓ(X��_Ñ%Ø˜eÑ#Ü$'¨¬3¨s´C¸¸kÑ8JÓ4KÓ+LÓ$M��[Ñ!ð ˆˆd‹ð;ñ< ØØ€Cˆ�LØ€JøôI ”zÐ"ò Ùðüò( >øÜ!¤:Ð.ò Úðûô œ:Ð&ò 	Úð	úsI   °A$H ÆH6Æ	H1ÆH6Æ8AIÈH.È-H.È1H6È6I	ÉI	ÉIÉIc                óä   — |si S | xs i j                  d«      xs i j                  d«      xs i }i }|j                  «       D ]*  \  }}t        j                  |«      }|sŒ|sŒ!|› d|› �||<   Œ, |S )u�  `{"start"|"finish": slot}` for the line ends this event puts a phone on.

    The slot is built rather than looked up, and it is built from the account NAME the QR was minted
    with (`trwc2026:buoy:A`) â€” never from an owner id. The two spellings are one of this codebase's
    standing traps: every owner column in the database is a `users.id`, while a slot prefix is the
    username, and comparing one to the other matches nothing without failing.

    No owner, or an event that declares no vessels â‡’ `{}`. A club Saturday whose line runs between
    two buoys simply has no vessel cameras, which is absence rather than a camera that is off.
    ÚdevicesÚvesselsz:buoy:)r,   ÚitemsÚVESSEL_CAMERA_NAMES)ÚcfgÚownerrF   r:   r=   Úbidr;   s          r$   Úvessel_camera_slotsrL   V   s�   € ñ Øˆ	Ø’	�r�‰˜yÓ)Ò/¨R×4Ñ4°YÓ?ÒEÀ2€GØ
€CØ—]‘]“_ò .‰	ˆˆcÜ"×&Ñ& tÓ,ˆÚ’CØ ˜' ¨ uÐ-ˆC�ŠIð.ð €Jó    N)rJ   c          	     óà  — |s| S t        | «      }t        ||«      }|r||d<   |j                  d«      xs i j                  d«      xs i }t        |t         «      r<|j	                  «       D ��cg c]  \  }}|t
        v r|rt        |«      ‘Œ }}}|r||d<   |j                  d«      rt        |d   «      |d<   	 ddlm}	  |	|«      }
|
�|
|d
<   |j                  d«      xs i }|�r$t        |j                  d«      xs i «      }|j                  d«      rt        |d   «      |d<   |j                  d«      rt        |d   «      |d<   |j                  d«      rt        |d   «      |d<   dD ]Y  }t        |j                  |«      t        t        f«      sŒ)t        |j                  |«      t        «      rŒIt        ||   «      ||<   Œ[ |j                  d«      �t        |d   «      |d<   |j                  d«      rt        |d   «      |d<   |j                  d«      rt        |d   «      |d<   |j                  d«      r|d   |d<   |j                  d«      rt        |d   «      |d<   |j                  d«      rt        |d   «      |d<   |j                  d«      rt        |d   «      |d<   ddlm} |j                  d«      xs i j                  d«      xs i j                  d«      } |||¬«      \  }}|r||d<   |r||d<   ||d<   |j                  d«      rt        |d   «      |d<   |j                  d«      r|d   |d<   |j                  d«      xs i }|j                  d«      �t        |d   «      |d<   |j                  d «      �t        |d    «      |d <   |j                  d!«      �t        |d!   «      |d!<   |j                  d"«      �t        |d"   «      |d"<   |j                  d#«      rt        |d#   «      |d#<   |j                  d$«      rt        |d$   «      |d$<   t        |j                  d%«      t         «      rL|d%   j	                  «       D ��ci c]*  \  }}t        |t         «      rt        |«      t        |«      “Œ, c}}|d%<   t        |j                  d&«      t         «      rW|d&   j	                  «       D ��ci c]5  \  }}t        |«      t        |t         «      rt        |«      n
t        |«      “Œ7 c}}|d&<   t        |j                  d'«      t         «      rXi }|d'   j	                  «       D ]9  \  }}	 t        |«      }|d(z  d(z   d(z  }|d)kD  r|d(z  }|d*v sŒ,||t        |«      <   Œ; |r||d'<   t#        |j                  d+«      «      }|r||d+<   |j                  d,«      �t        |d,   «      |d,<   |j                  d-«      �|d-   |d-<   |j                  d.«      rt        |d.   «      |d.<   t        |j                  d/«      t         «      r]|d/   j	                  «       D ��ci c];  \  }}t        |t         «      r&|j                  d0«      rt        |«      t        |«      “Œ= c}}|d/<   t        |j                  d1«      t         «      r]|d1   j	                  «       D ��ci c];  \  }}t        |t         «      r&|j                  d0«      rt        |«      t        |«      “Œ= c}}|d1<   t        |j                  d2«      t         «      rU|d2   j	                  «       D ��ci c]3  \  }}t        |«      j%                  «       rt        |«      t        |«      “Œ5 c}}|d2<   |j                  d3«      }|€d)}|�t        |«      }|dkD  rt'        d4|«      |d3<   |j                  d5«      rt        |d5   «      |d6<   |j                  d«      rt        |d   «      |d<   |j                  d7«      �t        |d7   «      |d7<   |j                  d8«      rt        |d8   «      |d8<   |j                  d9«      rt        |d9   «      |d9<   |j                  d:«      d;v rt        |d:   «      |d:<   |j                  d<«      rt        |d<   «      |d<<   |j                  d=«      rt        |d=   «      |d=<   |j                  d>«      rt        |d>   «      |d><   |j                  d?«      rt        |d?   «      |d?<   |j                  d@«      rt        |d@   «      |d@<   |S c c}}w # t        t        t        f$ r d	}
Y �Œpw xY wc c}}w c c}}w # t        t        f$ r Y �Œw xY wc c}}w c c}}w c c}}w )Au  Overlay an event-configuration document onto derived feed meta and return the result.

    Applied BEFORE any per-instance broadcast config, so instance keys win:
    engine-derived defaults < event config < instance broadcast config. An empty/None config
    leaves the meta untouched (full backwards compatibility).

    `owner` is the account NAME the devices registered under, and it is needed for one thing:
    turning the event's declared vessel buoy ids into slot refs the picture can ask for clips by.
    Callers derive it from a boat ref they already hold rather than from an owner column, because
    a slot prefix is the username and every owner column is a `users.id` â€” the two spellings that
    match nothing when compared and fail silently when they do.ÚvesselCamerasrE   rF   ÚvesselRolesr;   Ú	eventNamer   )Úcourse_line_length_mNÚcourseLineMÚvenueÚtimeZoneÚdisplayTimeZoneLabel)Ú	centreLatÚ	centreLonÚcityBearingDegÚworldÚwaterSurfaceÚnavMarksÚ
speechLangÚspeechNamesÚ	speechIpa)Úvenue_place_listsÚpresentationÚcruiseÚtourCategories)Ú
categoriesÚ	landmarksÚ	tourSitesÚ	boatClassÚteamBibsÚneuralTtsOnlyÚneuralTtsFallbackÚnoDownwindSailsÚ	rcVesselsÚ
markColorsÚ
hullLiveryÚhullProfilesÚhullSubstitutionsÚcameraDisplayRotationDegByRefih  é´   )iLÿÿÿi¦ÿÿÿr   éZ   rr   ÚlineCameraOverlayÚshowJibNumbersÚsailPlanÚsailFlagByBibÚidentityStreamersÚassetÚsailIdentityStreamersÚmastheadIdentityLabelByBibÚwaitingCoursePresentationEverySé<   ÚmodeÚpresentationModeÚcrewÚsignalFlagsÚpenaltyRegimeÚobservedGeometryGuard)ÚrieÚoffÚsanctionMarkÚpartnerMarksÚeventWaterMarkÚwaitingMusicÚstartSequence)r*   rL   r,   r)   rG   rH   r3   Úevent_configrR   ÚImportErrorr1   r2   r0   r/   r+   r5   r`   rC   Ústripr-   ) ÚmetarI   rJ   r:   rF   Úvessel_rolesr=   Úbuoy_idÚdeclared_rolesrR   Ú_line_mrT   ÚvÚ_kr`   Ú_catsÚ
_landmarksÚ_tour_sitesÚpresÚhullÚprofileÚslotÚreplacementÚ	rotationsÚrefr<   ÚdegÚline_camera_overlayÚcodeÚspecÚlabelÚwaiting_course_ss                                    r$   Úoverlay_event_configr¥   l   sx	  € ñ ØˆÜ
ˆt‹*€Cô " # uÓ-€GÙØ&ˆˆOÑð —W‘W˜YÓ'Ò-¨2×2Ñ2°9Ó=ÒCÀ€LÜ�,¤Ô%Ø9E×9KÑ9KÓ9M÷ F©¨¨gØ!Ô%8Ñ8¹Wô ˜d�)ð Fˆñ FáØ!/ˆC�Ñð ‡w�wˆv„Ü˜s 6™{Ó+ˆˆKÑðÝ5Ù& sÓ+ˆð ÐØ$ˆˆMÑØ�G‰G�GÓÒ" €EÚÜ�—‘˜Ó!Ò' RÓ(ˆØ�9‰9�VÔÜ˜E &™MÓ*ˆAˆf‰IØ�9‰9�ZÔ ô
    jÑ 1Ó2ˆAˆj‰MØ�9‰9Ð+Ô,ô ),¨EÐ2HÑ,IÓ(JˆAÐ$Ñ%ð -ò 	)ˆBÜ˜%Ÿ)™) B›-¬#¬u¨Õ6¼zÈ%Ï)É)ÐTVË-ÔY]Õ?^Ü˜e B™iÓ(��"’ð	)ð �9‰9Ð%Ó&Ð2Ü"'¨Ð.>Ñ(?Ó"@ˆAÐÑØ�9‰9�WÔÜ˜U 7™^Ó,ˆAˆg‰JØ�9‰9�^Ô$ô
 !% U¨>Ñ%:Ó ;ˆAˆnÑØ�9‰9�ZÔ Ø! *Ñ-ˆAˆj‰MØ�9‰9�\Ô"ô " %¨Ñ"5Ó6ˆAˆl‰OØ�9‰9�]Ô#Ü# E¨-Ñ$8Ó9ˆAˆmÑØ�9‰9�[Ô!ä! %¨Ñ"4Ó5ˆAˆk‰Nõ 	3Ø—'‘'˜.Ó)Ò/¨R×4Ñ4°XÓ>ÒDÀ"×IÑIÐJZÓ[ˆÙ"3°EÀeÔ"LÑˆ
�KÙØ'ˆAˆk‰NÙØ(ˆAˆk‰NØˆˆG‰Ø
‡w�wˆ{ÔÜ˜s ;Ñ/Ó0ˆˆKÑØ
‡w�wˆzÔð ˜j™/ˆˆJ‰Ø�7‰7�>Ó"Ò( b€DØ‡x�x�Ó Ð,ô  $ D¨Ñ$9Ó:ˆˆOÑØ‡x�xÐ#Ó$Ð0Ü#'¨Ð-@Ñ(AÓ#BˆÐÑ Ø‡x�xÐ!Ó"Ð.Ü!% dÐ+<Ñ&=Ó!>ˆÐÑØ‡x�x�ÓÐ(Ü  [Ñ 1Ó2ˆˆKÑØ‡x�x�Ôô
 !  lÑ!3Ó4ˆˆLÑØ‡x�x�ÔÜ  \Ñ 2Ó3ˆˆLÑÜ�$—(‘(˜>Ó*¬DÔ1ð 59¸Ñ4H×4NÑ4NÓ4P÷=Ù#0 4¨Ü",¨W´dÔ";ô  # 4›y¬$¨w«-Ñ7ó =ˆˆNÑô �$—(‘(Ð.Ó/´Ô6ð
 &*Ð*=Ñ%>×%DÑ%DÓ%F÷$
á!��kô �‹I¬J°{ÄDÔ,I”t˜KÔ(ÌsÐS^ÓO_Ñ_ó$
ˆÐÑ ô �$—(‘(Ð:Ó;¼TÔBð ˆ	ØÐ>Ñ?×EÑEÓGò 		*‰JˆC�ðÜ˜%“j�ð ˜#‘I Ñ$¨Ñ+ˆCØ�SŠyØ�s‘
�ØÐ-Ò-Ø&)�	œ#˜c›(Ò#ð		*ñ Ø3<ˆCÐ/Ñ0Ü3°D·H±HÐ=PÓ4QÓRÐÙð $7ˆÐÑ Ø‡x�xÐ Ó!Ð-Ü $ TÐ*:Ñ%;Ó <ˆÐÑØ‡x�x�
ÓÐ'ð ˜zÑ*ˆˆJ‰Ø‡x�x�Ô ô  $ D¨Ñ$9Ó:ˆˆOÑÜ�$—(‘(Ð.Ó/´Ô6ð 59Ð9LÑ4M×4SÑ4SÓ4U÷$
Ù&0 d¨DÜ˜$¤Ô%¨$¯(©(°7Ô*;ô �‹I”t˜D“zÑ!ó$
ˆÐÑ ô �$—(‘(Ð2Ó3´TÔ:ð
 59Ð9PÑ4Q×4WÑ4WÓ4Y÷(
Ù&0 d¨DÜ˜$¤Ô%¨$¯(©(°7Ô*;ô �‹I”t˜D“zÑ!ó(
ˆÐ#Ñ$ô �$—(‘(Ð7Ó8¼$Ô?ð 6:Ð:VÑ5W×5]Ñ5]Ó5_÷-
Ù&1 d¨EÜ�5‹z×ÑÔ!ô �‹I”s˜5“zÑ!ó-
ˆÐ(Ñ)ð —x‘xÐ AÓBÐØÐØÐØÐ#ÜÐ/Ó0ÐØ˜aÒÜ58¸Ð=MÓ5NˆCÐ1Ñ2Ø‡x�x�ÔÜ"% d¨6¡lÓ"3ˆÐÑØ‡x�x�Ôô ˜T (™^Ó,ˆˆH‰Ø‡x�x�ÓÐ#ô ˜4 ™<Ó(ˆˆF‰Ø‡x�x�Ôô " $ }Ñ"5Ó6ˆˆMÑØ‡x�x�Ô Ü" 4¨Ñ#8Ó9ˆˆOÑØ‡x�xÐ'Ó(¨NÑ:ô (+¨4Ð0GÑ+HÓ'IˆÐ#Ñ$Ø‡x�x�Ôô # 4¨Ñ#7Ó8ˆˆNÑØ‡x�x�Ôô # 4¨Ñ#7Ó8ˆˆNÑØ‡x�xÐ Ô!ô !% TÐ*:Ñ%;Ó <ˆÐÑØ‡x�x�Ôô
 # 4¨Ñ#7Ó8ˆˆNÑØ‡x�x�Ô ô  $ D¨Ñ$9Ó:ˆˆOÑØ€JùóoFøô œ¤JÐ/ò Ø‹ðüó|=ùó$
øô œzÐ*ò Úðüó:$
ùó(
ùó-
sJ   Á.dÂ:d Ñ/d<Ó:eÕeØ2A eÚ.A e$Ü*8e*äd9ä8d9åeåe)Úreturnúdict | None)rI   r§   rJ   ú
str | Noner¦   r*   )rŽ   r*   rI   r§   rJ   r¨   r¦   r*   )Ú__doc__Ú
__future__r   rH   rC   rL   r¥   r!   rM   r$   ú<module>r«      s;   ðñõ& #ð ¨Ø¨HñÐ ó1óhð, OSö PrM   