Ë
    V“ŽjT  ã            ,       óØ  — d dl Z d dlZd dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZmZ d dlmZ d dlmZ d dl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 d dlmZmZ d dl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( d dl)m*Z*m+Z+ d dl,m,Z,  e«         ee e jZ                  dd«      ¬«      Z. ed¬«      Z/e.e/j`                  _.        e/jc                  ee«       e/je                  edgddgdg¬«        ed¬«      Z3e3ji                  dd¬«        ed¬«      Z5e5ji                  dd¬«        e*e3«      Z6 e+e5«      Z7de8d e8fd!„Z9d"e8d e8fd#„Z:d[d$e;d%e8d&e8d e;fd'„Z<d(ed e8fd)„Z=e/j}                  d*e'¬+«      e.j                  d,«       ed-«       ed-«       ed-«       ed«       ed«       ed«       ed.«       ed.«       ed.«       ed/«       edd d0¬1«      fd(ed2e8de8d3e8d4ee@   d5eeA   d6eeA   d7e8d8e8d9e8d:ee8   d;eeA   fd<„«       «       ZBe/j‡                  d=d>d?ge!¬@«      e.j                  dA«       ed-«       ed-«       ed-«       ed«       ed«       ed«       ed.«       ed.«       ed.«       ed«       ed«       ed«       ed«       ed«       ed«       ed«       ed«       ed«       ed/«      fd(ed2e8de8d3e8d4ee@   d5eeA   d6eeA   d7e8d8e8d9e8dBee8   dCee@   dDeeA   dEeeA   dFeeA   dGee@   dHee@   dIee@   dJeDd:ee8   f(dK„«       «       ZEe/j}                  dLe#¬+«      e.j                  dM«       ed-«       ed-«       ed-«       ed-«       ed-«       ed-«       ed.«       ed.«       ed.«       ed«      f
d(ed2e8de8d3e8dNe8d"e8dOe@d7e8d8e8d9e8dJeDfdP„«       «       ZFe/j�                  dQe%¬+«      e.j                  dM«      d(edRe$fdS„«       «       ZHe/j�                  dTe&¬+«      e.j                  dA«       ed-«       ed-«       ed-«       ed.«       ed.«       ed.«       ed«       ed-«      fd(ed2e8de8d3e8d7e8d9e8d8e8dBee8   dUe
fdV„«       «       ZIe/j}                  dW«      d(efdX„«       ZJe/j}                  dY«      d(efdZ„«       ZKy)\é    N)ÚOptional)ÚFastAPIÚQueryÚRequestÚHTTPExceptionÚ
UploadFileÚFileÚForm)ÚJSONResponse)ÚCORSMiddleware)Úload_dotenv)ÚImage)Údatetime)ÚLimiterÚ_rate_limit_exceeded_handler)Úget_remote_address)ÚRateLimitExceeded)ÚMealGenVectorStoreÚScannerVectorStore)ÚMealPlanResponseÚSwapMealRequestÚSwapMealResponseÚMealImageRequestÚMealImageResponseÚFoodScanResponseÚDailyNutritionResponseÚMacronutrients)ÚEnhancedMealPlanGeneratorÚFoodScanner)Útranslation_serviceÚ	REDIS_URLzredis://localhost:6379)Úkey_funcÚstorage_uriz+BloodFIT Meal Plan Generator - Scalable API)ÚtitleÚ*T)Úallow_originsÚallow_credentialsÚallow_methodsÚallow_headersÚfaiss_mealgen)Ú
index_pathz'diet/meal_generation/mealgen_foods.jsonF)Úforce_rebuildÚfaiss_scannerz$diet/meal_scanner/scanner_foods.jsonÚ
blood_typeÚreturnc                 óŠ   — | j                  «       j                  «       } | j                  d«      d   j                  d«      d   S )NÚ+r   Ú-)ÚstripÚupperÚsplit)r.   s    ú7/var/www/html/Fitness-lenito-AI-main/fitness_app/app.pyÚnormalize_blood_typer7   7   s?   € Ø×!Ñ!Ó#×)Ñ)Ó+€JØ×Ñ˜CÓ  Ñ#×)Ñ)¨#Ó.¨qÑ1Ð1ó    Úsub_categoryc                 ó´   — | j                  «       j                  «       } dddddddœ}|j                  | | j                  dd«      j                  dd«      «      S )NÚprotein_packedÚlight_freshÚhealthy_comforting)zprotein-packedzprotein packedzlight & freshzlight and freshzhealthy & comfortingzhealthy and comfortingÚ Ú_r2   )Úlowerr3   ÚgetÚreplace)r9   Úmappings     r6   Únormalize_sub_categoryrD   ;   s`   € Ø×%Ñ%Ó'×-Ñ-Ó/€Là*Ø*Ø&Ø(Ø 4Ø"6ñ€Gð �;‰;�| \×%9Ñ%9¸#¸sÓ%C×%KÑ%KÈCÐQTÓ%UÓVÐVr8   Úresponse_dataÚlanguageÚresponse_typec                 ó0  — |dk(  st        j                  «       s| S |dk(  rt        j                  | |«      S |dk(  rt        j                  | |«      S |dk(  r:| j	                  dg «      D �cg c]  }t        j
                  ||«      ‘Œ }}|| d<   | S | S c c}w )NÚenÚ	meal_planÚ	food_scanÚ	swap_mealÚalternatives)r    Úis_translation_enabledÚtranslate_meal_plan_responseÚtranslate_food_scan_responserA   Útranslate_meal)rE   rF   rG   ÚmealÚtranslated_alternativess        r6   Útranslate_responserT   G   s´   € Ø�4ÒÔ2×IÑIÔKØÐØ˜Ò#Ü"×?Ñ?ÀÈxÓXÐXØ	˜+Ò	%Ü"×?Ñ?ÀÈxÓXÐXØ	˜+Ò	%ð &×)Ñ)¨.¸"Ô=ó#
á=�ô  ×.Ñ.¨t°XÕ>Ø=ð 	 ð #
ð )@ˆ�nÑ%ØÐØÐùò#
s   Á+BÚrequestc                 ó:   — | j                   j                  dd«      S )NrF   rI   )Úquery_paramsrA   )rU   s    r6   Úget_language_from_requestrX   W   s   € Ø×Ñ×#Ñ# J°Ó5Ð5r8   z/calculate-daily-nutrition)Úresponse_modelz	20/minute.Ú zStay Fiti,  )ÚgtÚleÚuser_idÚ	diet_typeÚageÚweightÚheightÚcountryÚfood_dislikesÚ	allergiesÚ	main_goalÚdesired_weightc              ƒ   ó:  K  — t        | «      }t        |«      }|j                  «       }g d¢}g d¢}||vrd}|dk(  rd}t        d|¬«      ‚||vrd}|dk(  rd	}t        d|¬«      ‚|d
k(  rd}|||||||||	|
|dœ}t        j                  |«      ƒ d {  –—† }|S 7 Œ­w)N©ÚOÚAÚBÚAB©ÚclassicÚveganÚpescatarianÚ
vegetarianú+Invalid blood type. Must be O, A, B, or AB.ÚkoõE   ìž˜ëª»ë�œ í˜ˆì•¡í˜•ìž…ë‹ˆë‹¤. O, A, B, AB ì¤‘ í•˜ë‚˜ì—¬ì•¼ í•©ë‹ˆë‹¤.é�  ©Ústatus_codeÚdetailúGInvalid diet type. Must be classic, vegan, pescatarian,  or vegetarian.õy   ìž˜ëª»ë�œ ì‹�ë‹¨ ìœ í˜•ìž…ë‹ˆë‹¤. í�´ëž˜ì‹�, ë¹„ê±´, íŽ˜ìŠ¤ì¹´í…Œë¦¬ì•ˆ, ì¹´ë‹ˆë³´ì–´, ë¹„ê±´ ì¤‘ í•˜ë‚˜ì—¬ì•¼ í•©ë‹ˆë‹¤.rn   Ústandard)r]   r.   r^   r_   r`   ra   rb   rc   rd   re   rf   )rX   r7   r@   r   Úmeal_generatorÚcalculate_daily_nutrition)rU   r]   r.   r^   r_   r`   ra   rb   rc   rd   re   rf   rF   Úvalid_blood_typesÚvalid_diet_typesÚ	error_msgÚ	user_dataÚnutrition_responses                     r6   r}   r}   ^   sà   è ø€ ô  )¨Ó1€HÜ% jÓ1€JØ—‘Ó!€Iâ-ÐÚHÐàÐ*Ñ*ØAˆ	Ø�tÒØ_ˆIÜ¨°IÔ>Ð>àÐ(Ñ(Ø]ˆ	Ø�tÒð TˆIÜ¨°IÔ>Ð>à�IÒØˆ	ð Ø ØØØØØØ&ØØØ(ñ€Iô  .×GÑGÈ	ÓR×RÐØÐð Sús   ‚BBÂBÂBz/generate-meal-planÚGETÚPOST)ÚmethodsrY   z	10/minuteÚblood_group_rulesÚtotal_daily_caloriesÚcarbsÚproteinÚfatÚbreakfast_caloriesÚlunch_caloriesÚdinner_caloriesÚgenerate_imagesc              ƒ   óZ  K  — t        | «      }t        |«      }|j                  «       }|
s=| j                  dk(  r.	 | j	                  «       ƒ d {  –—† }|j                  d«      xs d }
g d¢}g d¢}||vrd}|dk(  rd}t        d|¬	«      ‚||vrd
}|dk(  rd}t        d|¬	«      ‚|dk(  rd}|||||||||	|
|dœ}d }|rQ|rO|rM|rKi }|r||d<   |r||d<   |r||d<   t        |t        |||¬«      |||t        j                  «       |r|nd ¬«      }	 t        j                  |||¬«      ƒ d {  –—† }|j                  «       }t        ||d«      }t!        |¬«      S 7 �Œ
# t        $ r Y Œþw xY w7 Œ?# t        $ r3}dt#        |«      › �}|dk(  rdt#        |«      › �}t        d|¬	«      ‚d }~ww xY w­w)Nr„   r†   rh   rm   rr   rs   rt   ru   rv   ry   rz   rn   r{   )r]   r.   r^   r_   r`   ra   rb   rc   rd   r†   re   Ú	breakfastÚlunchÚdinner)Úcarbohydratesr‰   rŠ   )r‡   Útotal_daily_macronutrientsr]   r.   r^   Úcalculation_timestampÚmeal_calorie_distribution©rŽ   rJ   ©ÚcontentzMeal plan generation failed: u   ì‹�ë‹¨ ê³„íš� ìƒ�ì„± ì‹¤íŒ¨: éô  )rX   r7   r@   ÚmethodÚformrA   Ú	Exceptionr   r   r   r   Únowr|   Úgenerate_meal_planÚdictrT   r   Ústr) rU   r]   r.   r^   r_   r`   ra   rb   rc   rd   r†   r‡   rˆ   r‰   rŠ   r‹   rŒ   r�   rŽ   re   rF   rœ   r~   r   r€   r�   Údaily_nutritionÚmeal_distributionÚmeal_plan_responseÚresponse_dictÚtranslated_responseÚes                                    r6   rŸ   rŸ   –   s-  è ø€ ô0 )¨Ó1€HÜ% jÓ1€JØ—‘Ó!€Iñ Ø�>‰>˜VÒ#ðØ$Ÿ\™\›^×+�Ø$(§H¡HÐ-@Ó$AÒ$IÀTÐ!ò .ÐÚHÐàÐ*Ñ*ØAˆ	Ø�tÒØ_ˆIÜ¨°IÔ>Ð>àÐ(Ñ(Ø]ˆ	Ø�tÒð TˆIÜ¨°IÔ>Ð>à�IÒØˆ	ð Ø ØØØØØØ&ØØ.Øñ€Ið €OÙ¡©'±cØÐÙØ-?Ð˜kÑ*ÙØ)7Ð˜gÑ&ÙØ*9Ð˜hÑ'ä0Ø!5Ü'5Ø#ØØô(ð
 Ø!ØÜ"*§,¡,£.Ù;LÑ&7ÐRVô
ˆð?Ü#1×#DÑ#DØØØ+ð $Eó $
÷ 
Ðð +×/Ñ/Ó1ˆÜ0°ÀÈ+ÓVÐÜÐ$7Ô8Ð8ðM ,úäò Ùðúðx
ùô ò ?Ø3´C¸³F°8Ð<ˆ	Ø�tÒØ7¼¸A»°xÐ@ˆIÜ¨°IÔ>Ð>ûð	?üsq   ‚8F+»E ÁEÁE Á(B&F+ÄE, Ä*E*Ä+,E, ÅF+ÅE Å	E'Å$F+Å&E'Å'F+Å*E, Å,	F(Å5.F#Æ#F(Æ(F+z
/swap-mealz	15/minuteÚcategoryÚcurrent_caloriesc              ƒ   óN  K  — t        | «      }t        |«      }|j                  «       }|j                  «       }t        |«      }g d¢}g d¢}||vrd}|dk(  rd}t	        d|¬«      ‚||vrd}|dk(  rd	}t	        d|¬«      ‚|d
k(  rd}t        |||||||||	¬«	      }	 t        j                  ||
¬«      ƒ d {  –—† }|j                  «       }t        ||d«      }t        |¬«      S 7 Œ-# t        $ r3}dt        |«      › �}|dk(  rdt        |«      › �}t	        d|¬«      ‚d }~ww xY w­w)Nrh   rm   rr   rs   rt   ru   rv   ry   rz   rn   r{   )	r]   r.   r^   r¨   r9   r©   rb   rc   rd   r—   rL   r˜   zSwap meal generation failed: u   ëŒ€ì²´ ì‹�ì‚¬ ìƒ�ì„± ì‹¤íŒ¨: rš   )rX   r7   r@   rD   r   r   r|   Úgenerate_swap_mealsr    rT   r   r�   r¡   )rU   r]   r.   r^   r¨   r9   r©   rb   rc   rd   rŽ   rF   r~   r   r€   Úswap_requestÚswap_responser¥   r¦   r§   s                       r6   rL   rL     sb  è ø€ ô )¨Ó1€HÜ% jÓ1€JØ—‘Ó!€IØ�~‰~Ó€HÜ)¨,Ó7€Lâ-ÐÚHÐàÐ*Ñ*ØAˆ	Ø�tÒØ_ˆIÜ¨°IÔ>Ð>àÐ(Ñ(Ø]ˆ	Ø�tÒð TˆIÜ¨°IÔ>Ð>à�IÒØˆ	ä"ØØØØØ!Ø)ØØ#Øô
€Lð?ä,×@Ñ@ÀÐ_nÐ@Óo×oˆØ%×*Ñ*Ó,ˆÜ0°ÀÈ+ÓVÐÜÐ$7Ô8Ð8ð pùô
 ò ?Ø3´C¸³F°8Ð<ˆ	Ø�tÒØ7¼¸A»°xÐ@ˆIÜ¨°IÔ>Ð>ûð	?üs<   ‚BD%ÂC& Â6C$Â7,C& Ã#D%Ã$C& Ã&	D"Ã/.DÄD"Ä"D%z/generate-meal-imagesÚmeal_requestc              ƒ   óÀ  K  — 	 t        | «      }|j                  D �cg c]  }|j                  |j                  xs ddœ‘Œ! }}t        j
                  j                  |j                  |j                  |«      }t        ||j                  ¬«      S c c}w # t        $ r>}dt        |«      › �}t        | «      }|dk(  rdt        |«      › �}t        d|¬«      ‚d }~ww xY w­w)	NÚsome)ÚnameÚquantity)Úmeal_image_base64ÚidzImage generation failed: rs   u   ì�´ë¯¸ì§€ ìƒ�ì„± ì‹¤íŒ¨: rš   rv   )rX   Úingredientsr±   r²   r|   Úmeal_image_generatorÚgenerate_meal_imageÚ	meal_nameÚdescriptionr   r´   r�   r¡   r   )rU   r®   rF   ÚingÚingredients_listr³   r§   r€   s           r6   Úgenerate_meal_imagesr¼   F  së   è ø€ ð?Ü,¨WÓ5ˆð $×/Ò/ó
á/�ð —X‘X¨3¯<©<Ò+A¸6ÓBØ/ð 	ð 
ô
 +×?Ñ?×SÑSØ×"Ñ"Ø×$Ñ$Øó
Ðô !Ø/Ø�‰ô
ð 	
ùò
øô" ò ?Ø/´°A³¨xÐ8ˆ	Ü,¨WÓ5ˆØ�tÒØ3´C¸³F°8Ð<ˆIÜ¨°IÔ>Ð>ûð?üs:   ‚C„B �$BÁAB ÂCÂB Â	CÂ9CÃCÃCz
/scan-foodÚimagec	              ƒ   ó>  K  — t        | «      }	t        |«      }|j                  «       }|s| j                  j	                  d«      xs d }g d¢}
g d¢}||
vrd}|	dk(  rd}t        d|¬«      ‚||vrd	}|	dk(  rd
}t        d|¬«      ‚|dk(  rd}|j                  j                  d«      sd}|	dk(  rd}t        d|¬«      ‚	 |j                  «       ƒ d {  –—† }	 t        j                  t        j                  |«      «      }|j                  «        t        j                  t        j                  |«      «      }|j                  dk  s|j                   dk  rd}|	dk(  rd}t        d|¬«      ‚|j"                  dk7  r|j%                  d«      }|j'                  «        |||||||dœ}	 t*        j-                  ||«      ƒ d {  –—† }|j/                  «       }t1        ||	d«      }t3        |¬«      S 7 �Œ# t        $ r d}|	dk(  rd}t        d|¬«      ‚w xY w# t
        $ r ‚ t        $ r3}dt)        |«      › �}|	dk(  rdt)        |«      › �}t        d|¬«      ‚d }~ww xY w7 Œ›# t        $ r3}dt)        |«      › �}|	dk(  rdt)        |«      › �}t        d|¬«      ‚d }~ww xY w­w)Nr†   rh   rm   rr   rs   rt   ru   rv   ry   rz   rn   r{   zimage/zFile must be an imageu#   íŒŒì�¼ì�€ ì�´ë¯¸ì§€ì—¬ì•¼ í•©ë‹ˆë‹¤zInvalid image fileu#   ìž˜ëª»ë�œ ì�´ë¯¸ì§€ íŒŒì�¼ìž…ë‹ˆë‹¤éd   z1Image too small. Minimum 100x100 pixels required.uK   ì�´ë¯¸ì§€ê°€ ë„ˆë¬´ ìž‘ìŠµë‹ˆë‹¤. ìµœì†Œ 100x100 í”½ì…€ì�´ í•„ìš”í•©ë‹ˆë‹¤.ÚRGBzError processing image: u   ì�´ë¯¸ì§€ ì²˜ë¦¬ ì˜¤ë¥˜: )r]   r.   r^   rb   rc   rd   r†   rK   r˜   zFood scanning failed: u   ì�Œì‹� ìŠ¤ìº” ì‹¤íŒ¨: rš   )rX   r7   r@   rW   rA   r   Úcontent_typeÚ
startswithÚreadr   ÚopenÚioÚBytesIOÚverifyr�   Úwidthra   ÚmodeÚconvertÚcloser¡   Úfood_scannerÚscan_food_imager    rT   r   )rU   r]   r.   r^   rb   rd   rc   r†   r½   rF   r~   r   r€   Ú
image_dataÚimgr§   r�   Úscan_responser¥   r¦   s                       r6   Ú	scan_foodrÑ   g  sÉ  è ø€ ô )¨Ó1€HÜ% jÓ1€JØ—‘Ó!€Iñ Ø#×0Ñ0×4Ñ4Ð5HÓIÒQÈTÐâ-ÐÚHÐàÐ*Ñ*ØAˆ	Ø�tÒØ_ˆIÜ¨°IÔ>Ð>àÐ(Ñ(Ø]ˆ	Ø�tÒð TˆIÜ¨°IÔ>Ð>à�IÒØˆ	à×Ñ×(Ñ(¨Ô2Ø+ˆ	Ø�tÒØ=ˆIÜ¨°IÔ>Ð>ð?Ø Ÿ:™:›<×'ˆ
ð	CÜ—*‘*œRŸZ™Z¨
Ó3Ó4ˆCØ�J‰JŒLô �j‰jœŸ™ JÓ/Ó0ˆØ�9‰9�sŠ?˜cŸj™j¨3Ò.ØKˆIØ˜4ÒØi�	Ü¨C¸	ÔBÐBà�8‰8�uÒØ—+‘+˜eÓ$ˆCà�	‰	Œð Ø ØØØ&ØØ.ñ€Ið
?Ü*×:Ñ:¸:ÀyÓQ×QˆØ%×*Ñ*Ó,ˆÜ0°ÀÈ+ÓVÐÜÐ$7Ô8Ð8ð] (úô ò 	CØ,ˆIØ˜4ÒØA�	Ü¨C¸	ÔBÐBð		Cûô$ ò ØÜò ?Ø.¬s°1«v¨hÐ7ˆ	Ø�tÒØ3´C¸³F°8Ð<ˆIÜ¨°IÔ>Ð>ûð	?úð" Rùô
 ò ?Ø,¬S°«V¨HÐ5ˆ	Ø�tÒØ0´°Q³°Ð9ˆIÜ¨°IÔ>Ð>ûð	?üs‹   ‚B<JÂ?H ÃG.ÃH Ã8G1 ÄBH Æ
JÆ'I Ç IÇ,I Ç-JÇ.H Ç1 HÈH ÈIÈ&.IÉIÉJÉI É	JÉ'.JÊJÊJz/healthc              ƒ   ó  K  — t        | «      }t        j                  du}|r#t        t        j                  j                  «      nd}|rdnd}|dk(  r|rdnd}|d|||d	g d
¢dddddddœt        j                  «       dœ
S ­w)u6   Health check endpoint â€“ now uses vector store stats.Nr   ÚhealthyÚdegradedrs   u   ì •ìƒ�u	   ì €í•˜ë�¨úBloodFIT Meal Plan APIõA   9 meals per category (3 per subâ€‘category Ã— 3 subâ€‘categories)©zProtein-PackedzLight & FreshzHealthy & Comfortingé   z0Calculate daily nutrition with meal distributionu*   Generate 27â€‘meal plan with new structureu&   Swap meals with subâ€‘category supportzScan food imagesúGenerate meal images)z/meal/calculate-daily-nutritionz/meal/generate-meal-planz/meal/swap-mealz/meal/scan-foodz/meal/generate-meal-images)
ÚstatusÚservicerF   Úvector_store_loadedÚtotal_document_chunksÚnew_structureÚsub_categoriesÚtotal_meals_per_planÚ	endpointsÚtranslation_enabled)rX   Ú
meal_storeÚvectorstoreÚlenÚindex_to_docstore_idr    rN   )rU   rF   Úindex_loadedÚ	doc_countÚstatus_messages        r6   Úhealth_checkrê   Ì  sŸ   è ø€ ô )¨Ó1€Hô ×)Ñ)°Ð5€LÙDP””J×*Ñ*×?Ñ?Ô@ÐVW€Iá".‘Y°J€NØ�4ÒÙ%1™°{ˆð !Ø+ØØ+Ø!*Ø\ÚUØ "à/aØ(TØGØ1Ø*@ñ
ô  3×IÑIÓKñ!ð ùs   ‚A=A?Ú/c              ƒ   óz   K  — t        | «      }|dk(  rdddg d¢dddd	d
ddœg d¢dœS dddg d¢dddddddœg d¢dœS ­w)zAPI Documentationrs   u   BloodFIT ì‹�ë‹¨ ê³„íš� APIz3.0 (Vector Store)u`   ê°� ì¹´í…Œê³ ë¦¬ë‹¹ 9ê°œ ì‹�ì‚¬ ì˜µì…˜ (í•˜ìœ„ ì¹´í…Œê³ ë¦¬ë‹¹ 3ê°œ Ã— 3ê°œ í•˜ìœ„ ì¹´í…Œê³ ë¦¬))u   ë‹¨ë°±ì§ˆ í’�ë¶€u   ê°€ë³�ê³  ì‹ ì„ í•¨u   ê±´ê°•í•˜ê³  íŽ¸ì•ˆí•¨rØ   u   ì�¼ì�¼ ì˜�ì–‘ì†Œ ëª©í‘œ ê³„ì‚°u(   ìƒˆë¡œìš´ êµ¬ì¡°ë¡œ ì‹�ë‹¨ ê³„íš� ìƒ�ì„±u8   ë�™ì�¼í•œ í•˜ìœ„ ì¹´í…Œê³ ë¦¬ì—�ì„œ ëŒ€ì²´ ì‹�ì‚¬ ìƒ�ì„±u   ì�Œì‹� ì�´ë¯¸ì§€ ìŠ¤ìº”u   ì‹�ì‚¬ ì�´ë¯¸ì§€ ìƒ�ì„±)z#GET /meal/calculate-daily-nutritionzGET /meal/generate-meal-planzGET /meal/swap-mealzPOST /meal/scan-foodzPOST /meal/generate-meal-images)uN   1. /meal/calculate-daily-nutrition í˜¸ì¶œí•˜ì—¬ ì�¼ì�¼ ì˜�ì–‘ì†Œ ëª©í‘œ ê³„ì‚°uF   2. ê²°ê³¼ë¥¼ /meal/generate-meal-planì—� ì¿¼ë¦¬ ë§¤ê°œë³€ìˆ˜ë¡œ ì „ë‹¬uD   3. ë˜�ëŠ” /meal/generate-meal-plan ì§�ì ‘ í˜¸ì¶œí•˜ì—¬ ìž�ë�™ ê³„ì‚°)ÚmessageÚversionu   êµ¬ì¡°u   í•˜ìœ„_ì¹´í…Œê³ ë¦¬u   ì´�_ì‹�ì‚¬_ì˜µì…˜u   ì—”ë“œí�¬ì�¸íŠ¸u	   ì‚¬ìš©ë²•rÕ   rÖ   r×   z!Calculate daily nutrition targetsz%Generate meal plan with new structureu5   Generate alternative meals within same subâ€‘categoryz'Scan food image for harmful ingredientsrÙ   )zF1. Call /meal/calculate-daily-nutrition to get daily nutrition targetszF2. Pass the results to /meal/generate-meal-plan using query parameterszF3. Or call /meal/generate-meal-plan directly for automatic calculation)rí   rî   Ú	structurerß   Útotal_meal_optionsrá   Ú
usage_flow)rX   )rU   rF   s     r6   Úhomerò   í  s€   è ø€ ô )¨Ó1€Hà�4Òà3Ø+ØxÚ#hØ!#à7WØ0ZØ'aØ(AØ3Lñ òñ
ð 	
ð* 0Ø+Ø\ÚYØ"$à7ZØ0WØ'^Ø(QØ3Iñòñ
ð 	
ùs   ‚9;)rJ   )LÚosrÅ   ÚuvicornÚtypingr   Úfastapir   r   r   r   r   r	   r
   Úfastapi.responsesr   Úfastapi.middleware.corsr   Údotenvr   ÚPILr   r   Úslowapir   r   Úslowapi.utilr   Úslowapi.errorsr   Úfitness_app.vector_storer   r   Úfitness_app.data_managerr   r   r   r   r   r   r   r   Úfitness_app.ai_servicesr   r   r    ÚgetenvÚlimiterÚappÚstateÚadd_exception_handlerÚadd_middlewarerã   Úload_or_create_indexÚscanner_storer|   rÌ   r¡   r7   rD   r    rT   rX   rA   ÚlimitÚintÚfloatr}   Ú	api_routeÚboolrŸ   rL   Úpostr¼   rÑ   rê   rò   © r8   r6   Ú<module>r     sš  ðÛ 	Û 	Û Ý ß R× RÑ RÝ *Ý 2Ý Ý Ý ß 9Ý +Ý ,÷ L÷÷ ó ÷
 KÝ 3á „á
Ð-¸9¸2¿9¹9À[ÐRjÓ;kÔ
l€ÙÐAÔB€Ø€‡	�	Ô Ø × Ñ Ð+Ð-IÔ Jà × Ñ ØØ�%ØØ�%Ø�%ð ô ñ  ¨?Ô;€
Ø 
× Ñ Ð IÐY^Ð Ô _á"¨oÔ>€Ø × "Ñ "Ð#IÐY^Ð "Ô _á*¨:Ó6€Ù˜=Ó)€ð
2 Sð 2¨Só 2ð
W¨ð 
W°ó 
Wñ dð °cð È#ð Ð`dó ð 6 wð 6°3ó 6ð ‡�Ð	%Ð6L€ÓMØ‡�ˆ{Óñ ˜“:Ù˜C“jÙ˜3“ZÙ˜t›Ù# D›kÙ# D›kÙ˜“9Ù˜r›Ù˜2“YÙ$ ZÓ0Ù&+¨D°Q¸3Ô&?ñ3Øð3àð3ð ð3ð ð	3ð
 
�#‰ð3ð �U‰Oð3ð �U‰Oð3ð ð3ð ð3ð ð3ð ˜‰}ð3ð ˜U‘Oò3ó ó Nð3ðl ‡�Ð$¨u°f¨oÐN^€Ó_Ø‡�ˆ{Óñ ˜“:Ù˜C“jÙ˜3“ZÙ˜t›Ù# D›kÙ# D›kÙ˜“9Ù˜r›Ù˜2“YÙ',¨T£{Ù*/°«+Ù" 4›[Ù$ T›{Ù  ›;Ù(-¨d«Ù$)¨$£KÙ%*¨4£[Ù! %›LÙ$ ZÓ0ñ)j?Øðj?àðj?ð ðj?ð ð	j?ð
 
�#‰ðj?ð �U‰Oðj?ð �U‰Oðj?ð ðj?ð ðj?ð ðj?ð   ‘}ðj?ð # 3™-ðj?ð �E‰?ðj?ð �e‰_ðj?ð 
�%‰ðj?ð  ! ™ð!j?ð" ˜S‘Mð#j?ð$ ˜c‘]ð%j?ð& ð'j?ð( ˜‰}ò)j?ó ó `ðj?ðZ ‡�ˆÐ&6€Ó7Ø‡�ˆ{Óñ ˜“:Ù˜C“jÙ˜3“ZÙ˜#“JÙ˜c›
Ù! #›JÙ˜“9Ù˜r›Ù˜2“YÙ! %›Lñ<?Øð<?àð<?ð ð<?ð ð	<?ð
 ð<?ð ð<?ð ð<?ð ð<?ð ð<?ð ð<?ð ò<?ó ó 8ð<?ð~ ‡�Ð
!Ð2C€ÓDØ‡�ˆ{Óð?Øð?à"ò?ó ó Eð?ð> ‡�ˆ,Ð'7€Ó8Ø‡�ˆ{Óñ ˜“:Ù˜C“jÙ˜3“ZÙ˜“9Ù˜2“YÙ˜r›Ù'+¨D£zÙ˜S›	ñ`?Øð`?àð`?ð ð`?ð ð	`?ð
 ð`?ð ð`?ð ð`?ð   ‘}ð`?ð ò`?ó ó 9ð`?ðF ‡�ˆÓð ò ó ðð@ ‡�ˆƒð+
˜ò +
ó ñ+
r8   