Ë
    #K­j=L  ã                  óà  — d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	 ddl
mZ ddlmZ ddlmZmZ d	d
lmZ d	dlmZmZmZ d	dlmZmZ d	dlmZmZmZmZ d	dlm Z m!Z!m"Z"  edg¬«      Z# G d„ de«      Z$ G d„ de«      Z% G d„ de«      Z&d7d„Z'dZ(d8d„Z)d9d„Z*d:d„Z+d;d„Z,d<d„Z-d=d„Z.d>d„Z/e#ja                  d «       ee«       ee«      fd?d!„«       Z1e#je                  d «      dd" ee«       ee«      fd@d#„«       Z3e#je                  d$«       ee«       ee«      fdAd%„«       Z4e#jk                  d$«       ee«       ee«      fdBd&„«       Z6e#jo                  d$«       ee«       ee«      fdAd'„«       Z8e#ja                  d(«       ee«       ee«      fdCd)„«       Z9 e: e;ejx                  g d*¢d+¬,«      «      Z=d-d.d/d0œZ>dDd1„Z?dEd2„Z@dFd3„ZAe#je                  d4«      d5 ee«       ee«      fdGd6„«       ZBy)Ha  Wizard runs: save drafts, finalize with the forecaster's own ratings, export.

The server always recomputes the engine output from the inputs (never trusting
the browser's numbers) and records which config version and engine version
produced the suggestion.
é    )ÚannotationsN)Údate)Ú	APIRouterÚDependsÚHTTPException)ÚPlainTextResponse)Ú
Connection)Ú	BaseModelÚFieldé   )Úengine)ÚUserÚcurrent_userÚrequire_center)Úactive_configÚconfig_by_id)ÚJsonbÚfetchallÚfetchoneÚget_conn)ÚAFP_PROBLEM_NAMESÚAFP_TO_DRUPAL_PROBLEMÚLIKELIHOOD_NAMESÚruns)Útagsc                  ó€   — e Zd ZU ded<   dZded<   ded<   ded	<   i Zd
ed<   dZded<   dZded<   dZded<   dZ	ded<   y)ÚRunInÚintÚ	center_idNú
int | NoneÚzone_idr   Ú
valid_dateÚdictÚinputszdict[str, str]Újustificationsú
str | NoneÚnotesÚbottom_lineúdict | NoneÚclient_computedúdict[str, int | None] | NoneÚdraft_ratings)
Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r!   r%   r'   r(   r*   r,   © ó    ú-/var/www/avy-guidance/api/app/routers/runs.pyr   r      sO   … ØƒNØ€GˆZÓØÓØƒLØ%'€N�NÓ'Ø€Eˆ:ÓØ"€K�Ó"Ø#'€O�[Ó'Ø26€MÐ/Ô6r2   r   c                  ó~   — e Zd ZU dZded<   dZded<   dZded<   dZded	<   dZd
ed<   dZ	d
ed<   dZ
ded<   dZded<   y)Ú	RunUpdateNr    r!   zdate | Noner"   r)   r$   zdict[str, str] | Noner%   r&   r'   r(   r*   r+   r,   )r-   r.   r/   r!   r0   r"   r$   r%   r'   r(   r*   r,   r1   r2   r3   r5   r5   '   sT   … Ø€GˆZÓØ"€J�Ó"Ø€FˆKÓØ,0€NÐ)Ó0Ø€Eˆ:ÓØ"€K�Ó"Ø#'€O�[Ó'Ø26€MÐ/Ô6r2   r5   c                  ó¤   — e Zd ZU  edd¬«      Zded<    edd¬«      Zded<    edd¬«      Zded<    eddd¬	«      Zd
ed<   dZ	ded<   dZ
ded<   y)Ú
FinalizeInr   é   )ÚgeÚler   ÚupperÚmiddleÚlowerN)Údefaultr9   r:   r    Úoverallr&   r(   r'   )r-   r.   r/   r   r;   r0   r<   r=   r?   r(   r'   r1   r2   r3   r7   r7   2   s\   … Ù˜! Ô"€Eˆ3Ó"Ù˜1 Ô#€FˆCÓ#Ù˜! Ô"€Eˆ3Ó"Ù¨°°qÔ9€GˆZÓ9Ø"€K�Ó"Ø€Eˆ:Ôr2   r7   c                óŽ  — | xs i } i }dD ]g  }| j                  |«      }|dv rd ||<   Œ	 t        |«      }t        j                  |«      s||cxk  r|k  sn t	        d|› d|› d|› d|› �«      ‚|||<   Œi |d   �!|d	   �|d   |d	   kD  r|d	   |d   c|d<   |d	<   |S # t        t        f$ r}t	        d|› d|› d�«      |‚d }~ww xY w)
N)ÚminÚmax)NÚ é¦  ú.z must be a numberz must be between z and rA   rB   )ÚgetÚfloatÚ	TypeErrorÚ
ValueErrorr   ÚmathÚisnan)	ÚvalueÚloÚhiÚlabelÚoutÚkÚvÚfÚes	            r3   Ú_rangerU   >   s  € ØŠK�R€EØ
€CØò ˆØ�I‰I�a‹LˆØ�
‰?ØˆC�‰FØð	MÜ�a“ˆAô �:‰:�aŒ=  a¤¨2¤Ü ¨ w¨a°¨sÐ2CÀBÀ4ÀuÈRÈDÐ%QÓRÐRØˆˆAŠðð ˆ5�zÐ # e¡*Ð"8¸SÀ¹ZÈ#ÈeÉ*Ò=TØ!$ U¡¨S°©ZÐˆˆE‰
�C˜‘JØ€Jøô œ:Ð&ò 	MÜ ¨ w¨a°¨sÐ2CÐ%DÓEÈ1ÐLûð	Mús   ªBÂCÂ,B?Â?Ciˆ  c                óª   — | €yt        | t        «      st        dd|dz   › d�«      ‚t        | «      t        kD  rt        dd|dz   › dt        › d�«      ‚| S )NrC   rD   úProblem é   z: discussion must be textz: discussion is longer than z characters)Ú
isinstanceÚstrr   ÚlenÚMAX_DISCUSSION)rL   Úis     r3   Ú_discussionr^   U   sc   € Ø€}ØÜ�eœSÔ!Ü˜C 8¨A°©E¨7Ð2KÐ!LÓMÐMÜ
ˆ5ƒz”NÒ"Ü˜C 8¨A°©E¨7Ð2NÌ~ÐN^Ð^iÐ!jÓkÐkØ€Lr2   c                ó¬  — |d   D �ch c]  }|d   ’Œ	 }}|d   D �ch c]  }|d   ’Œ	 }}t        d„ |d   D «       «      }| j                  d«      xs g D �cg c]	  }||v sŒ|‘Œ }}| j                  d«      xs g }t        |«      |j                  dd«      kD  r t        d	d
|j                  dd«      › d�«      ‚t	        «       }	g }
t        |«      D �]Â  \  }}	 t        |j                  d«      «      }||vrt        d	d|dz   › d|› �«      ‚||	v rt        d	d|dz   › d�«      ‚|	j                  |«       g }|j                  d«      xs g D ]Q  }t        j                  |«      }|st        d	d|dz   › d|›�«      ‚|d   › d|d   › �}||vsŒA|j                  |«       ŒS |j                  d«      }|
j                  ||t        |j                  d«      dt        |d   «      dz
  d|› d�«      t        |j                  d«      dt        |d   «      dz
  d|› d�«      t        |j                  d«      d|d|› d�«      t        j                  |«      r"dt        |«      cxk  rdk  rn nt        |«      ndt        |j                  d «      |«      d!œ«       �ŒÅ ||
d"œS c c}w c c}w c c}w # t        t        f$ r}t        d	d|dz   › d�«      |‚d}~ww xY w)#zGNormalize wizard inputs to the canonical engine shape; 422 on bad data.Ú
conditionsÚidÚproblemTypesc              3  ó&   K  — | ]	  }|d    –— Œ y­w)rL   Nr1   )Ú.0Úss     r3   ú	<genexpr>z"validate_inputs.<locals>.<genexpr>c   s   è ø€ Ò7 !�1�W•:Ñ7ùs   ‚ÚsizesÚproblemsÚmaxProblemsé   rD   zAt most z avalanche problemsÚtyperW   rX   z: choose a problem typeNz: unknown problem type z&: each problem type can be listed onceÚ	locationsz: invalid location r   ú ÚlikelihoodChoiceÚsensitivityz	problems[z].sensitivityÚdistributionz].distributionÚsizez].sizer8   Ú
discussion)rk   rl   ro   rp   rq   rn   rr   )r`   rh   )rB   rF   r[   r   ÚsetÚ	enumerater   rH   rI   Úaddr   Úparse_locationÚappendrU   Úis_numr^   )r$   ÚconfigÚcÚcondition_idsÚpÚtype_idsÚmax_sizer`   rh   ÚseenÚcleanr]   ÚtrT   rl   ÚlocÚparsedÚkeyÚchoices                      r3   Úvalidate_inputsr†   _   s  € à&,¨\Ñ&:Ö; �Q�t“WÐ;€MÐ;Ø!'¨Ñ!7Ö8˜A��$“Ð8€HÐ8ÜÑ7 v¨g¡Ô7Ó7€HØ$Ÿj™j¨Ó6Ò<¸"ÖT˜ÀÀmÒAS’!ÐT€JÐTØ�z‰z˜*Ó%Ò+¨€HÜ
ˆ8ƒ}�v—z‘z -°Ó3Ò3Ü˜C 8¨F¯J©J°}ÀaÓ,HÐ+IÐI\Ð!]Ó^Ð^Ü‹5€DØ€EÜ˜(Ó#ó 
‰ˆˆ1ð	WÜ�A—E‘E˜&“MÓ"ˆAð �HÑÜ  x°°A±¨wÐ6MÈaÈSÐ%QÓRÐRØ�‰9Ü  x°°A±¨wÐ6\Ð%]Ó^Ð^Ø�‰�ŒØˆ	Ø—5‘5˜Ó%Ò+¨ò 	&ˆCÜ×*Ñ*¨3Ó/ˆFÙÜ# C¨8°A¸±E°7Ð:MÈcÈWÐ)UÓVÐVØ˜A‘Y�K˜q ¨¡ Ð,ˆCØ˜)Ò#Ø× Ñ  Õ%ð	&ð —‘Ð)Ó*ˆØ�‰àØ&Ü% a§e¡e¨MÓ&:¸A¼sÀ6È-ÑCXÓ?YÐ\]Ñ?]ÐajÐklÐjmÐmzÐ_{Ó|Ü & q§u¡u¨^Ó'<¸aÄÀVÈNÑE[ÓA\Ð_`ÑA`ÐdmÐnoÐmpÐp~Ðbó  !AÜ˜qŸu™u V›}¨a°¸YÀqÀcÈÐ;PÓQÜ39·=±=ÀÔ3HÈQÔRUÐV\ÓR]ÔMbÐabÕMb¤C¨¤KÐhlÜ)¨!¯%©%°Ó*=¸qÓAñö
	
ð'
ð< %°%Ñ8Ð8ùòO <ùÚ8ùâTøô œ:Ð&ò 	WÜ  x°°A±¨wÐ6MÐ%NÓOÐUVÐVûð	Wús.   ˆJ�J!Á	J&Á!J&ÃJ+Ê+KÊ:KËKc                ó  — | sy	 | j                  d«      |d   k7  ry| j                  dg «      D �cg c]  }|j                  d«      ‘Œ c}|d   D �cg c]  }|d   ‘Œ	 c}k7  S c c}w c c}w # t        t        f$ r Y yw xY w)NFÚsuggestionsTrh   Ú
likelihood)rF   ÚAttributeErrorrH   )ÚclientÚserverr|   s      r3   Ú_differsr�   ‹   s„   € ÙØðØ�:‰:�mÓ$¨¨}Ñ(=Ò=ØØ-3¯Z©Z¸
ÀBÓ-GÖH¨�—‘�lÕ#ÒHÐflÐmwÑfxÖLyÐabÈQÈ|Ë_ÒLyÑyÐyùÒHùÒLyøÜœIÐ&ò Ùðús3   …A- �A- ±A#Á		A- ÁA(ÁA- Á#
A- Á-A?Á>A?c                ó¸   — | syi }t         j                  D ]8  }| j                  |«      }t        |t        «      rd|cxk  rdk  rn n|nd||<   Œ: t        |«      S )zPIn-progress danger per band on a draft: {upper, middle, lower} each 0-5 or None.Nr   r8   )r   ÚBANDSrF   rY   r   r   )ÚratingsrP   ÚbrR   s       r3   Ú_clean_ratingsr’   –   sY   € áØØ
€CÜ�\‰\ò CˆØ�K‰K˜‹NˆÜ  ¤CÔ(¨Q°!¬[°q­[‘¸dˆˆAŠðCô �‹:Ðr2   c                ó2   — | d   }|d   |d   |d   |d   dœS )Nrˆ   r;   r<   r=   r?   )ÚsuÚsmÚslÚsor1   )Úcomputedre   s     r3   Ú_suggest_colsr™   ¡   s+   € Ø�Ñ€AØ�G‘* A h¡K°q¸±zÈÈ9ÉÑVÐVr2   c                ó\   — t        | d|f«      }|st        dd«      ‚t        ||d   «       |S )Na:  SELECT r.*, u.name AS user_name, cc.version AS config_version, z.name AS zone_name, c.name AS center_name
           FROM tool_runs r JOIN users u ON u.id = r.user_id JOIN center_configs cc ON cc.id = r.config_id
           JOIN centers c ON c.id = r.center_id LEFT JOIN zones z ON z.id = r.zone_id WHERE r.id = %si”  zRun not foundr   )r   r   r   )ÚconnÚrun_idÚuserÚruns       r3   Ú	_load_runrŸ   ¦   sB   € Ü
Øð	ið 
ˆ	ó€Cñ Ü˜C Ó1Ð1Ü�4˜˜[Ñ)Ô*Ø€Jr2   c                ó@   — |�t        | d||f«      st        dd«      ‚y y )Nz4SELECT 1 FROM zones WHERE id = %s AND center_id = %srD   z#Zone does not belong to this center)r   r   )r›   r   r!   s      r3   Ú_check_zoner¡   ´   s2   € ØÐ¤8¨DÐ2hÐkrÐt}Ðj~Ô#Ü˜CÐ!FÓGÐGð $@Ðr2   z/runsc                óž  — t        || j                  «       t        || j                  | j                  «       t	        || j                  «      }t        | j                  |d   «      }t        j                  ||d   «      }t        |d| j                  | j                  |j                  |d   t        j                  | j                  t        |«      t        |«      t        | j                  «      | j                  | j                   t#        | j$                  |«      t'        | j(                  «      dœt+        |«      ¥«      }t-        |d   ||«      S )Nry   aÈ  INSERT INTO tool_runs (center_id, zone_id, user_id, config_id, engine_version, valid_date, inputs, computed,
               justifications, suggested_upper, suggested_middle, suggested_lower, suggested_overall, bottom_line, notes,
               client_mismatch, draft_ratings)
           VALUES (%(c)s, %(z)s, %(u)s, %(cfg)s, %(ev)s, %(d)s, %(i)s, %(comp)s, %(j)s, %(su)s, %(sm)s, %(sl)s, %(so)s,
               %(bl)s, %(n)s, %(mm)s, %(dr)s) RETURNING idra   )rz   ÚzÚuÚcfgÚevÚdr]   ÚcompÚjÚblÚnÚmmÚdr)r   r   r¡   r!   r   r†   r$   r   Úcompute_runr   ra   ÚENGINE_VERSIONr"   r   r%   r(   r'   r�   r*   r’   r,   r™   Úget_run)Úbodyr›   r�   r¥   r$   r˜   Úrows          r3   Ú
create_runr³   ¼   s  € ä�4˜Ÿ™Ô(Ü��d—n‘n d§l¡lÔ3Ü
˜˜dŸn™nÓ
-€CÜ˜TŸ[™[¨#¨h©-Ó8€FÜ×!Ñ! &¨#¨h©-Ó8€HÜ
Øð	>ð —‘ d§l¡l¸¿¹ÈÈTÉÔZ`×ZoÑZoØ—‘¤u¨V£}¼eÀH»oÔTYÐZ^×ZmÑZmÓTnØ×"Ñ"¨¯©¼8ÀD×DXÑDXÐZbÓ;cÜ  ×!3Ñ!3Ó4ñ		
ô 9FÀhÓ8Oð		
ó€Cô �3�t‘9˜d DÓ)Ð)r2   é2   c                ód   — t        || «       t        |d| ||t        t        |d«      d«      f«      S )Na¼  SELECT r.id, r.valid_date, r.status, r.created_at, r.finalized_at, r.zone_id, z.name AS zone_name, u.name AS user_name,
                  r.suggested_upper, r.suggested_middle, r.suggested_lower, r.final_upper, r.final_middle, r.final_lower,
                  cc.version AS config_version,
                  (SELECT array_agg((p->>'type')::int) FROM jsonb_array_elements(r.inputs->'problems') p) AS problem_types
           FROM tool_runs r JOIN users u ON u.id = r.user_id JOIN center_configs cc ON cc.id = r.config_id
           LEFT JOIN zones z ON z.id = r.zone_id
           WHERE r.center_id = %s AND (%s::text IS NULL OR r.status = %s)
           ORDER BY r.valid_date DESC, r.id DESC LIMIT %srX   iô  )r   r   rA   rB   )r   ÚstatusÚlimitr›   r�   s        r3   Ú	list_runsr¸   Ô   s<   € ä�4˜Ô#ÜØð	=ð 
�F˜F¤C¬¨E°1«°sÓ$;Ð<óð r2   z/runs/{run_id}c                óÖ   — t        || |«      }t        j                  |d   |d   |d   «      |d<   |d   dk(  xr+ |d   |j                  k(  xs |j	                  |d   «      d	k(  |d
<   |S )Nr$   r˜   r%   Ú	readinessr¶   ÚdraftÚuser_idr   Úcenter_adminÚcan_edit)rŸ   r   rº   ra   Úrole_in©rœ   r›   r�   rž   s       r3   r°   r°   å   sŒ   € ä
�D˜& $Ó
'€CÜ×'Ñ'¨¨H©°s¸:±ÈÐL\ÑH]Ó^€CˆÑØ˜(‘m wÑ.ò  C°C¸	±NÀdÇgÁgÑ4Mò  5BÐQU×Q]ÑQ]Ð^aÐbmÑ^nÓQoð  tBñ  RB€Cˆ
�OØ€Jr2   c                ó”  — t        || |«      }|d   dk7  rt        dd«      ‚|d   |j                  k7  r#|j                  |d   «      dk7  rt        dd	«      ‚|j	                  d
¬«      }d|v rt        ||d   |d   «       t        ||d   «      }t        |j                  d|d   «      |d   «      }t        j                  ||d   «      }|j                  d| |j                  d|d   «      |j                  d|d   «      t        |«      t        |«      t        |j                  d|d   «      «      |j                  d|d   «      |j                  d|d   «      |d   t        j                  t        |j                  d«      |«      d|v rt        |d   «      n|d   rt        |d   «      nd dœt!        |«      ¥«       t#        | ||«      S )Nr¶   r»   é™  zFinalized runs cannot be editedr¼   r   r½   é“  z3Only the author or a center admin can edit this runT)Úexclude_unsetr!   r$   ry   aÃ  UPDATE tool_runs SET zone_id = %(z)s, valid_date = %(d)s, inputs = %(i)s, computed = %(comp)s, justifications = %(j)s,
               notes = %(n)s, bottom_line = %(bl)s, config_id = %(cfg)s, engine_version = %(ev)s,
               suggested_upper = %(su)s, suggested_middle = %(sm)s, suggested_lower = %(sl)s, suggested_overall = %(so)s,
               client_mismatch = %(mm)s, draft_ratings = %(dr)s, updated_at = now()
           WHERE id = %(id)sr"   r%   r'   r(   ra   r*   r,   )ra   r£   r§   r]   r¨   r©   r«   rª   r¥   r¦   r¬   r­   )rŸ   r   ra   r¿   Ú
model_dumpr¡   r   r†   rF   r   r®   Úexecuter   r¯   r�   r’   r™   r°   )	rœ   r±   r›   r�   rž   Úfieldsr¥   r$   r˜   s	            r3   Ú
update_runrÈ   í   sÍ  € ä
�D˜& $Ó
'€CØ
ˆ8�}˜ÒÜ˜CÐ!BÓCÐCØ
ˆ9�~˜Ÿ™Ò  T§\¡\°#°kÑ2BÓ%CÀ~Ò%UÜ˜CÐ!VÓWÐWØ�_‰_¨4ˆ_Ó0€FØ�FÑÜ�D˜#˜kÑ*¨F°9Ñ,=Ô>Ü
˜˜c +Ñ.Ó
/€CÜ˜VŸZ™Z¨°#°h±-Ó@À#ÀhÁ-ÓP€FÜ×!Ñ! &¨#¨h©-Ó8€HØ‡L�Lð	 ð ˜vŸz™z¨)°S¸±^ÓDÈ6Ï:É:ÐVbÐdgÐhtÑduÓKvÜ�v“¬¨h«¼eÀFÇJÁJÐO_ÐadÐeuÑavÓDwÓ>xØ—‘˜G S¨¡\Ó2¸&¿*¹*À]ÐTWÐXeÑTfÓ:gØ�t‘9¤F×$9Ñ$9ÄÈ&Ï*É*ÐUfÓJgÐiqÓArØ=LÐPVÑ=V”. ¨Ñ!8Ô9Ø/2°?Ò/C”�c˜/Ñ*Ô+Èñ	
ô ˜HÓ%ð	
ôô  �6˜4 Ó&Ð&r2   c                óÜ   — t        || |«      }|d   dk7  rt        dd«      ‚|d   |j                  k7  r#|j                  |d   «      dk7  rt        dd	«      ‚|j	                  d
| f«       ddiS )Nr¶   r»   rÂ   z"Finalized runs are kept as historyr¼   r   r½   rÃ   z5Only the author or a center admin can delete this runz#DELETE FROM tool_runs WHERE id = %sÚokT)rŸ   r   ra   r¿   rÆ   rÀ   s       r3   Ú
delete_runrË     sx   € ä
�D˜& $Ó
'€CØ
ˆ8�}˜ÒÜ˜CÐ!EÓFÐFØ
ˆ9�~˜Ÿ™Ò  T§\¡\°#°kÑ2BÓ%CÀ~Ò%UÜ˜CÐ!XÓYÐYØ‡L�LÐ6¸¸	ÔBØ�$ˆ<Ðr2   z/runs/{run_id}/finalizec                óà  — t        || |«      }|d   dk7  rt        dd«      ‚|d   |j                  k7  r#|j                  |d   «      dk7  rt        dd	«      ‚t	        ||d
   «      d   }t        j                  |d   |«      }t        j                  |d   ||d   «      }|rt        dd|dœ«      ‚|j                  |j                  |j                  dœ}|j                  �|j                  nt        |j                  «       «      }	t        j                  |d   ||«      |d<   t        |d   d   «      D �
�cg c]@  \  }
}|
dz   |d   |d   |d   |
   d   |d   d   |d   d   |j!                  d«      xs ddœ‘ŒB }}
}|j#                  dt%        |«      |j                  |j                  |j                  |	t%        |«      |j&                  |j(                  | f	«       t+        | ||«      S c c}}
w )Nr¶   r»   rÂ   zAlready finalizedr¼   r   r½   rÃ   z7Only the author or a center admin can finalize this runÚ	config_idry   r$   r%   rD   z Finish the run before finalizing)ÚmessageÚissues©r;   r<   r=   ÚfinalChecksrh   rX   rk   rl   r‰   rq   rA   rB   rr   rC   ©Úrankrk   rl   r‰   Úsize_minÚsize_maxrr   a?  UPDATE tool_runs SET status = 'finalized', finalized_at = now(), updated_at = now(), computed = %s,
               final_upper = %s, final_middle = %s, final_lower = %s, final_overall = %s, final_problems = %s,
               bottom_line = coalesce(%s, bottom_line), notes = coalesce(%s, notes)
           WHERE id = %s)rŸ   r   ra   r¿   r   r   r®   rº   r;   r<   r=   r?   rB   ÚvaluesÚguidance_checksrt   rF   rÆ   r   r(   r'   r°   )rœ   r±   r›   r�   rž   ry   r˜   rÏ   Úfinalr?   r]   r|   Úfinal_problemss                r3   Úfinalize_runrÚ     s  € ä
�D˜& $Ó
'€CØ
ˆ8�}˜ÒÜ˜CÐ!4Ó5Ð5Ø
ˆ9�~˜Ÿ™Ò  T§\¡\°#°kÑ2BÓ%CÀ~Ò%UÜ˜CÐ!ZÓ[Ð[Ü˜$  KÑ 0Ó1°(Ñ;€FÜ×!Ñ! # h¡-°Ó8€HÜ×Ñ˜c (™m¨X°sÐ;KÑ7LÓM€FÙÜ˜CÐ-OÐ[aÑ!bÓcÐcØ—j‘j¨D¯K©KÀ$Ç*Á*ÑM€EØ"Ÿl™lÐ6ˆd�lŠl¼CÀÇÁÃÓ<O€GÜ$×4Ñ4°S¸±]ÀFÈEÓR€Hˆ]Ñô ˜c (™m¨JÑ7Ó8÷ñ ˆAˆqð ˜‘EØ�f‘IØ˜;™Ø" :Ñ.¨qÑ1°,Ñ?Ø˜&™	 %Ñ(Ø˜&™	 %Ñ(ØŸ%™% Ó-Ò3°ó	
ð€Nñ ð 	‡L�Lð	ô 
ˆx‹˜$Ÿ*™* d§k¡k°4·:±:¸wÌÈnÓH]Ð_c×_oÑ_oÐqu×q{Ñq{ð  ~Dð  	Eôô �6˜4 Ó&Ð&ùó's   Ä6AG*)ÚNÚNEÚEÚSEÚSÚSWÚWÚNWT)ÚstrictÚaboveÚnearÚbelowrÐ   c                ó6   — | €yt        | «      }|dk\  ryd|d›�S )NÚ?é   u   D4â€“5ÚDÚg)rG   )rR   rS   s     r3   Ú	_fmt_sizerì   C  s+   € Ø€yØÜˆa‹€AØˆA‚vØØˆq�ˆeˆ9Ðr2   c                óà   ‡‡— i Š| D ]=  }|j                  «       \  }}‰j                  |g «      j                  t        |   «       Œ? dj	                  ˆˆfd„t
        j                  D «       «      S )Nz; c              3  óz   •K  — | ]2  }|‰v sŒ‰j                  ||«      › d dj                  ‰|   «      › �–— Œ4 y­w)ú: z, N)rF   Újoin)rd   r‘   Úband_labelsÚby_bands     €€r3   rf   z"_locations_text.<locals>.<genexpr>Q  s?   øè ø€ ÒoÈQÐbcÐgnÒbn˜Ÿ™¨¨1Ó-Ð.¨b°·±¸7À1¹:Ó1FÐ0GÔHÑoùs   ƒ	;�.;)ÚsplitÚ
setdefaultrw   ÚABBRrð   r   r�   )rl   rñ   r‚   ÚaspectÚbandrò   s    `   @r3   Ú_locations_textrø   L  sc   ù€ Ø$&€GØò :ˆØ—y‘y“{‰ˆ�Ø×Ñ˜4 Ó$×+Ñ+¬D°©LÕ9ð:ð �9‰9ÔoÔRX×R^ÑR^ÔoÓoÐor2   c                óú   — | j                  d«      r| d   S t        | d   d   «      D ��cg c]C  \  }}|dz   |d   |d   | d   d   |   d   |d	   d
   |d	   d   |j                  d«      xs ddœ‘ŒE c}}S c c}}w )NrÙ   r$   rh   rX   rk   rl   r˜   r‰   rq   rA   rB   rr   rC   rÒ   )rF   rt   )rž   r]   r|   s      r3   Ú_problems_for_exportrú   T  s¨   € Ø
‡w�wÐÔ ØÐ#Ñ$Ð$ô ˜c (™m¨JÑ7Ó8÷ñ ˆAˆqð	 ˜‘E 1 V¡9¸1¸[¹>Ø˜j™/¨*Ñ5°aÑ8¸ÑFØ˜&™	 %Ñ(°a¸±iÀÑ6FÐVW×V[ÑV[Ð\hÓViÒVoÐmoó	
óð ùó s   «AA7z/runs/{run_id}/exportÚtextc                óú	  ‡‡‡— t        || |«      Št        |‰d   «      d   }t        ‰«      }|j                  d«      xs i Š|d   D �ci c]  }|d   |d   “Œ c}Š|dk(  r¾d‰j                  d	«      xs d
d‰d   ‰d   ‰d   dœg|D �cg c]y  }|d   t	        j                  |d   «      |d   |d   t        j                  |d   «      |d   � t        |d   «      d›t        |d   «      d›gng |j                  d«      xs d
dœ‘Œ{ c}‰d   ‰d   ‰d   ‰d   dœdœS |dk(  �r¢|D ��cg c�]  }t        t        |d      «      t        |d   xs d
«      t        t        d t        d!t        j                  t        |d   xs |d   «      «      «      «      «      t        t        d t        d!t        j                  t        |d   xs |d   «      «      «      «      «      |d   D �cg c]O  }t        |j                  «       d       › d"t         j"                  j%                  |j                  «       d#   «      › �‘ŒQ c}d$œ‘�Œ c}}‰j                  ‰d%   «      ‰j                  ‰d&   «      ‰j                  ‰d'   «      ‰j                  ‰d(   «      d)œ‰j                  d*«      xs i j'                  «       D �	cg c]  }	|	sŒ|	‘Œ	 c}	d+œS |d,k7  rt)        d-d.«      ‚d/‰d0   › ‰d1   rd2‰d1   z   nd
› d3‰d   › �g}
‰d4   d5k(  r=|
j+                  d6d7j-                  ˆˆˆfd8„t         j.                  D «       «      z   «       n|
j+                  d9«       |
j+                  d
«       |D ]ï  }t        j                  |d   d:«      }|d   |d   k(  rt1        |d   «      nt1        |d   «      › d;t1        |d   «      › �}|
j+                  d<|d   › d=t	        j                  |d   «      › d3|j3                  «       › d3|› �«       |
j+                  d>t5        |d   ‰«      › �«       |j                  d«      sŒË|
j+                  d?|d   j7                  «       › �«       Œñ ‰j                  d*«      xs i j9                  «       D ]  \  }}|sŒ	|
j+                  d@|› dA|› �«       Œ! ‰j                  d	«      r|
d
dB‰d	   › �gz  }
|
d
dC‰d   › dD‰d   › dE�gz  }
t;        dFj-                  |
«      «      S c c}w c c}w c c}w c c}}w c c}	w )GNrÍ   ry   Ú
bandLabelsÚdangerLevelsÚlevelÚnameÚafpÚforecastr(   rC   ÚcurrentÚfinal_upperÚfinal_middleÚfinal_lower)Ú	valid_dayr;   r<   r=   rk   rÓ   rl   r‰   rÔ   z.1frÕ   rr   )Úavalanche_problem_idr   rÓ   Úlocationr‰   rq   rr   ra   r"   Úconfig_versionÚengine_version)Útool_run_idr"   r
  r  )Úproduct_typer(   ÚdangerÚforecast_avalanche_problemsÚmetaÚbackdroprX   r8   ú:r   )rk   r‰   ÚsizeMinÚsizeMaxÚroseÚsuggested_upperÚsuggested_middleÚsuggested_lowerÚsuggested_overall)rä   rå   ræ   r?   r%   )rh   rˆ   r'   rû   rD   z!fmt must be text, afp or backdropu    Avalanche forecast guidance â€” Úcenter_nameÚ	zone_namez / u    â€” r¶   Ú	finalizedzDanger: z | c              3  óx   •K  — | ]1  }‰j                  ||«      › d ‰j                  ‰d|z      d«      › �–— Œ3 y­w)rï   Úfinal_rè   N)rF   )rd   r‘   rñ   Údanger_namesrž   s     €€€r3   rf   zexport_run.<locals>.<genexpr>›  sB   øè ø€ ÒvÐde˜KŸO™O¨A¨qÓ1Ð2°"°\×5EÑ5EÀcÈ(ÐUVÉ,ÑFWÐY\Ó5]Ð4^Ô_Ñvùs   ƒ7:zDanger: not yet set (draft)rè   u   â€“rW   rï   z	  Where: z  zPairing note (z): zBottom line: zTool config vz	, engine u3   . Guidance only â€” the forecaster sets the rating.ú
)rŸ   r   rú   rF   r   r   rG   rZ   r   rB   rA   rJ   ÚfloorÚceilÚWIZARD_BANDró   r   ÚASPECTSÚindexrÖ   r   rw   rð   r�   rì   Ú
capitalizerø   ÚstripÚitemsr   )rœ   Úfmtr›   r�   ry   rh   r§   r|   r‚   rR   ÚlinesÚlikerq   r„   rû   rñ   r  rž   s                  @@@r3   Ú
export_runr,  a  sË  ú€ ä
�D˜& $Ó
'€CÜ˜$  KÑ 0Ó1°(Ñ;€FÜ# CÓ(€HØ—*‘*˜\Ó*Ò0¨b€KØ39¸.Ñ3IÖJ¨a�A�g‘J  &¡	Ñ)ÒJ€Là
ˆe‚|à&ØŸ7™7 =Ó1Ò7°RØ%.¸¸]Ñ9KÐWZÐ[iÑWjÐuxð  zGñ  vHñ  Ið  Jð "ö,ð ð -.¨f©IÜ-×1Ñ1°!°F±)Ó<Ø˜f™IØ ! +¡Ü"2×"6Ñ"6°q¸±Ó"GØ^_Ð`jÑ^kÐ^w¤ a¨
¡mÓ 4°SÐ9¼uÀQÀzÁ]Ó?SÐTWÐ>XÑZÐ}Ø"#§%¡%¨Ó"5Ò";¸óò,ð %(¨¡I¸SÀÑ=NÐbeÐfvÑbwð  LOð  P`ñ  Lañ  bñ!
ð 	
ð& ˆjÓð "÷ð ð ô  Ô 5°a¸±iÑ @ÓAÜ"% a¨¡oÒ&;¸Ó"<Ü"¤3 q¬#¨a´·±¼EÀ!ÀJÁ-ÒB`ÐSTÐU_ÑS`Ó<aÓ1bÓ*cÓ#dÓeÜ"¤3 q¬#¨a´·±¼5ÀÀ:ÁÒA_ÐRSÐT^ÑR_Ó;`Ó1aÓ*bÓ#cÓdàklÐmxÑkyöØdgœ; s§y¡y£{°1¡~Ñ6Ð7°q¼¿¹×9MÑ9MÈcÏiÉiËkÐZ[ÉnÓ9]Ð8^Ò_òôóð &×)Ñ)¨#Ð.?Ñ*@ÓAØ$×(Ñ(¨Ð-?Ñ)@ÓAØ%×)Ñ)¨#Ð.?Ñ*@ÓAØ'×+Ñ+¨CÐ0CÑ,DÓEñ	ð #&§'¡'Ð*:Ó";Ò"A¸r×!IÑ!IÓ!KÖQ˜AÊq’aÒQñ'
ð 	
ð, ˆf‚}Ü˜CÐ!DÓEÐEØ/°°MÑ0BÐ/CÐ`cÐdoÒ`pÀEÈCÐP[ÑL\ÒD\ÐvxÐCyÐy~ð  @Cð  DPñ  @Qð  Rð  Sð  T€EØ
ˆ8�}˜Ò#Ø�‰ØØ�j‰jÕvÔio×iuÑiuÔvÓvñwõ	
ð
 	�‰Ð2Ô3Ø	‡L�L�ÔØò 9ˆÜ×#Ñ# A l¡O°SÓ9ˆØ+,¨Z©=¸A¸j¹MÒ+IŒy˜˜:™Ô'ÔR[Ð\]Ð^hÑ\iÓRjÐQkÐknÔoxÐyzð  |Fñ  zGó  pHð  oIð  PJˆØ�‰�x  &¡	˜{¨"Ô->×-BÑ-BÀ1ÀVÁ9Ó-MÐ,NÈeÐTX×TcÑTcÓTeÐSfÐfkÐlpÐkqÐrÔsØ�‰�y¤°°;±ÀÓ!MÐ NÐOÔPØ�5‰5�ÕØ�L‰L˜2˜a ™o×3Ñ3Ó5Ð6Ð7Õ8ð9ð —g‘gÐ.Ó/Ò5°2×<Ñ<Ó>ò :‰	ˆˆTÚØ�L‰L˜>¨#¨¨c°$°Ð8Õ9ð:ð ‡w�wˆ}ÔØ�"˜ c¨-Ñ&8Ð%9Ð:Ð;Ñ;ˆØ	ˆb�M #Ð&6Ñ"7Ð!8¸	À#ÐFVÑBWÐAXð  YLð  Mð  Nñ  N€EÜ˜TŸY™Y uÓ-Ó.Ð.ùòM Kùò,ùò0ùóùò$ Rs3   Á
S#ÂA>S(
Ä+B:S2Ç%AS-È9S2Ê7S8Ê?S8Ó-S2)rM   rG   rN   rG   rO   rZ   Úreturnr#   )r]   r   r-  rZ   )r$   r#   ry   r#   r-  r#   )r‹   r)   rŒ   r#   r-  Úbool)r�   r)   r-  zJsonb | None)r˜   r#   r-  r#   )r›   r	   rœ   r   r�   r   r-  r#   )r›   r	   r   r   r!   r    r-  ÚNone)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±   r5   r›   r	   r�   r   )rœ   r   r±   r7   r›   r	   r�   r   )r-  rZ   )rl   z	list[str]rñ   r#   r-  rZ   )rž   r#   r-  z
list[dict])rœ   r   r)  rZ   r›   r	   r�   r   )CÚ__doc__Ú
__future__r   rJ   Údatetimer   Úfastapir   r   r   Úfastapi.responsesr   Úpsycopgr	   Úpydanticr
   r   rC   r   Úauthr   r   r   Úconfigsr   r   Údbr   r   r   r   Úmappingr   r   r   Úrouterr   r5   r7   rU   r\   r^   r†   r�   r’   r™   rŸ   r¡   Úpostr³   rF   r¸   r°   ÚputrÈ   ÚdeleterË   rÚ   r#   Úzipr$  rõ   r#  rì   rø   rú   r,  r1   r2   r3   ú<module>r@     s0  ðñõ #ã Ý ç 5Ñ 5Ý /Ý ß %å ß 5Ñ 5ß 1ß 4Ó 4ß PÑ Pá	˜˜Ô	!€ô	7ˆIô 	7ô7�	ô 7ô�ô óð( €óó)9óXóóWó
óHð ‡�ˆWÓÙ/6°xÓ/@ÉwÐWcÓOdó *ó ð*ð. ‡�ˆGÓØ37ÀbÑ]dÐemÓ]nñ  ~Eð  FRó  ~Só ó ðð  ‡�ÐÓÙ,3°HÓ,=ÉGÐT`ÓLaó ó ðð ‡�ÐÓÙ@GÈÓ@QÑ`gÐhtÓ`uó 'ó ð'ð> ‡�ÐÓ Ù/6°xÓ/@ÉwÐWcÓOdó ó !ðð ‡�Ð&Ó'ÙCJÈ8ÓCTÑcjÐkwÓcxó !'ó (ð!'ñL ‰C�—‘Ò LÐUYÔZÓ[€Ø¨6¸GÑD€óópó
ð ‡�Ð#Ó$Ø'-Á'È(ÓBSÑbiÐjvÓbwó K/ó %ñK/r2   