Ë
    ØÎŽjÑ_ ã                   ó¸  — U d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl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Zd d	lmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z% d d
l&m'Z'm(Z(  e«         ejR                  d«      Z* ejR                  d«      Z+ ejX                  dejZ                  «      Z.de/de/fd„Z0de/de/fd„Z1dUde
de2de/fd„Z3	 	 	 	 dVde/dee/   de/fd„Z4de/de/fd„Z5de
e	   de	e/e/f   fd„Z6de/de	e/e/f   dee/   fd„Z7de	de	e/e/f   de	fd „Z8d!d"d#d$œZ9e	e/e2f   e:d%<   h d&£Z;d'e	d(e/de<fd)„Z=	 dWd*e
e	   d+e2d(e/d,ee>   de
e	   f
d-„Z?g d.¢g d/¢g d0¢d1d2gg d3¢d4œZ@e	e/e
e/   f   e:d5<   g d6¢g d7¢g d7¢d8œZAe	e/e
e/   f   e:d9<   d:d;d<d=d>d4œZBd#d?d?d@dAd4œZCe	e/e2f   e:dB<   d*e
e	   dCe/de
e	   fdD„ZDdEe
e	   dFe
e	   d(e/dGe	e/e2f   dHe>dee	e/e
e	   f   e>f   fdI„ZEdJe	e/e
e	   f   d(e/de/fdK„ZFdEe
e	   dFe
e	   dee/e	e/e/f   f   fdL„ZGdEe
e	   dFe
e	   d(e/dee/e	e/e/f   f   fdM„ZHdXde
e	   de2de/fdN„ZI G dO„ dP«      ZJ G dQ„ dR«      ZK G dS„ dT«      ZLy)Yé    N)Údatetime)ÚDictÚListÚOptionalÚTuple)ÚHTTPException)Ú
ChatOpenAI)ÚChatPromptTemplate)ÚOpenAI)Úload_dotenv)ÚMealÚMealPlanResponseÚSwapMealResponseÚFoodScanResponseÚHarmfulIngredientÚSafeIngredientÚNeutralIngredientÚ
IngredientÚMacronutrientsÚDailyNutritionResponseÚSwapMealRequestÚFoodTypeInfoÚfood_types_for_scan)ÚMealGenVectorStoreÚScannerVectorStoreéô  éd   u»   \b(grilled|roasted|baked|fried|steamed|fresh|smoked|saut[eÃ©]ed|pan[-\s]seared|boiled|raw|cooked|diced|sliced|chopped|minced|shredded|whole|dried|canned|frozen|organic|lean|light|dark)\s+Ú
blood_typeÚreturnc                 ó¸   — | sy| j                  «       j                  «       j                  d«      d   j                  d«      d   j                  «       }|dv r|S dS )NÚOÚ+r   Ú-)r!   ÚAÚBÚAB)ÚstripÚupperÚsplit)r   Úcleaneds     ú?/var/www/html/Fitness-lenito-AI-main/fitness_app/ai_services.pyÚ_normalize_blood_typer,   +   s[   € ÙØØ×ÑÓ ×&Ñ&Ó(×.Ñ.¨sÓ3°AÑ6×<Ñ<¸SÓAÀ!ÑD×JÑJÓL€GØÐ!6Ñ6ˆ7Ð?¸CÐ?ó    Ú	diet_typec                 óv   — | sydddddddœ}|j                  | j                  «       j                  «       d«      S )NÚstandardÚveganÚpescatarianÚ
vegetarianÚ	carnivore)Úclassicr0   r1   r2   r3   r4   )Úgetr'   Úlower)r.   Úmappings     r+   Ú_normalize_diet_typer9   2   sA   € ÙØà¨:Ø¨Ø"°ñ€Gð
 �;‰;�y—‘Ó(×.Ñ.Ó0°*Ó=Ð=r-   ÚitemsÚ	max_itemsc                 óú   — | syg }| d| D ]Z  }t        |t        «      r)|j                  d«      xs |j                  d«      xs d}nt        |«      }|sŒJ|j	                  |«       Œ\ |rdj                  |«      S dS )zBFormat food names from str list or dict list for prompt injection.úNone providedNÚ	food_nameÚnameÚ ú, )Ú
isinstanceÚdictr6   ÚstrÚappendÚjoin)r:   r;   ÚnamesÚitemr?   s        r+   Ú_food_namesrI   =   sy   € áØØ€EØ�j�yÓ!ˆÜ�dœDÔ!Ø—8‘8˜KÓ(ÒB¨D¯H©H°VÓ,<ÒBÀ‰Dä�t“9ˆDÚØ�L‰L˜Õð "ñ  %ˆ4�9‰9�UÓÐ9¨/Ð9r-   Úclient_rulesc                 óÜ   — |r2t        |«      j                  «       rt        |«      j                  «       S d| › dt        |xs g «      › dt        |xs g «      › dt        |xs g «      › d| › d�S )zÐ
    Build blood-group diet rules for LLM prompts.
    If the client already sent blood_group_rules (FormData / query), use that.
    Otherwise build from vector-store beneficial / neutral / avoid lists.
    zBlood Type zQ diet rules (ground truth from our food database):
- Beneficial (prefer / safe): z
- Neutral (allowed): z'
- Avoid (do not recommend / harmful): zN
Prefer beneficial foods, allow neutral, never use avoid foods for blood type Ú.)rD   r'   rI   ©r   Ú
beneficialÚneutralÚavoidrJ   s        r+   Úformat_blood_group_rulesrQ   L   s�   € ñ œ˜LÓ)×/Ñ/Ô1Ü�<Ó ×&Ñ&Ó(Ð(ð �j�\ð ")Ü)4°ZÒ5EÀ2Ó)FÐ(Gð H Ü +¨GªM°rÓ :Ð;ð <1Ü1<¸Uº[ÀbÓ1IÐ0Jð KXØXbÐWcÐcdð		fðr-   r?   c                 óJ   — t         j                  d| «      j                  «       S )u-   'grilled Chicken Breast' â†’ 'Chicken Breast'r@   )Ú_COOKING_ADJÚsubr'   ©r?   s    r+   Ú_strip_cooking_adjectivesrV   g   s   € ä×Ñ˜B Ó%×+Ñ+Ó-Ð-r-   Ú
food_dictsc                 óh   — i }| D ]*  }|j                  dd«      }|sŒ|||j                  «       <   Œ, |S )z�
    Build {lowercase_name: exact_db_name} from a list of food dicts.
    Used for post-generation normalisation of LLM ingredient output.
    r>   r@   ©r6   r7   )rW   ÚlookupÚfr?   s       r+   Ú_build_name_lookupr\   l   s=   € ð
  €FÛˆØ�u‰u�[ "Ó%ˆÚØ#'ˆF�4—:‘:“<Ò ð ð €Mr-   Ú
ingredientrZ   c                 óä   — t        | «      j                  «       j                  «       }||v r||   S |j                  «       D ]  \  }}||v sŒ|c S  |j                  «       D ]  \  }}||v sŒ|c S  y)zù
    Try to map an LLM-output ingredient string to the exact DB name.
    1. Strip cooking adjectives, exact match.
    2. Substring match (DB name inside ingredient, or ingredient inside DB name).
    Returns exact DB name if found, else None.
    N)rV   r7   r'   r:   )r]   rZ   r*   r7   Úoriginals        r+   Ú_match_to_db_namer`   y   s   € ô (¨
Ó3×9Ñ9Ó;×AÑAÓC€Gð �&ÑØ�g‰Ðð "Ÿ<™<ž>‰ˆˆxØ�GÒØŠOð *ð
 "Ÿ<™<ž>‰ˆˆxØ�eÒØŠOð *ð r-   Ú	meal_dictc           	      óð   — g }| j                  dg «      D ]Y  }|j                  dd«      }t        ||«      }|j                  |r|n||j                  dd«      |j                  dd«      dœ«       Œ[ || d<   | S )z’
    Walk through a meal's ingredient list and replace each name with the
    exact DB name where possible.  Quantity and icon are preserved.
    Úingredientsr?   r@   ÚquantityÚiconõ   ðŸ�½ï¸�©r?   rd   re   )r6   r`   rE   )ra   rZ   Únew_ingredientsÚingÚraw_nameÚdb_names         r+   Ú_normalise_meal_ingredientsrl   “   s‚   € ð €OØ�}‰}˜]¨BÖ/ˆØ—7‘7˜6 2Ó&ˆÜ$ X¨vÓ6ˆØ×ÑÙ#*™°ØŸ™ 
¨BÓ/ØŸ™ ¨	Ó2ñ 
õ 	ð 0ð  /€IˆmÑØÐr-   éF   é   é
   )ÚHighÚMediumÚLowÚPRIORITY_WEIGHTS>   rr   rp   rq   ÚfoodÚ	meal_timec                 óF   — | j                  |j                  «       d«      dv S )Nrq   >   rp   rq   rY   )rt   ru   s     r+   Ú_is_eligible_for_mealrw   ¯   s    € à�8‰8�I—O‘OÓ% xÓ0Ð4FÐFÐFr-   ÚfoodsÚnÚ
used_namesc                 óÂ  — |€
t        «       }| D �cg c]2  }t        ||«      r$|j                  dd«      j                  «       |vr|‘Œ4 }}t	        |«      |k  rS| D �cg c]H  }|j                  |j                  «       d«      dv r$|j                  dd«      j                  «       |vr|‘ŒJ }}t	        |«      |k  r1| D �cg c]&  }|j                  |j                  «       d«      dv r|‘Œ( }}|D �cg c]  }|j                  dd«      dv sŒ|‘Œ }}|D �cg c]  }|j                  dd«      dk(  sŒ|‘Œ }}g }t	        |«      |k\  r³t        |«      }	|	D �cg c]  }t        j                  |d   d«      ‘Œ }
}|	�rGt	        |«      |k  �r8t        j                  t        t	        |	«      «      |
d	¬
«      d   }|j                  |	j                  |«      «       |
j                  |«       |	rØt	        |«      |k  rŒonÈ|j                  |«       |t	        |«      z
  }|r§|dkD  r¢t        |«      }	t        d   gt	        |	«      z  }
t        t        |t	        |	«      «      «      D ]`  }t        j                  t        t	        |	«      «      |
d	¬
«      d   }|j                  |	j                  |«      «       |
j                  |«       Œb |d | S c c}w c c}w c c}w c c}w c c}w c c}w )Nr>   r@   rq   >   rr   rp   rq   Úpriority>   rp   rq   rr   rn   é   )ÚweightsÚkr   )Úsetrw   r6   r7   ÚlenÚlistrs   ÚrandomÚchoicesÚrangerE   ÚpopÚextendÚmin)rx   ry   ru   rz   r[   ÚeligibleÚhigh_medÚlowÚresultÚpoolr~   ÚidxÚ	remainingÚ_s                 r+   Ú_weighted_sample_no_replacer‘   ´   s¾  € ð ÐÜ“Uˆ
ñ óÙˆaÜ   IÔ.Ø�E‰E�+˜rÓ"×(Ñ(Ó*°*Ñ<ò 	
�5ð ð ô ˆ8ƒ}�qÒáó
Ù�!Ø�u‰u�Y—_‘_Ó&¨Ó1Ð5NÑNØ—‘�k 2Ó&×,Ñ,Ó.°jÑ@ò �uð 	ð 
ô ˆ8ƒ}�qÒáó
Ù�!Ø�u‰u�Y—_‘_Ó&¨Ó1Ð5NÑNò �uð 	ð 
ñ $ÓY™8�a q§u¡u¨Z¸Ó'BÐFXÒ'X’˜8€HÐYÙ#ÓL™8�a q§u¡u¨Z¸Ó'BÀeÓ'K’˜8€CÐLà€Fô ˆ8ƒ}˜ÒÜ�H‹~ˆÙDHÓIÁD¸qÔ#×'Ñ'¨¨*©°rÕ:ÀDˆÐIÚ”s˜6“{ Q“Ü—.‘.¤¤s¨4£yÓ!1¸7ÀaÔHÈÑKˆCØ�M‰M˜$Ÿ(™( 3›-Ô(Ø�K‰K˜Ôñ ”s˜6“{ Q”ð
 	�‰�hÔØœ˜H›Ñ%ˆ	ñ �9˜q’=Ü˜“9ˆDÜ'¨Ñ.Ð/´#°d³)Ñ;ˆGÜœ3˜y¬#¨d«)Ó4Ö5�Ü—n‘n¤U¬3¨t«9Ó%5¸wÈ!ÔLÈQÑO�Ø—‘˜dŸh™h s›mÔ,Ø—‘˜CÕ ð 6ð
 �"�1ˆ:Ðùòaùò
ùò
ùò ZùÚLùò Js0   ‘7KÁAKÂ=+KÃ.KÄKÄKÄ-KÅ K)ÚProteinÚSeafoodzDairy / ProteinúCarb / ProteinzLegume / ProteinÚDairy)ÚCarbzCarb / Legumez
Carb / NutzLegume / CarbúCarb / VegetableúVegetable / Carbr”   )Ú	Vegetabler˜   r—   zVegetable / cornÚFruitzFruit / Seasoning)z	Fat / Nutz
Fat / SeedzFat / Spreadz	Fat / OilzFat / Dairy)r’   ÚCarbsÚ
VegetablesÚFruitsÚFatsÚ_CATEGORY_ALIASES)r’   r›   r�   rž   ©r’   r›   rœ   rž   ©Ú	breakfastÚlunchÚdinnerÚ_MEAL_CATEGORIESé   é   é   é   é   é   é   é   Ú_SWAP_POOL_SIZESÚlogicalc                 ó–   — t        t        j                  ||g«      «      }| D �cg c]  }|j                  dd«      |v sŒ|‘Œ c}S c c}w )zJReturn foods whose DB category matches any alias for the logical category.Úcategoryr@   )r€   rŸ   r6   )rx   r¯   Úaliasesr[   s       r+   Ú_filter_by_logical_categoryr³     sF   € äÔ#×'Ñ'¨°'°Ó;Ó<€GÙÓA‘u�! §¡ j°"Ó 5¸Ò @ŠA�uÑAÐAùÒAs
   ¥A¿ArN   rO   Ú
pool_sizesÚused_globallyc                 óô  — t         j                  |j                  «       g d¢«      }i }t        |«      }| D �ch c]"  }|j                  dd«      j                  «       ’Œ$ }	}|D �]
  }
|j                  |
d«      }t	        dt        |dz  «      «      }t	        d||z
  «      }t        | |
«      }t        ||
«      }t        |«      |k  r||t        |«      z
  z  }t        |«      }t        ||||«      }t        ||||«      }||z   }|D ]+  }|j                  dd«      j                  «       |	v rdnd|d	<   Œ- |||
<   |D ]1  }|j                  |j                  dd«      j                  «       «       Œ3 �Œ ||fS c c}w )
z»
    For each required category, draw foods using priority-weighted sampling.
    Returns (selected_by_category, updated_used_names).
    70% drawn from beneficial, 30% from neutral.
    r    r>   r@   é   r}   çffffffæ?Ú
BeneficialÚNeutralÚ_compat)
r¥   r6   r7   r€   ÚmaxÚroundr³   r�   r‘   Úadd)rN   rO   ru   r´   rµ   Ú
categoriesÚselectedÚused_this_mealr[   Ú	ben_namesÚcatÚtotal_nÚn_benÚn_neuÚben_catÚneu_catÚsel_benÚsel_neuÚcombineds                      r+   Ú_select_pool_for_mealrÌ     sy  € ô "×%Ñ% i§o¡oÓ&7Ò9cÓd€JØ&(€HÜ˜Ó'€Ná9CÓD¹°A�—‘�{ BÓ'×-Ñ-Õ/¸€IÐDäˆØ—.‘.  aÓ(ˆÜ�aœ˜w¨™~Ó.Ó/ˆÜ�a˜ 5™Ó)ˆä-¨j¸#Ó>ˆÜ-¨g°sÓ;ˆäˆw‹<˜%ÒØ�UœS ›\Ñ)Ñ)ˆEÜ˜“LˆEä-¨g°u¸iÈÓXˆÜ-¨g°u¸iÈÓXˆà˜WÑ$ˆãˆAØ+,¯5©5°¸bÓ+A×+GÑ+GÓ+IÈYÑ+V™<Ð\eˆAˆiŠLð ð !ˆ�‰ÛˆAØ×Ñ˜qŸu™u [°"Ó5×;Ñ;Ó=Õ>ò ð+ ð0 �^Ð#Ð#ùò5 Es   ¸'E5rÀ   c           
      óÈ  — d|j                  «       › d�dddddg}| j                  «       D ]¥  \  }}|sŒ	|j                  d|j                  «       › d	�«       |D ]d  }|j                  d
d«      }|j                  dd«      }|j                  dd«      }|dk(  rdnd}	|dk(  rdnd}
|j                  d|	› d|
› d|› �«       Œf |j                  d«       Œ§ dj	                  |«      S )z˜
    Format the pre-selected pool into a compact, unambiguous prompt block.
    Lists EXACT food names from the DB. LLM must use these exact names.
    z=== PRE-SELECTED FOOD POOL FOR z ===zJRULE: Use ONLY the EXACT food names listed below in your ingredient lists.uV         â˜…â˜… = High priority (use as primary ingredient, ~70% of calorie contribution)u<         â˜…  = Medium priority (supporting/variety role, ~30%)z4      [B] = Beneficial for blood type  [N] = Neutralr@   z  [Ú]r>   r|   rq   r»   rº   rp   u   â˜…â˜…u   â˜… r¹   r%   ÚNz    z [z] Ú
)r(   r:   rE   r6   rF   )rÀ   ru   ÚlinesrÃ   rx   r[   r?   r|   ÚcompatÚtagÚcts              r+   Ú_format_pool_for_promptrÕ   I  sú   € ð *¨)¯/©/Ó*;Ð)<¸DÐAØTØ`ØFØ>Ø
ð€Eð —n‘nÖ&‰
ˆˆUÙØØ�‰�s˜3Ÿ9™9›;˜- qÐ)Ô*ÛˆAØ—u‘u˜[¨"Ó-ˆDØ—u‘u˜Z¨Ó2ˆHØ—u‘u˜Y¨	Ó2ˆFØ#+¨vÒ#5‘x¸6ˆCØ$¨Ò4‘s¸#ˆBØ�L‰L˜4 ˜u B r d¨"¨T¨FÐ3Õ4ð ð 	�‰�RÕð 'ð �9‰9�UÓÐr-   c           	      ó–  — g }t        «       }dD ]–  }t        | ||t        |«      \  }}|j                  t	        ||«      «       |j                  «       D ]P  \  }}|D ]F  }	|	j                  d«      dk(  sŒ|j                  |	j                  dd«      j                  «       «       ŒH ŒR Œ˜ | |z   }
t        |
«      }dj                  |«      |fS )z‘
    Build the food database string for the full 27-meal plan prompt.
    Also returns a name lookup dict for post-generation normalisation.
    r¡   r|   rp   r>   r@   z

)r€   rÌ   Ú_POOL_SIZESrE   rÕ   r:   r6   r¾   r7   r\   rF   )rN   rO   Úsectionsrµ   ru   rÀ   Ú
used_afterrÃ   rx   r[   Ú	all_foodsÚname_lookups               r+   Ú_build_full_plan_databaserÜ   h  sÆ   € ð €HÜ›€Mã5ˆ	Ü4Ø˜ ¬K¸ó 
Ñˆ�*ð 	�‰Ô/°¸)ÓDÔEà"Ÿ.™.Ö*‰JˆC�Û�Ø—5‘5˜Ó$¨Ó.Ø!×%Ñ% a§e¡e¨K¸Ó&<×&BÑ&BÓ&DÕEñ ñ +ð 6ð  Ñ'€IÜ% iÓ0€KØ�;‰;�xÓ  +Ð-Ð-r-   c                 óz   — t        | ||t        t        «       «      \  }}| |z   }t        |«      }t	        ||«      |fS )zx
    Build the food database for a swap-meal prompt (single meal time).
    Returns (database_string, name_lookup).
    )rÌ   r®   r€   r\   rÕ   )rN   rO   ru   rÀ   r�   rÚ   rÛ   s          r+   Ú_build_swap_databaserÞ   ƒ  sH   € ô (Ø�G˜YÔ(8¼#»%ó�K€Hˆað ˜wÑ&€IÜ$ YÓ/€KÜ" 8¨YÓ7¸ÐDÐDr-   c                 ó>   — | sydj                  d„ | d | D «       «      S )NÚNonerÐ   c              3   ó~   K  — | ]5  }t        |t        «      rd |d   › d|j                  dd«      › d�nd |› �–— Œ7 y­w)u   â€¢ r>   z (r±   r@   Ú)N)rB   rC   r6   )Ú.0r[   s     r+   Ú	<genexpr>z,_format_food_list_bullets.<locals>.<genexpr>š  sT   è ø€ ð ñ (ˆAô �aœÔð ˆq�‰~Ð˜b §¡ z°2Ó!6Ð 7°qÑ9Ø&*¨1¨# Jó	/á'ùs   ‚;=©rF   )rW   r;   s     r+   Ú_format_food_list_bulletsræ   —  s/   € ÙØØ�9‰9ñ ð ˜J˜YÑ'óó ð r-   c                   ó,   — e Zd Zd„ Zdd„Zd„ Zd„ Zd„ Zy)ÚMealImageGeneratorc                 óL   — t        t        j                  d«      ¬«      | _        y )NÚOPENAI_API_KEY)Úapi_key)r   ÚosÚgetenvÚclient)Úselfs    r+   Ú__init__zMealImageGenerator.__init__¥  s   € Ü¤R§Y¡YÐ/?Ó%@ÔAˆ�r-   c                 ó¼   — dj                  d„ |D «       «      }d|› d|› d|› d�}	 | j                  |«      S # t        $ r}t        d|› d|› �«       Y d }~y d }~ww xY w)	NrA   c              3   ój   K  — | ]+  }|j                  d d«      › d|j                  dd«      › �–— Œ- y­w)rd   ÚsomeÚ r?   r@   N)r6   )rã   Úis     r+   rä   z9MealImageGenerator.generate_meal_image.<locals>.<genexpr>©  s7   è ø€ ð $
ÙFQÀˆq�u‰u�Z Ó'Ð(¨¨!¯%©%°°rÓ*:Ð);Ô<Ákùs   ‚13z"Professional food photography of: z. Description: z. Ingredients: zg. Style: High-quality restaurant presentation, natural lighting, appetizing. No text, labels, or logos.zImage gen failed for ú: )rF   Ú_generate_imageÚ	ExceptionÚprint)rï   Ú	meal_nameÚdescriptionrc   Úsub_categoryÚingredient_listÚpromptÚes           r+   Úgenerate_meal_imagez&MealImageGenerator.generate_meal_image¨  s†   € ØŸ)™)ñ $
ÙFQó$
ó 
ˆð 1°°ð <Ø'˜=¨¸Ð7Hð I)ð)ð 	ð	Ø×'Ñ'¨Ó/Ð/øÜò 	ÜÐ)¨)¨°B°q°cÐ:Ô;Üûð	ús   ¦7 ·	AÁ AÁAc                 ó†   — | j                   j                  j                  d|dd¬«      }|j                  d   j                  S )Núgpt-image-1.5Ú	1024x1024r‹   ©Úmodelrþ   ÚsizeÚqualityr   )rî   ÚimagesÚgenerateÚdataÚb64_json)rï   rþ   Úrs      r+   r÷   z"MealImageGenerator._generate_image¸  s@   € Ø�K‰K×Ñ×'Ñ'Ø!¨&°{ÈEð (ó 
ˆð �v‰v�a‰y×!Ñ!Ð!r-   c                 ó  — 	 |› d|› d�}| j                   j                  j                  d|d d dd¬«      }|j                  d   j                  S # t
        $ r,}t        d	|› d
|› �«       | j                  |«      cY d }~S d }~ww xY w)Nz Category: zV. Style: Professional food photography, clean presentation. No text, labels, or logos.r  iè  r  r‹   r  r   zCategory image failed for rö   )rî   r  r	  r
  r  rø   rù   Ú generate_fallback_category_image)rï   r±   rþ   Ú
meals_dictÚenhancedr  rÿ   s          r+   Úgenerate_category_imagez*MealImageGenerator.generate_category_image¾  s¢   € ð	Cà�(˜+ h Zð 0-ð -ð ð
 —‘×"Ñ"×+Ñ+Ø%¨h°u¸¨oØ ¨%ð ,ó ˆAð —6‘6˜!‘9×%Ñ%Ð%øÜò 	CÜÐ.¨x¨j¸¸1¸#Ð>Ô?Ø×8Ñ8¸ÓBÕBûð	Cús   ‚AA Á	BÁ!A?Á9BÁ?Bc                 ó  — ddddœ}|j                  |j                  «       d«      }	 | j                  j                  j	                  d|dd¬	«      }|j
                  d
   j                  S # t        $ r}t        d|› �«       Y d }~y d }~ww xY w)NzQBeautiful breakfast spread, clean white background, professional food photographyzIAppetizing lunch plate, clean presentation, professional food photographyzGDelicious dinner, elegant plating, professional restaurant presentationr¡   z0Professional food photography of a balanced mealr  r  r‹   r  r   zFallback image failed: )	r6   r7   rî   r  r	  r
  r  rø   rù   )rï   r±   Úpromptsrþ   r  rÿ   s         r+   r  z3MealImageGenerator.generate_fallback_category_imageÎ  s“   € àlØdØbñ
ˆð
 —‘˜XŸ^™^Ó-Ð/aÓbˆð	Ø—‘×"Ñ"×+Ñ+Ø%¨f¸;ÐPUð ,ó ˆAð —6‘6˜!‘9×%Ñ%Ð%øÜò 	ÜÐ+¨A¨3Ð/Ô0Üûð	ús   ¨AA* Á*	BÁ3BÂBN)r@   )Ú__name__Ú
__module__Ú__qualname__rð   r   r÷   r  r  © r-   r+   rè   rè   ¤  s   „ òBóò "òCó r-   rè   c            	       ó6  — e Zd Zddee   fd„Zededefd„«       Zededefd„«       Z	ede
fd	„«       Zed
edefd„«       Zd„ Zd„ Zd„ Zdedefd„Z	 	 ddedee   dedefd„Z	 ddededefd„Zdd„Zdeeee   f   deeee   f   fd„Zdee   dee   fd„Zy)ÚEnhancedMealPlanGeneratorNÚvector_storec                 ód  — t        ddt        j                  d«      ¬«      | _        |xs
 t	        «       | _        t        «       | _        t        j                  d«      | _
        t        j                  d«      | _        t        j                  d«      | _        t        j                  d«      | _        y )	Núgpt-4or¸   rê   ©r  Útemperaturerë   a  
        You are an expert food photographer. Create a single image prompt representing {category} meals.
        MEAL SUMMARY: {meal_options_summary}
        USER: Blood Type {blood_type}, Diet {diet_type}, Country {country}
        Return ONLY the image prompt text.
        u3  
        You are an expert nutritionist specialising in blood type diets. Calculate the optimal daily calorie intake, macronutrient distribution, and meal calorie distribution.

        USER PROFILE:
        - Blood Type: {blood_type}
        - Diet Type: {diet_type}
        - Country: {country}
        - Age: {age} years
        - Current Weight: {weight} kg
        - Desired Weight: {desired_weight} kg
        - Height: {height} cm
        - Main Goal: {main_goal}

        CALORIE DISTRIBUTION GUIDELINES:
        Breakfast 25%, Lunch 40%, Dinner 35%

        BLOOD TYPE MACRONUTRIENT GUIDELINES:
        - O:  Protein 30-40%, Fat 30-35%, Carbs 25-35%
        - A:  Protein 15-25%, Fat 25-30%, Carbs 45-60%
        - B:  Balanced (Carbs 30-40%, Protein 20-30%, Fat 30-35%)
        - AB: Similar to A but slightly more protein (20-30%)

        DIET ADJUSTMENTS:
        - Vegan: plant-based protein sources
        - Carnivore: Protein 50-60%, Fat 40-50%, minimal carbs
        - Pescatarian: moderate protein from fish, balanced macros
        - Vegetarian: plant-based protein with dairy/eggs

        If desired_weight is provided, adjust calories for 0.5-1 kg/week loss or 0.25-0.5 kg/week gain.

        Respond ONLY with valid JSON:
        {{
            "total_daily_calories": number,
            "total_daily_macronutrients": {{"carbohydrates": number, "protein": number, "fat": number}},
            "meal_calorie_distribution": {{"breakfast": number, "lunch": number, "dinner": number}}
        }}
        carbs*4 + protein*4 + fat*9 â‰ˆ total_daily_calories.
        us?  
        You are an expert nutritionist specialising in blood type diets.
        Generate a personalised daily meal plan with 3 subâ€‘categories per meal Ã— 3 options = 27 meals total.

        USER PROFILE:
        - Blood Type: {blood_type}  |  Diet: {diet_type}  |  Country: {country}
        - Age: {age}  |  Weight: {weight} kg  |  Height: {height} cm
        - Dislikes: {food_dislikes}  |  Allergies: {allergies}
        - Target Daily Calories: {target_calories}  |  Macros: {total_daily_macronutrients}
        - Goal: {main_goal}

        â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�
        BLOOD GROUP RULES (must follow)
        â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�
        {blood_group_rules}
        â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�

        â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�
        BACKEND PREâ€‘SELECTED FOOD POOL
        â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�
        {food_database}
        â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        ABSOLUTE RULES (must be followed for every single meal)
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�

        1. INGREDIENT RULES
        a. Use ONLY the EXACT food names from the pool above. Copy them characterâ€‘forâ€‘case.
        b. DO NOT add any ingredient not in the pool â€“ no salt, pepper, oil, water, spices,
            herbs, sauces, stock, etc., unless it is explicitly listed in the pool.
        c. List EVERY ingredient you use in the `ingredients` array.
        d. The 3 meals within a subâ€‘category must use a different primary protein/carb source.
            Do not repeat the exact same ingredient combination.

        2. PRIORITY RULES
        â˜…â˜… High priority â†’ primary ingredient (~70 % of the meal's calories).
        â˜…  Medium priority â†’ supporting role (~30 % of calories).
        You may repeat a highâ€‘priority protein across different meals if it naturally fits;
        aim for variety in carb sources, vegetables, cooking styles and meal names.

        3. CALORIE RANGES (VARY NATURALLY)
        Breakfast meals: each between {breakfast_cal_min} and {breakfast_cal_max} kcal(use any number which is within the range and look natural).
        Lunch meals:     each between {lunch_cal_min} and {lunch_cal_max} kcal(use any number which is within the range and look natural).
        Dinner meals:    each between {dinner_cal_min} and {dinner_cal_max} kcal(use any number which is within the range and look natural).
        âš  Do NOT make all meals in a mealâ€‘time identical in calories. Vary them naturally
            across the 9 options, keeping each within its range. The numbers needs to vary across the 3 subâ€‘categories and 3 options and needs to use variety of different calorie values within each one range, not the same repeated.
                                                                 
        4. CALORIE MATHS
        total_calories = (carbohydrates Ã— 4) + (protein Ã— 4) + (fat Ã— 9)
        Must equal the stated calorie value.
        Every ingredient must have a quantity in grams (g) or millilitres (ml).
        The macronutrient totals must be the sum of the listed ingredients.

        5. PORTION ADJUSTMENT ORDER (when tuning to hit target)
        Adjust in this strict order: â‘  carbs â†’ â‘¡ protein â†’ â‘¢ fats/oils/seeds.
        Never add an ingredient that is not already present just to hit numbers.

        6. COUNTRY CONTEXT
        {country_guidance}

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        BANNED MEAL TYPES (NEVER generate these)
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Do NOT generate any of the following meal types under any circumstances:
        - Wraps, Burritos, Tacos
        - Rice Bowls, Quinoa Bowls, Comfort Bowls, Power Bowls, Protein Bowls, Noodle Bowls
        - Any meal named or structured as a "Bowl" of any kind
        The goal is realistic plated meals, not trendy bowl/wrap formats.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        MEAL NAMING RULES
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Meal names must describe the actual food being served.
        âœ“ GOOD names: "Grilled Salmon with Rice & Broccoli", "Steak with Sweet Potato & Asparagus",
                      "Shrimp Stir Fry", "Blueberry Oatmeal", "Scrambled Eggs with Spinach"
        âœ— BAD names:  "Comfort Bowl", "Power Bowl", "Protein Packed Bowl", "Energy Bowl",
                      "Light & Fresh Bowl", "Nourish Bowl", "Wellness Plate"
        The name must reflect the protein, cooking method, and key ingredients.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        BREAKFAST TEMPLATES â€“ CHOOSE ONE STYLE PER MEAL
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Every breakfast meal must belong to exactly ONE of the four templates below.
        NEVER mix ingredients from different templates in the same meal.

        Target breakfast distribution across the 9 breakfast meals:
        ~30% Oatmeal (â‰ˆ3 meals) | ~30% Yogurt Bowls (â‰ˆ3 meals) | ~30% Egg-Based (â‰ˆ3 meals) | ~10% Other Approved

        â–  OATMEAL BREAKFAST
        Must contain: oats + at least 1 fruit + at least 1 approved topping.
        Approved toppings (only if in pool): Honey, Cinnamon, Walnuts, Almonds, Chia Seeds,
            Pumpkin Seeds, Flax Seeds.
        FORBIDDEN: fish, meat, eggs, rice, noodles, savoury proteins, random oils.
        Example: Oats + Blueberries + Walnuts + Honey â†’ "Blueberry Walnut Oatmeal"

        â–  YOGURT BOWL BREAKFAST
        Must contain: yogurt + at least 1 fruit + at least 1 approved topping.
        Approved toppings (only if in pool): Honey, Walnuts, Almonds, Chia Seeds,
            Pumpkin Seeds, Flax Seeds, Granola.
        FORBIDDEN: fish, meat, eggs, rice, noodles, savoury proteins.
        Example: Greek Yogurt + Strawberries + Chia Seeds + Honey â†’ "Strawberry Yogurt Bowl"

        â–  EGG BREAKFAST
        Allowed: eggs + vegetables + optional approved carb (e.g. potato, bread if in pool)
                + optional approved fat/oil.
        FORBIDDEN: fruit, berries, yogurt, kefir, honey, oats.
        Example: scrambled eggs + spinach + wholeâ€‘grain toast + olive oil.

        â–  SAVOURY BREAKFAST
        Allowed: eggs, fish/tofu (ONLY if breakfast priority is Medium or High),
                rice/potato/vegetables (ONLY if breakfast priority Medium or High).
        FORBIDDEN: oats, berries, fruit, yogurt, kefir, honey, sweet ingredients.
        Example: smoked salmon + scrambled eggs + sautÃ©ed vegetables.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        LUNCH & DINNER MEAL TYPES & DISTRIBUTION
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Across the 9 lunch meals and 9 dinner meals, use this distribution:
        â€¢ 70% Standard Plated Meals  (â‰ˆ6 meals per meal time)
        â€¢ 20% Stir Fries             (â‰ˆ2 meals per meal time)
        â€¢ 10% Salads                 (â‰ˆ1 meal per meal time)

        â–  STANDARD PLATED MEAL (most common)
        Structure: Protein + Carbohydrate + Vegetable
        Every meal must contain:
        â€¢ a clear main protein (100â€‘180 g cooked)
        â€¢ a carb (rice/pasta/noodles 60â€‘90 g dry; potatoes 150â€‘250 g)
        â€¢ vegetables (50â€‘150 g)
        â€¢ optional fats (5â€‘15 g)
        All quantities in grams or millilitres; no cups or tablespoons.
        Examples: "Grilled Salmon with Rice & Broccoli", "Steak with Sweet Potato & Asparagus",
                  "Turkey with Potatoes & Kale", "Cod with Rice & Green Beans"

        â–  STIR FRY
        Structure: Protein + Vegetables + Optional Carbohydrate
        Must contain a clear protein source and at least 2 vegetables.
        Carbohydrate is optional (e.g. rice noodles or rice on the side).
        Examples: "Chicken & Vegetable Stir Fry", "Shrimp Stir Fry with Broccoli & Peppers"

        â–  SALAD
        Structure: Protein + Salad Vegetables + Optional Carb or Fat
        Must contain a clear protein source; not just leaves.
        Examples: "Grilled Chicken Salad", "Tuna Salad with Mixed Greens"

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        SEASONING & FLAVOUR RULES
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Meals must not be plain. Add suitable seasonings from the pool where available.
        If the following are in the pool, apply them to matching proteins:
        â€¢ Fish dishes   â†’ Lemon, Garlic, Dill, Parsley
        â€¢ Beef dishes   â†’ Garlic, Rosemary, Black Pepper
        â€¢ Turkey dishes â†’ Garlic, Rosemary, Thyme
        â€¢ Vegetables    â†’ Herbs, Garlic, Black Pepper

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        PROTEIN ROTATION & VARIETY RULES
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        â€¢ Do NOT use the same primary protein in consecutive meals within a meal time.
        â€¢ Rotate proteins across all 9 meals in each meal time â€“ avoid repeating the same
          protein more than twice across lunch options or more than twice across dinner options.
        â€¢ Rotate fruits, vegetables, carbohydrates, and breakfast toppings for variety.
        â€¢ The same meal must not appear more than once across the 27 generated meals.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        BANNED PAIRINGS (never appear together in ANY meal)
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        - fish + berries / fruit / oats / yogurt / kefir
        - meat + berries / fruit
        - rice + yogurt / kefir
        - noodles for breakfast
        - oil as a main ingredient
        - random fruit in savoury lunch/dinner meals
        - sweet ingredients (fruit, berries, yogurt, kefir, honey) in any lunch/dinner

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        MEAL COMPLEXITY DISTRIBUTION
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Target: 80% Simple Meals | 20% Complex/Specialty Meals
        Simple = Protein + Vegetable + Carbohydrate (easy to prepare)
        Complex = Stir Fries or specialty preparations
        Keep most meals straightforward and realistic to cook.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        SUBâ€‘CATEGORY DEFINITIONS (3 per meal time)
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�

        1. PROTEINâ€‘PACKED
        - Feels highâ€‘protein, filling, gym/performance focused.
        - Protein clearly dominates the meal (>30 g).
        - Larger approved protein portions, moderate carbs, balanced fats.
        - Avoid: fruitâ€‘heavy, lowâ€‘protein, snackâ€‘style meals.
        - Calorie feel: substantial, higher than other subâ€‘categories.

        2. LIGHT & FRESH
        - Feels lighter, refreshing, cleaner, easier to digest.
        - Lighter approved protein portions, more fruit/vegetables, simpler combinations.
        - Avoid: heavy oily meals, dense carbs, oversized portions, greasy meals.
        - Calorie feel: lighter, lower than Proteinâ€‘Packed.

        3. HEALTHY & COMFORTING
        - Feels warm, balanced, comforting, realistic, healthy but satisfying.
        - Balanced protein/carb/fat, softer comforting foods, everyday combinations.
        - Avoid: random ingredient combos, ultraâ€‘light or extremely heavy meals.
        - Calorie feel: balanced, moderate.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        MEAL QUALITY TEST
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Before finalising each meal, ask: "Would a normal person realistically cook, order, or eat this?"
        If NO â†’ reject and regenerate.
        Requirements: clear protein, realistic ingredient combinations, descriptive meal name,
        proper cooking method in description.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        OUTPUT FORMAT (valid JSON only, no extra text)
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        {{
        "breakfast_options": {{
            "protein_packed":      [ meal_obj, meal_obj, meal_obj ],
            "light_fresh":         [ meal_obj, meal_obj, meal_obj ],
            "healthy_comforting":  [ meal_obj, meal_obj, meal_obj ]
        }},
        "lunch_options": {{ ... }},
        "dinner_options": {{ ... }}
        }}

        Where each meal_obj is:
        {{
        "meal_name": "string",
        "category": "Breakfast|Lunch|Dinner",
        "sub_category": "Protein-Packed|Light & Fresh|Healthy & Comforting",
        "total_calories": number,
        "macronutrients": {{"carbohydrates": number, "protein": number, "fat": number}},
        "description": "string",
        "ingredients": [{{"name": "EXACT_POOL_NAME", "quantity": "Xg or Xml", "icon": "emoji"}}],
        "number_of_servings": 1
        }}
        u,  
        You are an expert nutritionist. Generate 3 COMPLETELY DISTINCT alternative {category} meals for the {sub_category} subâ€‘category.

        USER: Blood Type {blood_type} | Diet {diet_type} | Country {country}
        Target: {target_calories} kcal Â± 5 | Allergies: {allergies} | Dislikes: {food_dislikes}

        â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�
        BACKEND PREâ€‘SELECTED FOOD POOL FOR {category_upper}
        â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�
        {food_database}
        â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�â”�

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        ABSOLUTE RULES (must be followed for every single meal)
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�

        1. INGREDIENT RULES
        a. Use ONLY the EXACT food names from the pool above. Copy them characterâ€‘forâ€‘case.
        b. DO NOT add any ingredient not in the pool â€“ no salt, pepper, oil, water, spices,
            herbs, sauces, stock, etc., unless it is explicitly listed in the pool.
        c. List EVERY ingredient you use in the `ingredients` array.
        d. The 3 meals within a subâ€‘category must use a different primary protein/carb source.
            Do not repeat the exact same ingredient combination.

        2. PRIORITY RULES
        â˜…â˜… High priority â†’ primary ingredient (~70 % of the meal's calories).
        â˜…  Medium priority â†’ supporting role (~30 % of calories).
        You may repeat a highâ€‘priority protein across different meals if it naturally fits;
        aim for variety in carb sources, vegetables, cooking styles and meal names.

        3. CALORIE MATHS
        total_calories = (carbsÃ—4)+(proteinÃ—4)+(fatÃ—9). Must match {target_calories} Â±5 kcal.
        Every ingredient must have a quantity in g or ml.
        Adjust in order: carbs â†’ protein â†’ fats.

        4. PORTION ADJUSTMENT ORDER (when tuning to hit target)
        Adjust in this strict order: â‘  carbs â†’ â‘¡ protein â†’ â‘¢ fats/oils/seeds.
        Never add an ingredient that is not already present just to hit numbers.

        5. COUNTRY CONTEXT
        {country_guidance}

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        BANNED MEAL TYPES (NEVER generate these)
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Do NOT generate any of the following meal types:
        - Wraps, Burritos, Tacos
        - Rice Bowls, Quinoa Bowls, Comfort Bowls, Power Bowls, Protein Bowls, Noodle Bowls
        - Any meal named or structured as a "Bowl" of any kind
        The goal is realistic plated meals, not trendy bowl/wrap formats.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        MEAL NAMING RULES
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Meal names must describe the actual food.
        âœ“ GOOD: "Grilled Salmon with Rice & Broccoli", "Shrimp Stir Fry", "Blueberry Oatmeal"
        âœ— BAD:  "Comfort Bowl", "Power Bowl", "Protein Packed Bowl", "Energy Bowl", "Nourish Bowl"
        The name must reflect the protein, cooking method, and key ingredients.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        BREAKFAST TEMPLATES â€“ CHOOSE ONE STYLE PER MEAL
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Every breakfast meal must belong to exactly ONE of the four templates below.
        NEVER mix ingredients from different templates in the same meal.

        â–  OATMEAL BREAKFAST
        Must contain: oats + at least 1 fruit + at least 1 approved topping.
        Approved toppings (only if in pool): Honey, Cinnamon, Walnuts, Almonds, Chia Seeds,
            Pumpkin Seeds, Flax Seeds.
        FORBIDDEN: fish, meat, eggs, rice, noodles, savoury proteins, random oils.

        â–  YOGURT BOWL BREAKFAST
        Must contain: yogurt + at least 1 fruit + at least 1 approved topping.
        Approved toppings (only if in pool): Honey, Walnuts, Almonds, Chia Seeds,
            Pumpkin Seeds, Flax Seeds, Granola.
        FORBIDDEN: fish, meat, eggs, rice, noodles, savoury proteins.

        â–  EGG BREAKFAST
        Allowed: eggs + vegetables + optional approved carb (e.g. potato, bread if in pool)
                + optional approved fat/oil.
        FORBIDDEN: fruit, berries, yogurt, kefir, honey, oats.
        Example: scrambled eggs + spinach + wholeâ€‘grain toast + olive oil.

        â–  SAVOURY BREAKFAST
        Allowed: eggs, fish/tofu (ONLY if breakfast priority is Medium or High),
                rice/potato/vegetables (ONLY if breakfast priority Medium or High).
        FORBIDDEN: oats, berries, fruit, yogurt, kefir, honey, sweet ingredients.
        Example: smoked salmon + scrambled eggs + sautÃ©ed vegetables.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        LUNCH & DINNER MEAL TYPES
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        â–  STANDARD PLATED MEAL: Protein + Carbohydrate + Vegetable
          â€¢ protein (100â€‘180 g cooked), carb (60â€‘90 g dry), vegetables (50â€‘150 g), optional fats (5â€‘15 g)
          â€¢ All quantities in grams or millilitres; no cups or tablespoons.
          â€¢ Examples: "Grilled Salmon with Rice & Broccoli", "Steak with Sweet Potato & Asparagus"

        â–  STIR FRY: Protein + Vegetables + Optional Carbohydrate
          â€¢ Must contain a clear protein source and at least 2 vegetables.
          â€¢ Examples: "Chicken & Vegetable Stir Fry", "Shrimp Stir Fry with Broccoli & Peppers"

        â–  SALAD: Protein + Salad Vegetables + Optional Carb or Fat
          â€¢ Must contain a clear protein source; not just leaves.
          â€¢ Examples: "Grilled Chicken Salad", "Tuna Salad with Mixed Greens"

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        SEASONING & FLAVOUR RULES
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Meals must not be plain. Add suitable seasonings from the pool where available.
        â€¢ Fish dishes   â†’ Lemon, Garlic, Dill, Parsley
        â€¢ Beef dishes   â†’ Garlic, Rosemary, Black Pepper
        â€¢ Turkey dishes â†’ Garlic, Rosemary, Thyme
        â€¢ Vegetables    â†’ Herbs, Garlic, Black Pepper

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        BANNED PAIRINGS (never appear together in ANY meal)
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        - fish + berries / fruit / oats / yogurt / kefir
        - meat + berries / fruit
        - rice + yogurt / kefir
        - noodles for breakfast
        - oil as a main ingredient
        - random fruit in savoury lunch/dinner meals
        - sweet ingredients (fruit, berries, yogurt, kefir, honey) in any lunch/dinner

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        SUBâ€‘CATEGORY DEFINITIONS
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�

        1. PROTEINâ€‘PACKED
        - Feels highâ€‘protein, filling, gym/performance focused.
        - Protein clearly dominates the meal (>30 g).
        - Larger approved protein portions, moderate carbs, balanced fats.
        - Avoid: fruitâ€‘heavy, lowâ€‘protein, snackâ€‘style meals.
        - Calorie feel: substantial, higher than other subâ€‘categories.

        2. LIGHT & FRESH
        - Feels lighter, refreshing, cleaner, easier to digest.
        - Lighter approved protein portions, more fruit/vegetables, simpler combinations.
        - Avoid: heavy oily meals, dense carbs, oversized portions, greasy meals.
        - Calorie feel: lighter, lower than Proteinâ€‘Packed.

        3. HEALTHY & COMFORTING
        - Feels warm, balanced, comforting, realistic, healthy but satisfying.
        - Balanced protein/carb/fat, softer comforting foods, everyday combinations.
        - Avoid: random ingredient combos, ultraâ€‘light or extremely heavy meals.
        - Calorie feel: balanced, moderate.

        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        MEAL QUALITY TEST
        â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�â•�
        Before finalising each meal, ask: "Would a normal person realistically cook, order, or eat this?"
        If NO â†’ reject and regenerate.
        Requirements: clear protein, realistic combinations, descriptive meal name, proper cooking method.

        VARIETY: the 3 meals must differ in protein, carb, vegetable, cooking style, and cultural flavour.

        Return ONLY valid JSON:
        {{
        "alternatives": [
            {{
            "meal_name": "string",
            "category": "{category}",
            "sub_category": "{sub_category}",
            "total_calories": number,
            "macronutrients": {{"carbohydrates": number, "protein": number, "fat": number}},
            "description": "string",
            "ingredients": [{{"name": "EXACT_POOL_NAME", "quantity": "Xg or Xml", "icon": "emoji"}}],
            "number_of_servings": 1
            }},
            {{...}}, {{...}}
        ]
        }}
        )r	   rì   rí   Úllmr   r  rè   Úmeal_image_generatorr
   Úfrom_templateÚcategory_image_promptÚdaily_nutrition_promptÚmeal_plan_promptÚswap_meal_prompt©rï   r  s     r+   rð   z"EnhancedMealPlanGenerator.__init__ä  s°   € ÜØ¨Ü—I‘IÐ.Ó/ô
ˆŒð $0Ò#GÔ3EÓ3GˆÔÜ$6Ó$8ˆÔ!ô &8×%EÑ%Eð Gó &ˆÔ"ô '9×&FÑ&Fð %Hó %'ˆÔ#ôP !3× @Ñ @ð nBó n!ˆÔôd !3× @Ñ @ð mBó m!ˆÕr-   Úcountryr   c                 ó~   — dddœ}| sy| j                  «       j                  «       }|dv r|d   S |dv r|d   S d	| › d
�S )Nz_Traditional Chinese cooking: steaming, stir-frying, braising. Ginger, garlic, tofu, vegetables.zUKorean traditions: fermented foods, gochujang, sesame oil, kimchi, varied vegetables.©ÚchinaÚsouth_koreaz<Create balanced meals using generally available ingredients.©r*  Úchineser*  ©zsouth koreazsouth koreanÚkoreaÚkoreanr+  z7Create balanced meals incorporating local cuisine from z when appropriate.©r'   r7   ©r'  Úgr   s      r+   Úget_country_guidancez.EnhancedMealPlanGenerator.get_country_guidanceÀ  sc   € ð }Ørñ
ˆñ ØQØ�M‰M‹O×!Ñ!Ó#ˆØÐ$Ñ$°1°W±:Ð,=ØÐBÑBÈ1È]ÑK[ÐD[ØHÈÈ	ÐQcÐdÐdr-   r±   c                 ó4   — | j                  «       dk(  ry| › d�S )Nr¢   z>Light protein + carb or fruit + optional fats. No heavy meats.zW: protein 100-180g cooked + carb 60-90g dry + vegetables 50-150g + optional fats 5-15g.)r7   )r±   s    r+   Ú_meal_structure_textz.EnhancedMealPlanGenerator._meal_structure_textÍ  s"   € à�>‰>Ó˜{Ò*ØSØ�ÐrÐsÐsr-   c           
      ó|   — | r:|r8|r6d|z  d|z  z   d| z  z
  dz   }t        dt        dt        |dz  «      «      «      S y)Nro   g      @r·   iÜ  i   gÍÌÌÌÌÌø?éÐ  )r¼   rˆ   Úint)ÚageÚweightÚheightÚbmrs       r+   Úcalculate_target_caloriesz3EnhancedMealPlanGenerator.calculate_target_caloriesÓ  sH   € á‘6™fØ�v‘+  v¡Ñ-°°C±Ñ7¸!Ñ;ˆCÜ�tœS ¤s¨3°©:£Ó7Ó8Ð8Ør-   Úbtfc                 ó6  — g }| j                  «       D ]o  \  }}|sŒ	|D �cg c]  }t        |t        «      r|d   n|‘Œ }}|j                  |j	                  dd«      j                  «       › ddj                  |«      › �«       Œq dj                  |«      S c c}w )Nr>   r�   rô   rö   rA   rÐ   )r:   rB   rC   rE   ÚreplaceÚtitlerF   )r?  rÑ   rÃ   rx   r[   rG   s         r+   Ú_format_blood_type_foodsz2EnhancedMealPlanGenerator._format_blood_type_foodsÚ  s‘   € àˆØŸ)™)ž+‰JˆC�ÚÙOTÓUÉuÈ!¬:°a¼Ô+>˜˜;šÀAÑEÈu�ÐUØ—‘ §¡¨C°Ó 4× :Ñ :Ó <Ð=¸RÀÇ	Á	È%Ó@PÐ?QÐRÕSð &ð �y‰y˜ÓÐùò Vs    Bc              ƒ   ó®  K  — 	 g }|rš|j                  «       D ]‡  \  }}t        |d d «      D ]q  \  }}dj                  d„ |j                  d d D «       «      }	|j	                  |j                  dd«      j                  «       › d|dz   › d|j                  › d	|	› �«       Œs Œ‰ d
j                  |«      xs |› d�}
| j                  | j                  z  }t        4 ƒd {  –—†  |j                  ||
|j                  dd«      |j                  dd«      |j                  dd«      dœ«      ƒ d {  –—† }d d d «      ƒd {  –—†  j                  j                  «       }|j                  d«      r"|j!                  d«      d   j                  «       S |S 7 Œ²7 Œe7 ŒW# 1 ƒd {  –—†7  sw Y   ŒgxY w# t"        $ r}t%        d|› �«       d|› d�cY d }~S d }~ww xY w­w)Né   rA   c              3   ó4   K  — | ]  }|j                   –— Œ y ­w©NrU   )rã   ri   s     r+   rä   zKEnhancedMealPlanGenerator.generate_category_image_prompt.<locals>.<genexpr>ë  s   è ø€ Ð(OÑ=N°c¨¯­Ñ=Nùs   ‚é   r�   rô   r}   rö   u    â€” rÐ   z4 protein-packed, light & fresh, healthy & comfortingr   r@   r.   r0   r'  )r±   Úmeal_options_summaryr   r.   r'  z```zCategory image prompt error: z!Professional food photography of z. meals, balanced, appetising, clean background)r:   Ú	enumeraterF   rc   rE   rA  rB  rú   r"  r  ÚIMAGE_SEMAPHOREÚainvoker6   Úcontentr'   Ú
startswithr)   rø   rù   )rï   r±   r  Ú	user_dataÚ	summariesrT   Úmealsrõ   ÚmÚkeysÚsummaryÚchainr  Úprÿ   s                  r+   Úgenerate_category_image_promptz8EnhancedMealPlanGenerator.generate_category_image_promptå  s¹  è ø€ ð	pØˆIÙØ",×"2Ñ"2Ö"4‘J�C˜Ü )¨%°°¨)Ö 4™˜˜1Ø#Ÿy™yÑ(O¸Q¿]¹]È2ÈAÑ=NÓ(OÓO˜Ø!×(Ñ(¨C¯K©K¸¸CÓ,@×,FÑ,FÓ,HÐ+IÈÈ1ÈQÉ3È%ÈrÐRS×R]ÑR]ÐQ^Ð^cÐdhÐciÐ)jÕkñ !5ð #5ð —i‘i 	Ó*Òo°°
Ð:nÐ.oˆGØ×.Ñ.°·±Ñ9ˆEß&–ØŸ-™-Ø (À'Ø"+§-¡-°¸RÓ"@Ø"+§-¡-°¸JÓ"GØ"+§-¡-°	¸"Ó"=ñ	)ó ÷ �÷ '—ð —	‘	—‘Ó!ˆAØ01·±¸UÔ0C�1—7‘7˜5“> !Ñ$×*Ñ*Ó,ÐJÈÐJð 'øðøð 'ø——‘ûô ò 	pÜÐ1°!°Ð5Ô6Ø6°x°jÐ@nÐoÕoûð	püs�   ‚G„CF+ ÃFÃF+ Ã!AFÄ,FÄ-FÄ1F+ Ä<FÄ=AF+ ÆGÆF+ ÆGÆF+ ÆFÆF+ ÆF(ÆFÆF(Æ$F+ Æ+	GÆ4GÇGÇGÇGÇGc              ƒ   ó  K  — 	 | j                  |||«      ƒ d {  –—† }| j                  j                  |||«      }|r"|t        t	        j
                  «       «      d d fS dS 7 ŒG# t        $ r}t        d|› d|› �«       Y d }~yd }~ww xY w­w)Nr«   ©NNzCategory image error rö   )rW  r   r  rD   ÚuuidÚuuid4rø   rù   )rï   r±   r  rO  rþ   Úb64rÿ   s          r+   Úgenerate_single_category_imagez8EnhancedMealPlanGenerator.generate_single_category_imageü  s“   è ø€ ð	 Ø×>Ñ>¸xÈÐU^Ó_×_ˆFØ×.Ñ.×FÑFÀxÐQWÐYcÓdˆCÙ36�CœœTŸZ™Z›\Ó*¨2¨AÐ.Ð/ÐH¸LÐHð `ùô ò 	 ÜÐ)¨(¨°2°a°SÐ9Ô:Üûð	 üsK   ‚B„A$ šA"›AA$ ÁBÁ A$ Á!BÁ"A$ Á$	BÁ-BÁ>BÂBÂBc              ƒ   óÒ   K  — |j                   |j                  |j                  dœ}i }|j                  «       D ]'  \  }}|r| j	                  |||«      ƒ d {  –—† nd||<   Œ) |S 7 Œ­w)Nr¡   rY  )Úbreakfast_optionsÚlunch_optionsÚdinner_optionsr:   r]  )rï   Ú	meal_planrO  ÚcatsÚoutr?   Úmds          r+   Úgenerate_category_imagesz2EnhancedMealPlanGenerator.generate_category_images  sq   è ø€ Ø&×8Ñ8Ø&×4Ñ4Ø&×5Ñ5ñ7ˆð ˆØŸ
™
ž‰HˆD�"ÙZ\˜d×AÑAÀ$ÈÈIÓV×VÐVÐbnˆC�ŠIð %àˆ
ð Wús   ‚AA'ÁA%ÁA'rO  c              ƒ   óú  K  — t        |j                  dd«      «      }t        |j                  dd«      «      }|j                  dd«      }| j                  | j                  z  }t
        4 ƒd {  –—†  |j                  |||xs d|j                  dd«      |j                  d	d«      |j                  d
d«      |j                  dd«      |j                  dd«      dœ«      ƒ d {  –—† }d d d «      ƒd {  –—†  t        j                  ddj                  j                  «       «      }t        j                  dd|«      j                  «       }	 t        j                  |«      }|j                  dd«      }
|j                  di «      }|j                  d«      xs* t        |
dz  «      t        |
dz  «      t        |
dz  «      dœ}t!        |
t#        |j                  dd«      |j                  dd«      |j                  dd«      ¬ «      |j                  d!d"«      t%        j&                  «       |¬#«      S 7 �ŒÄ7 �ŒQ7 �ŒD# 1 ƒd {  –—†7  sw Y   �ŒUxY w# t        j                  $ r}	t        dd|	› �«      ‚d }	~	ww xY w­w)$Nr   r!   r.   r0   r'  r@   úNot specifiedr:  r;  Údesired_weightr<  Ú	main_goalúStay Fit)r   r.   r'  r:  r;  ri  r<  rj  ú^```json\s*ú\s*```$r   z$Failed to parse nutrition response: Útotal_daily_caloriesr8  Útotal_daily_macronutrientsÚmeal_calorie_distributionç333333Ó?çš™™™™™Ù?r¡   Úcarbohydrateséú   Úproteinr   ÚfatéC   ©rs  ru  rv  Úuser_idÚunknown)rn  ro  ry  Úcalculation_timestamprp  )r,   r6   r9   r#  r  ÚLLM_SEMAPHORErL  ÚrerT   rM  r'   ÚjsonÚloadsÚJSONDecodeErrorr   r9  r   r   r   Únow)rï   rO  r   r.   r'  rU  r  rM  r
  rÿ   ÚtotalÚmacrosÚ	meal_dists                r+   Úcalculate_daily_nutritionz3EnhancedMealPlanGenerator.calculate_daily_nutrition  s!  è ø€ Ü*¨9¯=©=¸ÀsÓ+KÓLˆ
Ü)¨)¯-©-¸ÀZÓ*PÓQˆ	Ø—]‘] 9¨bÓ1ˆà×+Ñ+¨d¯h©hÑ6ˆß –=Ø—m‘mØ(°yØ%Ò8¨Ø'Ÿm™m¨E¸oÓNØ'Ÿm™m¨H¸oÓNØ"+§-¡-Ð0@À/Ó"RØ'Ÿm™m¨H¸oÓNØ'Ÿm™m¨K¸jÓIñ%ó ÷ ˆA÷ !—=ô —&‘&˜¨¨Q¯Y©Y¯_©_Ó->Ó?ˆÜ—&‘&˜ R¨Ó1×7Ñ7Ó9ˆð	QÜ—:‘:˜gÓ&ˆDð —H‘HÐ3°TÓ:ˆØ—H‘HÐ9¸2Ó>ˆØ—H‘HÐ8Ó9ò 
Ü˜U T™\Ó*Ü˜U T™\Ó*Ü˜U T™\Ó*ñ>
ˆ	ô
 &Ø!&Ü'5Ø$Ÿj™j¨¸#Ó>ØŸ
™
 9°CÓ8Ø—J‘J˜u°Ó4ô(ð
 —M‘M )¨YÓ7Ü"*§,¡,£.Ø&/ô

ð 
	
ð3 !ùðùð !ù—=—=’=ûô ×#Ñ#ò 	QÜ Ð'KÈAÈ3Ð%OÓPÐPûð	Qüs�   ‚A,I;Á.H2Á/I;Á2A2H;Ã$H5Ã%H;Ã)I;Ã4H8Ã5AI;ÅI Å#CI;È5H;È8I;È;IÉIÉIÉ	I;ÉI8É$I3É3I8É8I;Údaily_nutritionÚgenerate_imagesc              ƒ   ó¤  K  — t        |j                  dd«      «      }t        |j                  dd«      «      }|j                  dd«      }| j                  j	                  ||d¬«      ƒ d {  –—† }| j                  j                  ||d	¬«      ƒ d {  –—† }t        d
t        |«      › dt        |«      › �«       t        |||g |j                  d«      ¬«      }	t        ||«      \  }
}|r)|j                  }|j                  }|j                  xs i }nD| j                  |j                  d«      |j                  d«      |j                  d«      «      }d }i }|j                  dt        |dz  «      «      }|j                  dt        |dz  «      «      }|j                  dt        |dz  «      «      }|dz
  }|dz   }|dz
  }|dz   }|dz
  }|dz   }|r7t        j                   |j"                  |j$                  |j&                  dœ«      nd}| j(                  | j*                  z  }t,        4 ƒd {  –—†  |j/                  i d|“d|“d|xs d“d|j                  dd«      “d|j                  dd«      “d|j                  dd«      “d|j                  dd«      “d|j                  dd«      “d|“d|“d|j                  dd «      “d!t        j                   |«      “d"|“d#|“d$|“d%|“d&|“||
|	| j1                  |«      d'œ¥«      ƒ d {  –—† }d d d «      ƒd {  –—†  t3        j4                  d(dj6                  j9                  «       «      }t3        j4                  d)d|«      j9                  «       }	 t        j:                  |«      }g d-¢}g d.¢}|D ]R  } | |vr| j?                  ||«      c S |D ]3  }!|!||    vst        ||    |!   «      d/k7  sŒ| j?                  ||«      c c S  ŒT |D ]/  } |D ](  }!||    |!   D �"cg c]  }"tA        |"|«      ‘Œ c}"||    |!<   Œ* Œ1 tC        | jE                  |d0   «      | jE                  |d1   «      | jE                  |d2   «      |j                  d3d4«      |||j                  d!«      ¬5«      }#|r"|j                  |#_
        |j                  |#_        |r¶| jG                  |#|«      ƒ d {  –—† }$|$j                  dd6«      d7   |#_$        |$j                  dd6«      d8   |#_%        |$j                  dd6«      d7   |#_&        |$j                  dd6«      d8   |#_'        |$j                  dd6«      d7   |#_(        |$j                  dd6«      d8   |#_)        |#S 7 �Œñ7 �ŒÎ7 �Œ67 �Œ`7 �ŒS# 1 ƒd {  –—†7  sw Y   �ŒdxY w# t        j<                  $ r0}t        d*|› d+|d d, › �«       | j?                  ||«      cY d }~S d }~ww xY wc c}"w 7 �Œ­w)9Nr   r!   r.   r0   r'  r@   r   ©ÚlimitéÈ   u!   [MealPlan] Pools â€” beneficial: ú, neutral: Úblood_group_rulesrM   r:  r;  r<  r¢   g      Ð?r£   rr  r¤   gffffffÖ?r·   rx  rh  Úfood_dislikesrà   Ú	allergiesÚtarget_caloriesro  rj  rk  rp  Úbreakfast_cal_minÚbreakfast_cal_maxÚlunch_cal_minÚlunch_cal_maxÚdinner_cal_min)Údinner_cal_maxÚfood_databaser�  Úcountry_guidancerl  rm  zJSON error: rÐ   i�  )r_  r`  ra  ©Úprotein_packedÚlight_freshÚhealthy_comfortingrH  r_  r`  ra  ry  rz  ©r_  r`  ra  ry  r   r.   rp  rY  r   r}   )*r,   r6   r9   r  Úget_beneficial_foodsÚget_neutral_foodsrù   r�   rQ   rÜ   rn  ro  rp  r>  r9  r~  Údumpsrs  ru  rv  r$  r  r|  rL  r4  r}  rT   rM  r'   r  r€  Ú_create_fallback_meal_planrl   r   Ú_convert_subcatsrf  Úbreakfast_imageÚbreakfast_image_idÚlunch_imageÚlunch_image_idÚdinner_imageÚdinner_image_id)%rï   rO  r†  r‡  r   r.   r'  ÚbenÚneur�  r—  rÛ   Útargetrƒ  ÚdistÚb_calÚl_calÚd_calÚbreakfast_minÚbreakfast_maxÚ	lunch_minÚ	lunch_maxÚ
dinner_minÚ
dinner_maxÚ	macro_strrU  r  rM  r
  rÿ   Úreq_catsÚreq_subsrÃ   rT   Úmealrb  Úimgss%                                        r+   Úgenerate_meal_planz,EnhancedMealPlanGenerator.generate_meal_plan;  s#  è ø€ ô +¨9¯=©=¸ÀsÓ+KÓLˆ
Ü)¨)¯-©-¸ÀZÓ*PÓQˆ	Ø—]‘] 9¨bÓ1ˆð ×%Ñ%×:Ñ:¸:ÀyÐX[Ð:Ó\×\ˆØ×%Ñ%×7Ñ7¸
ÀIÐUXÐ7ÓY×YˆÜÐ1´#°c³(°¸;ÄsÈ3ÃxÀjÐQÔRä4Ø!ØØØØ"Ÿ™Ð':Ó;ô
Ðô &?¸sÀCÓ%HÑ"ˆ�{ñ Ø%×:Ñ:ˆFØ%×@Ñ@ˆFØ%×?Ñ?ÒEÀ2‰Dà×4Ñ4Ø—‘˜eÓ$ i§m¡m°HÓ&=¸y¿}¹}ÈXÓ?VóXˆFàˆFØˆDà—‘˜¤c¨&°4©-Ó&8Ó9ˆØ—‘˜¤c¨&°4©-Ó&8Ó9ˆØ—‘˜¤c¨&°4©-Ó&8Ó9ˆà ™	ˆØ ™	ˆØ ™	ˆ	Ø ™	ˆ	Ø ™	ˆ
Ø ™	ˆ
ñ ô	 —J‘JØ#×1Ñ1Ø#Ÿ^™^Ø#ŸZ™Zñ 
ô ð *ð	 	ð ×%Ñ%¨¯©Ñ0ˆß –=Ø—m‘mð %Ø˜jð%Ø*5°yð%à˜gÒ8¨ð%ð ˜iŸm™m¨E°oÓFð%ð ˜iŸm™m¨H°oÓFð	%ð
 ˜iŸm™m¨H°oÓFð%ð   §¡¨ÀÓ!Gð%ð  §¡¨{ÀÓ!Gð%ð "¨Vð%ð -¨ið%ð ¨Y¯]©]¸;È
Ó-Sð%ð ,¬T¯Z©Z¸Ó-=ð%ð $ ]ð%ð $ ]ð%ð   ð%ð   ð%ð  ! *ð!%ð" #-Ø&3Ø&7Ø&*×&?Ñ&?ÀÓ&Hò)%ó ÷ ˆA÷ !—=ô0 —&‘&˜¨¨Q¯Y©Y¯_©_Ó->Ó?ˆÜ—&‘&˜ R¨Ó1×7Ñ7Ó9ˆð	OÜ—:‘:˜gÓ&ˆDò LˆÚJˆÛˆCØ˜$‰Ø×6Ñ6°yÀ/ÓRÒRÛ�Ø˜d 3™iÑ'¬3¨t°C©y¸©~Ó+>À!Ó+CØ×:Ñ:¸9ÀoÓVÔVñ  ð ó ˆCÛ�ð !% S¡	¨#¢ó"á .˜ô 0°°kÕBØ .ñ"��S‘	˜#’ñ  ð ô %Ø"×3Ñ3°DÐ9LÑ4MÓNØ"×3Ñ3°D¸Ñ4IÓJØ"×3Ñ3°DÐ9IÑ4JÓKØ!Ÿ™ i°Ó;Ø"Ø!Ø&*§h¡hÐ/JÓ&Kô
ˆ	ñ Ø3B×3WÑ3WˆIÔ*Ø3B×3]Ñ3]ˆIÔ0ñ Ø×6Ñ6°yÀ)ÓL×LˆDØ+/¯8©8°KÀÓ+LÈQÑ+OˆIÔ%Ø+/¯8©8°KÀÓ+LÈQÑ+OˆIÔ(Ø+/¯8©8°GÀÓ+LÈQÑ+OˆIÔ!Ø+/¯8©8°GÀÓ+LÈQÑ+OˆIÔ$Ø+/¯8©8°HÀÓ+LÈQÑ+OˆIÔ"Ø+/¯8©8°HÀÓ+LÈQÑ+OˆIÔ%àÐðq ]ùØYùðX !ùðùð !ù—=—=’=ûô8 ×#Ñ#ò 	OÜ�L   2 g¨d¨s m _Ð5Ô6Ø×2Ñ2°9¸oÓNÕNûð	Oüò$"ð* MûsÒ   ‚A*WÁ,UÁ-%WÂU ÂFWÈ-U#È.WÈ1CU,ÌU&ÌU,ÌWÌU)ÌAWÍ0V ÎAWÏ-WÏ8WÐB/WÒ:WÒ;B#WÕ WÕ#WÕ&U,Õ)WÕ,U?Õ2U5Õ3U?Õ:WÖWÖ%W Ö:WÖ;W× W×	WÚswap_requestc              ƒ   óÒ  K  — t        |j                  xs d«      }t        |j                  xs d«      }|j                  xs d}|j
                  xs d}|j                  «       }| j                  j                  ||d¬«      ƒ d {  –—† }| j                  j                  ||d¬«      ƒ d {  –—† }	t        dt        |«      › d	t        |	«      › �«       t        ||	|«      \  }
}| j                  | j                  z  }t        4 ƒd {  –—†  |j!                  ||j#                  «       |j$                  xs d
|||xs d|j&                  xs d|j(                  xs d|j*                  xs d|
| j-                  |«      | j/                  |«      dœ«      ƒ d {  –—† }d d d «      ƒd {  –—†  t1        j2                  ddj4                  j7                  «       «      }t1        j2                  dd|«      j7                  «       }	 t9        j:                  |«      }d|vst        |d   «      dk7  rt?        dd«      ‚|d   D �cg c]  }tA        ||«      ‘Œ c}|d<   | jC                  |d   «      }|rx|D ]s  }| jD                  jG                  |jH                  |jJ                  |jL                  D �cg c]  }|jN                  |jP                  dœ‘Œ c}|j$                  ¬«      |_)        Œu tU        |||j$                  xs d
|j&                  xs d¬«      S 7 �Œˆ7 �Œe7 �Œ7 �Œ‚7 �Œu# 1 ƒd {  –—†7  sw Y   �Œ†xY w# t8        j<                  $ r}t?        dd|› �«      ‚d }~ww xY wc c}w c c}w ­w)Nr!   r0   r@   ÚLunchi,  r‰  é–   u!   [SwapMeal] Pools â€” beneficial: rŒ  ÚGeneralrh  iX  rà   )r±   Úcategory_upperrü   r   r.   r'  r�  r�  rŽ  r—  Úmeal_structurer˜  rl  rm  r   z$Failed to parse swap meal response: ÚalternativesrH  z$Expected exactly 3 alternative meals©r?   rd   )rú   rû   rc   rü   )rÃ  Úoriginal_categoryÚoriginal_sub_categoryr�  )+r,   r   r9   r.   r'  r±   r7   r  rž  rŸ  rù   r�   rÞ   r%  r  r|  rL  r(   rü   Úcurrent_caloriesr�  rŽ  r6  r4  r}  rT   rM  r'   r~  r  r€  r   rl   Ú_convert_meal_listr   r   rú   rû   rc   r?   rd   Úimager   )rï   r¼  r‡  r   r.   r'  r±   Úmeal_keyr©  rª  r—  rÛ   rU  r  rM  r
  rÿ   rR  rQ  rõ   s                       r+   Úgenerate_swap_mealsz-EnhancedMealPlanGenerator.generate_swap_mealsÁ  s,  è ø€ ô
 +¨<×+BÑ+BÒ+IÀcÓJˆ
Ü)¨,×*@Ñ*@Ò*NÀJÓOˆ	Ø!×)Ñ)Ò/¨RˆØ!×*Ñ*Ò5¨gˆØ—^‘^Ó%ˆà×%Ñ%×:Ñ:¸:ÀyÐX[Ð:Ó\×\ˆØ×%Ñ%×7Ñ7¸
ÀIÐUXÐ7ÓY×YˆÜÐ1´#°c³(°¸;ÄsÈ3ÃxÀjÐQÔRä%9¸#¸sÀHÓ%MÑ"ˆ�{à×%Ñ%¨¯©Ñ0ˆß –=Ø—m‘mØ"*Ø"*§.¡.Ó"2Ø".×";Ñ";Ò"H¸yØ(°yØ%Ò8¨Ø#/×#@Ñ#@Ò#GÀCØ#/×#9Ñ#9Ò#FÀØ#/×#=Ñ#=Ò#GÀØ#0Ø#'×#<Ñ#<¸XÓ#FØ$(×$=Ñ$=¸gÓ$Fñ%ó ÷ ˆA÷ !—=ô —&‘&˜¨¨Q¯Y©Y¯_©_Ó->Ó?ˆÜ—&‘&˜ R¨Ó1×7Ñ7Ó9ˆð	QÜ—:‘:˜gÓ&ˆDð  Ñ%¬¨T°.Ñ-AÓ)BÀaÒ)GÜ Ð%KÓLÐLð
 ˜.Ò)ó 
á)�ô (¨¨;Õ7Ø)ñ 
ˆˆ^Ñð
 ×'Ñ'¨¨^Ñ(<Ó=ˆÙÛ�Ø×3Ñ3×GÑGØŸk™k°q·}±}ØST×S`ÒS`Ó aÑS`Èa¨!¯&©&¸a¿j¹jÓ!IÐS`Ñ aØ!"§¡ð Hó �•ð ô  ØØ&Ø".×";Ñ";Ò"H¸yØ(×9Ñ9Ò@¸Sô	
ð 	
ð_ ]ùØYùð !ùðùð !ù—=—=’=ûô& ×#Ñ#ò 	QÜ Ð'KÈAÈ3Ð%OÓPÐPûð	Qüò 
ùò !bùs¿   ‚BM'ÂLÂ%M'Â,LÂ-AM'ÄLÄM'ÄB
LÆLÆLÆM'Æ%LÆ&AM'Ç?L3 È(M'È<MÉAM'Ê) M"Ë	AM'ÌM'ÌM'ÌLÌM'ÌL0Ì#L&Ì$L0Ì+M'Ì3MÍMÍMÍM'c                 ó˜  — t        d«       |r|j                  n?| j                  |j                  d«      |j                  d«      |j                  d«      «      }|r|j                  xs i ni }|j                  dt        |dz  «      «      }|j                  dt        |dz  «      «      }|j                  d	t        |dz  «      «      }d
„ }t         |d|«       |d|«       |d|«      |j                  dd«      |j                  dd«      |j                  dd«      |||dœ¬«      }	|r"|j                  |	_        |j                  |	_        |	S )NzUsing fallback meal planr:  r;  r<  r¢   rq  r£   rr  r¤   c                 óö  — g d¢}|D ��ci c]Ý  }|t        d«      D �cg c]Å  }t        | › d|j                  dd«      j                  «       › d|dz   › �| |j                  dd«      j                  «       |t	        |dz  dz  |dz  dz  |d	z  d
z  ¬«      d|j                  dd«      › d| j                  «       › d�t        ddd¬«      t        ddd¬«      t        ddd¬«      g¬«      ‘ŒÇ c}“Œß c}}S c c}w c c}}w )Nr™  rH  rô   r�   r}   g      à?r­   rq  gš™™™™™É?é	   rx  zA balanced rL   zMixed vegetablesÚ100gu   ðŸ¥—rg   zProtein sourceÚ150gu   ðŸ�—zWhole grainsÚ80gu   ðŸŒ¾©rú   r±   rü   Útotal_caloriesÚmacronutrientsrû   rc   )r…   r   rA  rB  r   r7   r   )r±   ÚcalÚsubsÚscrõ   s        r+   Ú_fbzAEnhancedMealPlanGenerator._create_fallback_meal_plan.<locals>._fb  s/  € ÚJˆDñ  !ôñ !�bð ô  % Qœxóñ  (˜!ô Ø%- J¨a°·
±
¸3¸sÓ0C×0IÑ0IÓ0KÐ/LÈAÈaÐPQÉcÈUÐ"SØ!)¸¿
¹
À3ÀsÓ8K×8QÑ8QÓ8SØ'*Ü'5Ø*-¨c©'°!©)¸SÀ¹WÀQ¹YÈCÐPSÉGÐTUÉIô(Wà&1°"·*±*¸SÀÓ2EÐ1FÀaÈÏÉÓHXÐGYÐYZÐ$[ä&Ð,>ÈÐV\Ô]Ü&Ð,<ÈÐV\Ô]Ü&¨NÈÐV\Ô]ð%öð  (ññ ð !òð ùòùós   ŠC5�C
C0Ã'C5Ã0C5Ú	Breakfastr¾  ÚDinnerry  rz  r   r!   r.   r0   r¡   r�  )rù   rn  r>  r6   rp  r9  r   ro  )
rï   rO  r†  r«  r¬  r­  r®  r¯  rØ  Úmps
             r+   r¡  z4EnhancedMealPlanGenerator._create_fallback_meal_plan  s;  € ÜÐ(Ô)Ù:I�/×6Ò6Ø×5Ñ5Ø—m‘m EÓ*¨I¯M©M¸(Ó,CÀYÇ]Á]ÐS[ÓE\ó^ð 	ñ GV�/×;Ñ;ÒA¹rÐ[]ˆØ—‘˜+¤s¨6°D©=Ó'9Ó:ˆØ—‘˜'¤s¨6°D©=Ó'9Ó:ˆØ—‘˜(¤s¨6°D©=Ó'9Ó:ˆò	ô( Ù! +¨uÓ5Ù! '¨uÓ5Ù! (¨uÓ5Ø —}‘} Y°)Ó<Ø —}‘} \°#Ó6Ø —}‘} [°*Ó=Ø49ÀEÐUZÑ&[ô
ˆñ Ø,;×,PÑ,PˆBÔ#Ø,;×,VÑ,VˆBÔ)Øˆ	r-   r
  c                 ót   — |j                  «       D ��ci c]  \  }}|| j                  |«      “Œ c}}S c c}}w rG  )r:   rÈ  )rï   r
  rT   rQ  s       r+   r¢  z*EnhancedMealPlanGenerator._convert_subcats0  s4   € ØFJÇjÁjÄlÔSÁl¹
¸¸U��T×,Ñ,¨UÓ3Ñ3ÀlÒSÐSùÓSs   ”4Ú	meal_listc                 óž  — g }|D �]8  }	 |j                  dg «      D �cg c]3  }t        |t        «      rt        d!i |¤Žnt        t	        |«      d¬«      ‘Œ5 }}|j                  di «      }t        |t        «      sddddœ}|j                  t        |j                  d	d
«      |j                  dd«      |j                  dd«      |j                  dd«      t        |j                  dd«      |j                  dd«      |j                  dd«      ¬«      |j                  dd«      ||j                  dd«      ¬«      «       �Œ; |S c c}w # t        $ r{}t        d|› �«       |j                  t        d|r|j                  dd«      nd|r|j                  dd«      nddt        ddd¬«      dt        ddd¬«      g¬ «      «       Y d }~�ŒÂd }~ww xY w)"Nrc   z	as neededrÄ  rÔ  é(   r¦   r¨   rx  rú   zUnnamed Mealr±   r   rü   rÀ  rÓ  r   rs  ru  rv  rû   r@   Únumber_of_servingsr}   )rú   r±   rü   rÓ  rÔ  rû   rc   rà  zMeal conversion error: zDefault MealzA balanced mealzMixed ingredientsz	1 servingrf   rg   rÒ  r  )
r6   rB   rC   r   rD   rE   r   r   rø   rù   )rï   rÝ  rQ  re  ri   rc   Úmrrÿ   s           r+   rÈ  z,EnhancedMealPlanGenerator._convert_meal_list3  sÆ  € ØˆÜˆBð!ð  "Ÿv™v m°RÔ8óñ  9˜ô *4°C¼Ô)>”JÑ% Ò%Ü#¬¨S«¸KÔHñIà8ð ð ð
 —V‘VÐ,¨bÓ1�Ü! "¤dÔ+Ø+-¸"ÀRÑH�BØ—‘œTØ"$§&¡&¨¸Ó"GØ"$§&¡&¨¸Ó"?Ø"$§&¡&¨¸	Ó"BØ#%§6¡6Ð*:¸CÓ#@Ü#1Ø&(§f¡f¨_¸bÓ&AØ&(§f¡f¨Y¸bÓ&AØ&(§f¡f¨U¸bÓ&Aô$ð
 &(§V¡V¨M¸bÓ%AØ%0Ø')§v¡vÐ.BÀAÓ'Fôö ð ðF ˆùòCøô, ò 
ÜÐ/°¨sÐ3Ô4Ø—‘œTØ,Ù:<˜RŸV™V J¨vÔ6À&ÙEG §¡¨°yÔ!AÈYØ#&Ü#1ÀÈBÐTVÔ#WØ 1Ü!+Ð1DÈ{ÐajÔ!kÐ lô÷ ò ûð
ús*   ŠEž8EÁC(EÅEÅ	GÅA0GÇGrG  )NF)F)r  r  r  r   r   rð   ÚstaticmethodrD   r4  r6  r9  r>  r   rC  rW  r]  rf  r   r…  Úboolr   r»  r   r   rË  r¡  r   r   r¢  rÈ  r  r-   r+   r  r  â  s}  „ ñX XÐ.@Ñ%Aó Xðx ð
e cð 
e¨cò 
eó ð
eð ðt sð t¨sò tó ðtð
 ð¸#ò ó ðð ð  dð  ¨sò  ó ð òpò. òð)
¸ð )
ÐBXó )
ð^ =AØ %ñ	CàðCð "Ð"8Ñ9ðCð ð	Cð
 
óCðR !&ñ?
à(ð?
ð ð?
ð 
ó	?
óD*ðZT T¨#¨t°D©z¨/Ñ%:ð T¸tÀCÈÈdÉÀOÑ?Tó Tð%¨D°©Jð %¸4À¹:ô %r-   r  c                   ó¼   — e Zd Zdded   fd„Zededefd„«       Zded	e	de
fd
„Zdedededededee   dee   dee   defd„Zed„ «       Zed„ «       Zed„ «       Zy)ÚFoodScannerNr  r   c                 óú   — t        ddt        j                  d«      ¬«      | _        || _        t        j                  d«      | _        t        j                  d«      | _        t        j                  d«      | _	        y )Nr  g        rê   r  a^  
        You are an expert food image analysis system.

        Your task is ONLY to identify visible food ingredients from the image.

        IMPORTANT RULES:
        1. Identify ONLY ingredients that are visually present.
        2. Do NOT use dietary logic, blood type logic, allergies, or health assumptions.
        3. Do NOT guess hidden ingredients unless visually obvious.
        4. Keep ingredient names simple and consistent.
        5. Include sauces, oils, spices, garnishes, toppings, vegetables, meats, grains, and beverages if visible.
        6. The same image should always produce the same ingredient list.
        7. Do NOT classify ingredients as healthy, harmful, beneficial, or avoid.
        8. Do NOT explain anything.

        COUNTRY CONTEXT:
        {country_guidance}

        Return ONLY valid JSON:

        {{
            "identified_ingredients": [
                "ingredient1",
                "ingredient2",
                "ingredient3"
            ]
        }}

        If no ingredients can be identified:

        {{
            "identified_ingredients": []
        }}
        u 
  
        You are a precise food compatibility classifier.

        **USER PROFILE**
        - Blood Type: {blood_type}
        - Diet: {diet_type}
        - Allergies: {allergies}
        - Country: {country}

        **BLOOD GROUP RULES** (ground truth â€“ follow these when classifying)
        {blood_group_rules}

        **REFERENCE LISTS** (same data broken out for matching)
        Beneficial foods for {blood_type}:
        {beneficial_list}

        Neutral foods:
        {neutral_list}

        Avoid foods:
        {avoid_list}

        **TASK**
        Given the list of identified ingredients below, classify each ingredient into one of three categories:
        - "safe"   (beneficial or allowed)
        - "neutral" (allowed but not particularly beneficial)
        - "avoid"  (harmful based on blood type, diet, or allergy)

        **RULES FOR CLASSIFICATION AND REASON** (MUST FOLLOW EXACTLY):
        1. If an ingredient matches an allergy â†’ status = "avoid", reason = "Not Suitable Due to Your Allergies: {{allergen}}"
        (replace {{allergen}} with the actual allergen, e.g., "Not Suitable Due to Your Allergies: peanuts")
        2. If diet is "vegan" and ingredient contains any animal product (meat, dairy, egg, honey, gelatin, etc.) â†’ status = "avoid", reason = "Not Suitable For Your Vegan Diet"
        3. If diet is "vegetarian" and ingredient contains meat or seafood â†’ status = "avoid", reason = "Not Suitable For Your Vegetarian Diet"
        4. Otherwise, use BLOOD GROUP RULES / reference lists:
        - If ingredient is in "avoid" list â†’ status = "avoid", reason = "Not Recommended For your Blood Type {blood_type} Diet"
        - If ingredient is in "beneficial" list â†’ status = "safe", reason = "" (empty string)
        - If ingredient is in "neutral" list â†’ status = "neutral", reason = "" (empty string)
        - If ingredient not in any list, use general nutritional knowledge for the given blood type and diet, and produce a reason accordingly (but prefer the exact strings above when possible).

        **IMPORTANT**: 
        - For any "avoid", the reason MUST be exactly one of the three formats above.
        - For "safe" or "neutral", reason MUST be an empty string "".
        - Accept synonyms, plurals, and common variations (e.g., "tomatoes" = "tomato").

        **IDENTIFIED INGREDIENTS** (from the image):
        {ingredients_json}

        **OUTPUT FORMAT** (valid JSON only)
        {{
        "classifications": [
            {{
            "ingredient": "exact ingredient name as given",
            "status": "safe|neutral|avoid",
            "reason": "exact reason string as specified above"
            }}
        ]
        }}
        u  
        You are a BloodFIT nutrition coach. Generate a fresh description for this food scan.

        USER PROFILE
        - Blood Type: {blood_type}
        - Diet: {diet_type}
        - Allergies: {allergies}

        OVERALL RESULT TYPE: {type_title}

        INGREDIENTS FOUND IN THE IMAGE:
        - Beneficial: {beneficial_ingredients}
        - Neutral: {neutral_ingredients}
        - Avoid: {avoid_ingredients}

        BLOOD GROUP RULES:
        {blood_group_rules}

        RULES
        1. Write ONE short description (1â€“2 sentences) for type "{type_title}".
        2. The description MUST be generated from the ingredients and profile above.
        3. Be specific â€” mention relevant ingredients when possible.
        4. Do NOT use generic template phrases. Do NOT copy fixed marketing copy.
        5. Tone: clear, supportive, BloodFIT product style. No markdown or bullets.

        Return ONLY valid JSON:
        {{
            "description": "your AI-generated 1-2 sentence description"
        }}
        )
r	   rì   rí   r  r  r
   r!  Úfood_scan_promptÚclassify_promptÚtype_description_promptr&  s     r+   rð   zFoodScanner.__init___  s~   € ÜØØÜ—I‘IÐ.Ó/ô
ˆŒð
 )ˆÔô !3× @Ñ @ð !Bó !!ˆÔôH  2×?Ñ?ð 9Aó 9 ˆÔôx (:×'GÑ'Gð Ió (ˆÕ$r-   r'  r   c                 ó~   — dddœ}| sy| j                  «       j                  «       }|dv r|d   S |dv r|d   S d	| › d
�S )NzMTraditional Chinese cuisine: steamed dishes, vegetables, rice, tofu, seafood.z;Korean cuisine: vegetables, rice, fermented foods, seafood.r)  zXGeneral international cuisine. Focus on whole foods appropriate for blood type and diet.r,  r*  r.  r+  zGeneral guidance for z	 cuisine.r1  r2  s      r+   r4  z FoodScanner.get_country_guidanceç  sd   € ð kØXñ
ˆñ ØmØ�M‰M‹O×!Ñ!Ó#ˆØÐ#Ñ#Ø�W‘:ÐØÐ?Ñ?Ø�]Ñ#Ð#Ø& w i¨yÐ9Ð9r-   Ú
image_datarO  c              ƒ   ó^  K  — 	 t        |j                  dd«      «      }t        |j                  dd«      «      }|j                  dd«      }|j                  dd«      }g g g }	}}| j                  ri| j                  j	                  |«      ƒ d {  –—† }| j                  j                  |«      ƒ d {  –—† }| j                  j                  |«      ƒ d {  –—† }	t        ||||	|j                  d«      ¬	«      }
d2d
„}t        j                  |«      j                  d«      }dd| j                  j                  | j                  |«      ¬«      dœddd|› �idœgdœg}| j                  j                  |«      }|j                   j#                  «       }d }	 t%        j&                  |«      }|st3        g g g g dddg ¬«      S |j                  dg «      }|st3        g g g g dddg ¬«      S | j4                  j                  ||j7                  «       |xs d|xs d|
 ||«       ||«       ||	«      t%        j8                  |«      ¬«	      }d|dœg}| j                  j                  |«      }|j                   j#                  «       }	 t%        j&                  |«      }|j                  dg «      }g }g }g }|D ]›  }|d    }|d!   j=                  «       }|j                  d"d«      }|d#k(  r.d$|v rd%} n	d&|v rd'} nd} |j?                  tA        ||| ¬(«      «       Œ`|d)k(  r|j?                  tC        |¬*«      «       Œ�|j?                  tE        |¬*«      «       Œ� | jG                  |||«      }!| jI                  |«      }"| jK                  |«      }#tM        tO        |«      tO        |«      tO        |«      ¬+«      }$g }%|$r¥|$d,   }&| jQ                  |&jR                  |||xs d|
|D �'cg c]  }'|'jT                  ‘Œ c}'|D �'cg c]  }'|'jT                  ‘Œ c}'|D �'cg c]  }'|'jT                  ‘Œ c}'¬-«      }(|(stW        d.d/«      ‚tY        |&jZ                  |&jR                  |(¬0«      g}%t3        |||||!|"|#|%¬«      S 7 �ŒÙ7 �Œ¹7 �Œ™# t$        j(                  $ rj t+        j,                  d|t*        j.                  «      }|r?	 t%        j&                  |j1                  d«      «      }n# t$        j(                  $ r Y nw xY wY �ŒCw xY w# t$        j(                  $ r[ t+        j,                  d|t*        j.                  «      }|r%t%        j&                  |j1                  d«      «      }nt;        d«      ‚Y �ŒÈw xY wc c}'w c c}'w c c}'w # tV        $ r ‚ t\        $ r(})t_        j`                  «        tW        d.d1|)› �«      ‚d })~)ww xY w­w)3Nr   r!   r.   r0   r'  r@   r�  r�  rM   c                 ó2   — | rdj                  | d | «      S dS )NrA   r=   rå   )Úlstr;   s     r+   Úfmtz(FoodScanner.scan_food_image.<locals>.fmt  s   € Ù58�t—y‘y  Z i Ó1ÐM¸oÐMr-   zutf-8ÚuserÚtext)r˜  )Útyperñ  Ú	image_urlÚurlzdata:image/jpeg;base64,)rò  ró  ©ÚrolerM  ú(\{.*\})r}   z8Unable to analyse the image. Please try a clearer photo.)Úidentified_ingredientsÚharmful_ingredientsÚsafe_ingredientsÚneutral_ingredientsÚwarning_messageÚsafe_messageÚneutral_messageÚ
food_typesrø  z:No ingredients detected. Please ensure the image is clear.rà   ÚUnknown)	r   r.   r�  r'  r�  Úbeneficial_listÚneutral_listÚ
avoid_listÚingredients_jsonz(No valid JSON in classification responseÚclassificationsr]   ÚstatusÚreasonrP   Ú	AllergiesÚallergyÚDietÚdiet)r?   r  r±   ÚsaferU   )Úhas_beneficialÚhas_neutralÚ	has_avoidr   )Ú
type_titler   r.   r�  r�  Úbeneficial_ingredientsrû  Úavoid_ingredientsr   z0Failed to generate AI description for food type.)ÚkeyrB  rû   zFood scanning failed: ©é2   )1r,   r6   r9   r  rž  rŸ  Úget_avoid_foodsrQ   Úbase64Ú	b64encodeÚdecoderç  Úformatr4  r  ÚinvokerM  r'   r~  r  r€  r}  ÚsearchÚDOTALLÚgroupr   rè  Ú
capitalizer   Ú
ValueErrorr7   rE   r   r   r   Ú_warning_msgÚ	_safe_msgÚ_neutral_msgr   rã  Ú_generate_type_descriptionrB  r?   r   r   r  rø   Ú	tracebackÚ	print_exc)*rï   rë  rO  r   r.   r'  r�  rN   rO   rP   r�  rï  Ú	image_b64Úvision_messagesÚresponserM  Ú	scan_datarR  Ú
identifiedÚclassify_textÚclassify_messagesÚclassify_responseÚclassify_contentÚclassify_resultr  rù  rú  rû  rH   Úing_namer  r  r±   Úwarning_msgÚsafe_msgÚneutral_msgÚpresent_typesrÿ  rÀ   rõ   Úai_descriptionrÿ   s*                                             r+   Úscan_food_imagezFoodScanner.scan_food_imageö  sè  è ø€ ðy	CÜ.¨y¯}©}¸\È3Ó/OÓPˆJÜ-¨i¯m©m¸KÈÓ.TÓUˆIØ"Ÿ™ y°"Ó5ˆGØ"Ÿ™ {°BÓ7ˆIð *,¨R° ˜ˆJØ× Ò Ø#'×#4Ñ#4×#IÑ#IÈ*Ó#U×U�
Ø#'×#4Ñ#4×#FÑ#FÀzÓ#R×R�Ø#'×#4Ñ#4×#DÑ#DÀZÓ#P×P�ä 8Ø%Ø%ØØØ&Ÿ]™]Ð+>Ó?ô!ÐóNô ×(Ñ(¨Ó4×;Ñ;¸GÓDˆIàð !'Ø $× 5Ñ 5× <Ñ <Ø-1×-FÑ-FÀwÓ-Oð !=ó !ñð !,Ø&+Ð/FÀyÀkÐ-RÐ%Sñðñ ð ˆOð  —x‘x—‘ Ó7ˆHØ×&Ñ&×,Ñ,Ó.ˆGð ˆIðÜ ŸJ™J wÓ/�	ñ Ü'Ø+-Ø(*¸RÐUWØ$^Ø!#°RØ!ôð ð #Ÿ™Ð'?ÀÓDˆJÙÜ'Ø+-Ø(*¸RÐUWØ$`Ø!#°RØ!ôð ð !×0Ñ0×7Ñ7Ø%Ø#×.Ñ.Ó0Ø#Ò- vØÒ, 9Ø"3Ù # J£Ù  ›\Ù˜u›:Ü!%§¡¨JÓ!7ð 8ó 
ˆMð +1¸]Ñ!KÐ LÐØ $§¡§¡Ð0AÓ BÐØ0×8Ñ8×>Ñ>Ó@ÐðQÜ"&§*¡*Ð-=Ó">�ð .×1Ñ1Ð2CÀRÓHˆOð <>ÐØ57ÐØ;=Ðã'�Ø Ñ-�Ø˜h™×-Ñ-Ó/�ØŸ™ (¨BÓ/�à˜WÒ$à" fÑ,Ø#,™Ø 6Ñ)Ø#)™à#/˜Ø'×.Ñ.Ô/@Ø%Ø%Ø!)ô0õ ð
 ˜vÒ%Ø$×+Ñ+¬NÀÔ,IÕJà'×.Ñ.Ô/@ÀhÔ/OÕPð+ (ð0 ×+Ñ+Ð,?ÀÈYÓWˆKØ—~‘~Ð&6Ó7ˆHØ×+Ñ+Ð,?Ó@ˆKô 0Ü#Ð$4Ó5Ü Ð!4Ó5ÜÐ2Ó3ôˆMð
 .0ˆJÙØ(¨Ñ+�Ø!%×!@Ñ!@Ø'Ÿ~™~Ø)Ø'Ø'Ò1¨6Ø&7Ù<LÓ+MÑ<L°q¨A¯F«FÐ<LÑ+MÙ9LÓ(MÑ9L°A¨¯«Ð9LÑ(MÙ7JÓ&KÑ7J°! q§v£vÐ7JÑ&Kð "Aó 	"�ñ &Ü'ØØJóð ô
 !Ø$ŸL™LØ&Ÿn™nØ$2ôð�
ô $Ø'1Ø$7Ø!1Ø$7Ø +Ø%Ø +Ø%ô	ð 	ðC VùØRùØPúôL ×'Ñ'ò Ü—I‘I˜k¨7´B·I±IÓ>�ÙðÜ$(§J¡J¨q¯w©w°q«zÓ$:™	øÜ×/Ñ/ò Ùðýðûô^ ×'Ñ'ò QÜ—I‘I˜kÐ+;¼R¿Y¹YÓG�ÙÜ&*§j¡j°·±¸³Ó&<‘Oä$Ð%OÓPÐPò $ðQüòr ,NùÚ(MùÚ&Køô4 ò 	ØÜò 	CÜ×ÑÔ!Ü Ð'=¸a¸SÐ%AÓBÐBûð	Cüs  ‚V-„B
U0 ÂQ'Â"U0 Â1Q*Â2"U0 ÃQ-ÃB>U0 ÆQ0 Æ)U0 Æ=V-Æ>&U0 Ç$V-Ç%BU0 Ê S0 ÊEU0 ÏU!Ï)U0 Ï/U&ÐU0 ÐU+ÐAU0 Ñ&V-Ñ'U0 Ñ*U0 Ñ-U0 Ñ0:S-Ò+$SÓS-ÓS&Ó#S-Ó%S&Ó&S-Ó)U0 Ó,S-Ó-U0 Ó0A*UÕU0 ÕUÕU0 Õ0V*Ö#V%Ö%V*Ö*V-r  r   r.   r�  r�  r  rû  r  c                ó(  — | j                   j                  ||j                  «       ||dj                  |«      xs ddj                  |«      xs ddj                  |«      xs d|¬«      }	d}
t	        d«      D ]ß  }	 | j
                  j                  d|	dœg«      }|j                  xs dj                  «       }|sŒDd}	 t        j                  |«      }t!        |t"        «      r)|j%                  d«      xs dj                  «       }|r|c S t        j&                  dd|«      j                  «       }|r$|j)                  d«      s|j                  d«      c S Œá |
rt-        d|
› �«       y# t        j                  $ rl t        j                  d	|t        j                  «      }|rA	 t        j                  |j                  d
«      «      }n# t        j                  $ r d}Y nw xY wY �Œw xY w# t*        $ r}|}
t-        d|› �«       Y d}~�Œ”d}~ww xY w)u@   Generate description via AI only â€” no hardcoded fallback text.rA   rà   )r   r.   r�  r  r  rû  r  r�  NrE  rð  rõ  r@   r÷  r}   rû   z^```(?:json)?\s*|\s*```$Ú{Ú"z/[FoodScanner] type description AI call failed: z8[FoodScanner] AI description unavailable after retries: )ré  r  r  rF   r…   r  r  rM  r'   r~  r  r€  r}  r  r  r  rB   rC   r6   rT   rN  rø   rù   )rï   r  r   r.   r�  r�  r  rû  r  Úprompt_textÚ
last_errorr�   r)  rM  r
  rR  rû   r*   rÿ   s                      r+   r$  z&FoodScanner._generate_type_description²  sð  € ð ×2Ñ2×9Ñ9Ø!Ø×*Ñ*Ó,ØØ!Ø#'§9¡9Ð-CÓ#DÒ#NÈØ $§	¡	Ð*=Ó >Ò HÀ&Ø"Ÿi™iÐ(9Ó:ÒD¸fØ/ð :ó 	
ˆð ˆ
Ü�q–ˆAðMØŸ8™8Ÿ?™?°VÈÑ,TÐ+UÓV�Ø#×+Ñ+Ò1¨r×8Ñ8Ó:�ÙØà�ð(ÜŸ:™: gÓ.�Dô ˜d¤DÔ)Ø#'§8¡8¨MÓ#:Ò#@¸b×"GÑ"GÓ"I�KÙ"Ø*Ò*ô Ÿ&™&Ð!<¸bÀ'ÓJ×PÑPÓR�Ù 7×#5Ñ#5°cÔ#:Ø"Ÿ=™=¨Ó-Ò-øð5 ñ> ÜÐLÈZÈLÐYÔZØøô/ ×+Ñ+ò (ÜŸ	™	 +¨w¼¿	¹	ÓB�AÙð(Ü#'§:¡:¨a¯g©g°a«jÓ#9™DøÜ#×3Ñ3ò (Ø#'šDð(ýð(ûô" ò MØ�
ÜÐGÈÀsÐK×LÒLûðMúsm   Á<?G-Â<G-Â?E+Ã6G-ÄAG-Å+:G*Æ&$GÇ
G*ÇG#Ç G*Ç"G#Ç#G*Ç&G-Ç)G*Ç*G-Ç-	HÇ6HÈHc                 óâ   — | sy| D �cg c]  }|j                   ‘Œ }}t        |«      dk(  rd|d   › d| d   j                  › �S ddj                  |«      › d|› d|j	                  «       › d	�S c c}w )
Nz,No Avoid ingredients found for your profile!r}   zAvoid r   z! rA   z9! These ingredients are not suitable for your Blood Type rô   z Diet.)r?   r�   r  rF   r  )Úharmfulr   r.   rõ   rG   s        r+   r!  zFoodScanner._warning_msgï  sŠ   € áØAÙ!(Ó)¡˜A�—“ ˆÐ)Üˆu‹:˜Š?Ø˜E !™H˜: R¨°©
×(9Ñ(9Ð':Ð;Ð;à�T—Y‘Y˜uÓ%Ð&ð '#Ø#- ,¨a°	×0DÑ0DÓ0FÐ/GÀvðOð	
ùò *s   ˆA,c                 óŒ   — | sy| D �cg c]  }|j                   ‘Œ }}t        |«      dk  rddj                  |«      › �S dS c c}w )Nz%No beneficial ingredients identified.rH  zBeneficial to eat: rA   z6All other ingredients are beneficial for your profile.©r?   r�   rF   )r  rõ   rG   s      r+   r"  zFoodScanner._safe_msgû  sW   € áØ:Ù!%Ó&¡˜A�—“ ˆÐ&Ü;>¸u»:Èº?Ð$ T§Y¡Y¨uÓ%5Ð$6Ð7ð  	Ið  QIð  	Iùò 's   ˆAc                 ó˜   — | sy| D �cg c]  }|j                   ‘Œ }}t        |«      dk(  r|d   › d�S dj                  |«      › d�S c c}w )Nr@   r}   r   uH    is a neutral food â€“ allowed but not particularly beneficial or avoid.rA   uH    are neutral foods â€“ allowed but not particularly beneficial or avoid.r@  )rO   rõ   rG   s      r+   r#  zFoodScanner._neutral_msg  sZ   € áØÙ!(Ó)¡˜A�—“ ˆÐ)Üˆu‹:˜Š?Ø˜A‘h�ZÐgÐhÐhØ—)‘)˜EÓ"Ð#Ð#kÐlÐlùò *s   ˆArG  )r  r  r  r   rð   râ  rD   r4  Úbytesr   r   r7  r   r$  r!  r"  r#  r  r-   r+   rå  rå  ^  s	  „ ñF XÐ.BÑ%Có FðP ð: cð :¨cò :ó ð:ðzC°ð zCÀ$ð zCÐK[ó zCðx:ð ð:ð ð	:ð
 ð:ð ð:ð ð:ð !% S¡	ð:ð " #™Yð:ð   ™9ð:ð 
ó:ðz ñ	
ó ð	
ð ñIó ðIð ñmó ñmr-   rå  )éP   )NNNNrG  r  )Mr  r~  Úasyncior}  rZ  rƒ   r%  r   Útypingr   r   r   r   Úfastapir   Úlangchain_openair	   Úlangchain.promptsr
   Úopenair   Údotenvr   rì   Úfitness_app.data_managerr   r   r   r   r   r   r   r   r   r   r   r   r   Úfitness_app.vector_storer   r   Ú	Semaphorer|  rK  ÚcompileÚ
IGNORECASErS   rD   r,   r9   r9  rI   rQ   rV   r\   r`   rl   rs   Ú__annotations__ÚMEAL_TIME_ELIGIBLErã  rw   r€   r‘   rŸ   r¥   r×   r®   r³   rÌ   rÕ   rÜ   rÞ   ræ   rè   r  rå  r  r-   r+   Ú<module>rR     s,  ðÜ Û Û Û 	Û Û Û Ý ß .Ó .å !Ý 'Ý 0Ý Ý Û 	÷÷ ÷ õ ÷ Lá „à#�'×#Ñ# CÓ(€Ø#�'×#Ñ# CÓ(€ð ˆr�z‰zðFð ‡M�Mó	€ð@ cð @¨có @ð> Cð >¨Có >ñ:�tð :¨ð :°Só :ð" ØØ
Ø"&ñØðð
 ˜3‘-ðð 	óð6. Cð .¨Có .ð

 4¨¡:ð 
°$°s¸C°x±.ó 
ð #ð ¨t°C¸°H©~ð À(È3Á-ó ð4Øðà��c�‰Nðð 
óð0 -/¸"ÀRÑ#HÐ �$�s˜C�x‘.Ó HÚ.Ð ðG ð G°ð G¸ó Gð !%ñ	:Ø�T‘
ð:àð:ð ð:ð ˜‘ð	:ð
 
ˆ$�Zó:òD0òMò'àÐ/Ð0ò"ñ+Ð �4˜˜T #™Y˜Ñ'ó ò 8Ú;Ú;ñ*Ð �$�s˜D ™I�~Ñ&ó ð ˜B¨b¸BÈñ€ð ØØØØñ$Ð �$�s˜C�x‘.ó ðB t¨D¡zð B¸Cð BÀDÈÁJó Bð*$Ø�d‘ð*$à�d‘ð*$ð ð*$ð �c˜3�h‘ð	*$ð
 ð*$ð ˆ4��T˜$‘Z�Ñ  #Ð%Ñ&ó*$ðZØ�C˜˜d™�OÑ$ðàðð 	óð>.Ø�T‘
ð.à�T‘
ð.ð ˆ3��S˜#�X‘ÐÑó.ð6EØ�T‘
ðEà�T‘
ðEð ðEð ˆ3��S˜#�X‘ÐÑó	Eñ(¨$¨t©*ð Àð Ècó ÷8ñ 8÷|vñ v÷xkmò kmr-   