# Project export: Munch

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 11.0
- Tagline: Leftover groceries in your dorm and not sure what to make? Munch has you covered! You're 1 snapshot away from a quick and easy meal, and also, clearing up your fridge. Munch, brunch in a time crunch.
- Devpost: https://devpost.com/software/munch-eyqji9
- GitHub: https://github.com/TC960/munch
- Team: 2 GitHub contributor(s) — Aryen Singhal (14 commits), TC960 (7 commits)

## Devpost submission (written by the team)

### Inspiration

The inspiration for Munch comes from our challenging experience living in a cramped triple dorm last year. With limited space, our own mini-fridge quickly became a source of frustration, often overflowing with forgotten leftovers, giving birth to factor 1. Our floor in the building was shared by over 50 people, who kept their groceries in the common floor fridge and often forgot about them. By the end of the year, it all piled up and our floor's shared fridge was so overstuffed that it broke down, leading to a $75 repair charge we all had to bear, birthing factor 2. These 2 eye-opening experiences revealed the common issues of food waste and mismanagement in shared living spaces. Determined to find a solution, we envisioned an app that streamlines meal planning and helps users manage their groceries efficiently. Munch aims to create a supportive community around food management, helping students reclaim their kitchen space and foster a sustainable approach to consumption.

### What it does

Leftover groceries in your dorm and not sure what to make? Munch is a recipe app that allows users to search for recipes based on the ingredients they have on hand. Just point your phone camera at your groceries - Munch will automatically detect the ingredients and suggest recipes sorted by preparation time. Find something interesting? Munch will give you hands-free cooking instruction on every step of the way. Munch is the perfect solution for college students who are looking to make a quick and easy meal with the ingredients they have on hand.

### How we built it

With the help of LangChain and leveraging Google's flagship generative AI models Gemini 1.5 Flash-002 and 1.5 Turbo, we were able to feed the image and get a list of all the ingredients in sight in the photograph provided. With the help of a thoroughly engineered query and Gemini, we were able to list out a bunch of different recipes using the ingredients at hand, categorized by Breakfast, Lunch, Dinner and Snacks, with each recipe being listed with its preparation time. The user can then select which recipe to make. As for the steps, we utilized Hume AI's Empathic Voice Interface (EVI) API with a custom system prompt to be as concise with the steps, while forming complete and coherent sentences, easy for the user to understand. With the EVI's help, the user may request to Restart the recipe, skip or go back to another step, get enhanced details on any particular step, or anything else one might think of while cooking with the help of Gordon Ramsay (excluding "idiot sandwich"). If the user is unable to gain access to the audio in any certain circumstance, they will not be limited to text-to-speech, with a set of instructions as they would hear from the voice model, available on screen. If the user wishes to not use one of the recipe's provided, then they can input the URL to that craft using Perplexity Ai's integrated fast "Answer-engine". The engine will scan the website and generate the name, description, ingredients and steps, and finally allow for hands-free access to that recipe! We came up with a quick, minimalistic and elegant design for the app, with the help of Figma. We used Flask as a mediator to integrate all the files together and Flutter to lay the foundation for Munch.

### Challenges we ran into

Our front-end development hit several roadblocks, primarily with the Hume AI integration into flutter. The unreleased Flutter SDK for Hume posed a significant hurdle. A lack of documentation left us navigating through uncharted territory, making it extremely time consuming to implement Hume's emotional analysis features. We also faced dependency issues with Android packages, which caused multiple compatibility problems. These conflicts meant we had to troubleshoot package versions and configurations, which ate into our development time. Additionally, we struggled with getting a reliable camera feed on Android emulators. This was crucial since our app relies on camera input for scanning groceries, but the inconsistencies in the feed, particularly on Android, disrupted the flow of our testing and user experience. For the hands-free step by step guidance, we initially used Deepgram for Speech-to-Text (STT) and LMNT for Text-to-Speech (TTS) to enable hands-free guidance, but integrating them became too complex and time-consuming. Coordinating voice input and output without delays or errors added significant overhead, limiting our app’s flexibility. Managing dependencies for both STT and TTS created performance challenges, leading us to search for a more efficient solution. Despite all these hurdles, we had a fun, enjoyable, and memorable journey.

### Accomplishments we're proud of

Despite all the problems faced, the team was able to develop a fully functional mobile app with cross platform support in under 48 hours. It just goes to show the resilience and will to surmount problems no matter what. Despite just the 2 of us working, we displayed how passionate we were about building the project, working through the night, keeping each other company. Seeing it work through the stages of development fueled us with motivation to keep going and work till the end.

### What we learned

Throughout the development of Munch, we gained valuable insights into both technical and user experience challenges. We learned the importance of effective integration strategies when dealing with third-party APIs, especially with the unreleased Hume SDK and its limited documentation. This taught us to prioritize clear documentation and community support when choosing tools for future projects. We also discovered how crucial user feedback is in shaping features and functionality. Iterative testing allowed us to refine our approach, ensuring that Munch truly meets the needs of college students. The journey highlighted the importance of adaptability—pivoting from using Deepgram and LMNT for voice guidance to a more streamlined approach with Hume's EVI, ultimately enhancing our app’s usability. Finally, we recognized that collaboration and communication within our team were vital for overcoming obstacles. Our shared passion for the project helped us stay motivated and inspired, reinforcing the belief that resilience and teamwork can lead to meaningful solutions.

### What's next

We had a lot of ideas that we wish to formulate and bring to fruition with Munch, starting off with: 1) Support of YouTube video recipes: While the initial feature of adding support for internet links to recipes was essential for broadening the scope of recipe suggestions, we believe that many people, especially in the digital age, turn to YouTube for cooking tutorials. With Munch, we want to take this convenience a step further by integrating YouTube video support directly into the app. 2) Integrated Log-in System: As of now, our product runs without the user having to log in, reducing the click off rate. But some customers would wish to store their information long term, and some might be returning users. Thus, to ensure their data does remains intact, a log-in system will retain all the recipes they have ever added to our database 3) Grocery Management System: As a part of our motto, working in a time crunch serves to a high priority. Misplacing and then overbuying groceries is a big problem, and we want to help you. After implementation of a log-in system, we will be able to help you keep track how many groceries you have, ask for weekly updates and then when you're running low, suggest you go shopping at the nearest wholesale market. 4) Expanding beyond basic college recipes: As much as we value your time and provide you with the quickest recipes, we also wish to cater to people who derive their hobbies and passions from cooking. Thus, we wish to implement more databases, with more professional recipe from chefs across the globe, thus allowing you to convert your home to a Michelin star restaurant, all through one delectable meal.

## README (from the GitHub repository)

# Munch

Leftover groceries in your dorm and not sure what to make? Munch is a recipe app that allows users to search for recipes based on the ingredients they have on hand. Just point your phone camera at your groceries - Munch will automatically detect the ingredients and suggest recipes sorted by preparation time. Find something interesting? Munch will give you hands-free cooking instruction on every step of the way. Munch is the perfect solution for college students who are looking to make a quick and easy meal with the ingredients they have on hand.


## Detected evidence (automated analysis)

Indexed codebase: 47 recognized source files, 77 KB.
- C (language) — detected in the code
- C++ (language) — detected in the code
- Dart (language) — detected in the code
- Flask (technology) — detected in the code
- HTML (language) — detected in the code
- Kotlin (language) — detected in the code
- LangChain (technology) — detected in the code
- Python (language) — detected in the code
- Swift (language) — detected in the code
- Google Gemini (technology) — claimed on Devpost, not found in the code
- SQL (language) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (104 of 104)

```
.gitignore
backend/addData.py
backend/api.py
backend/recipe_list.py
backend/step_gen.py
backend/stt.py
backend/tts.py
frontend/munch/.gitignore
frontend/munch/.metadata
frontend/munch/analysis_options.yaml
frontend/munch/android/.gitignore
frontend/munch/android/app/build.gradle
frontend/munch/android/app/src/debug/AndroidManifest.xml
frontend/munch/android/app/src/main/AndroidManifest.xml
frontend/munch/android/app/src/main/kotlin/com/example/munch/MainActivity.kt
frontend/munch/android/app/src/main/res/drawable-v21/launch_background.xml
frontend/munch/android/app/src/main/res/drawable/launch_background.xml
frontend/munch/android/app/src/main/res/values-night/styles.xml
frontend/munch/android/app/src/main/res/values/styles.xml
frontend/munch/android/app/src/profile/AndroidManifest.xml
frontend/munch/android/build.gradle
frontend/munch/android/gradle.properties
frontend/munch/android/gradle/wrapper/gradle-wrapper.properties
frontend/munch/android/settings.gradle
frontend/munch/ios/.gitignore
frontend/munch/ios/Flutter/AppFrameworkInfo.plist
frontend/munch/ios/Flutter/Debug.xcconfig
frontend/munch/ios/Flutter/Release.xcconfig
frontend/munch/ios/Runner.xcodeproj/project.pbxproj
frontend/munch/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
frontend/munch/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
frontend/munch/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
frontend/munch/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
frontend/munch/ios/Runner.xcworkspace/contents.xcworkspacedata
frontend/munch/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
frontend/munch/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
frontend/munch/ios/Runner/AppDelegate.swift
frontend/munch/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
frontend/munch/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
frontend/munch/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
frontend/munch/ios/Runner/Base.lproj/LaunchScreen.storyboard
frontend/munch/ios/Runner/Base.lproj/Main.storyboard
frontend/munch/ios/Runner/Info.plist
frontend/munch/ios/Runner/Runner-Bridging-Header.h
frontend/munch/ios/RunnerTests/RunnerTests.swift
frontend/munch/lib/instructions.dart
frontend/munch/lib/main.dart
frontend/munch/lib/show_steps.dart
frontend/munch/lib/string_extensions.dart
frontend/munch/linux/.gitignore
frontend/munch/linux/CMakeLists.txt
frontend/munch/linux/flutter/CMakeLists.txt
frontend/munch/linux/flutter/generated_plugin_registrant.cc
frontend/munch/linux/flutter/generated_plugin_registrant.h
frontend/munch/linux/flutter/generated_plugins.cmake
frontend/munch/linux/main.cc
frontend/munch/linux/my_application.cc
frontend/munch/linux/my_application.h
frontend/munch/macos/.gitignore
frontend/munch/macos/Flutter/Flutter-Debug.xcconfig
frontend/munch/macos/Flutter/Flutter-Release.xcconfig
frontend/munch/macos/Flutter/GeneratedPluginRegistrant.swift
frontend/munch/macos/Runner.xcodeproj/project.pbxproj
frontend/munch/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
frontend/munch/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
frontend/munch/macos/Runner.xcworkspace/contents.xcworkspacedata
frontend/munch/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
frontend/munch/macos/Runner/AppDelegate.swift
frontend/munch/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
frontend/munch/macos/Runner/Base.lproj/MainMenu.xib
frontend/munch/macos/Runner/Configs/AppInfo.xcconfig
frontend/munch/macos/Runner/Configs/Debug.xcconfig
frontend/munch/macos/Runner/Configs/Release.xcconfig
frontend/munch/macos/Runner/Configs/Warnings.xcconfig
frontend/munch/macos/Runner/DebugProfile.entitlements
frontend/munch/macos/Runner/Info.plist
frontend/munch/macos/Runner/MainFlutterWindow.swift
frontend/munch/macos/Runner/Release.entitlements
frontend/munch/macos/RunnerTests/RunnerTests.swift
frontend/munch/pubspec.lock
frontend/munch/pubspec.yaml
frontend/munch/README.md
frontend/munch/test/widget_test.dart
frontend/munch/web/index.html
frontend/munch/web/manifest.json
frontend/munch/windows/.gitignore
frontend/munch/windows/CMakeLists.txt
frontend/munch/windows/flutter/CMakeLists.txt
frontend/munch/windows/flutter/generated_plugin_registrant.cc
frontend/munch/windows/flutter/generated_plugin_registrant.h
frontend/munch/windows/flutter/generated_plugins.cmake
frontend/munch/windows/runner/CMakeLists.txt
frontend/munch/windows/runner/flutter_window.cpp
frontend/munch/windows/runner/flutter_window.h
frontend/munch/windows/runner/main.cpp
frontend/munch/windows/runner/resource.h
frontend/munch/windows/runner/runner.exe.manifest
frontend/munch/windows/runner/Runner.rc
frontend/munch/windows/runner/utils.cpp
frontend/munch/windows/runner/utils.h
frontend/munch/windows/runner/win32_window.cpp
frontend/munch/windows/runner/win32_window.h
README.md
REQUIREMENTS.txt
```

### Dependencies

- REQUIREMENTS.txt: flask, google-generativeai, langchain, langchain_google_genai, python-dotenv

### Recent commits (newest first)

- hume ai
- get recipe steps
- get recipe list
- missed global lmao
- api changes
- added data base and setup
- initialize flutter app
- implement flask api
- remove unneeded image compression function
- use gemini for image classification
- added speech to text with ai integration
- update gemini model to pro 002
- image detection using foodvisor
- added temp tts method
- format response as json
- update recipe prompts
- update gitignore
- third times the charm
- update file organization
- deleting querying.py, replaced with recipeList.py

## Key source files (fetched from GitHub, selected and truncated for size)

### REQUIREMENTS.txt

```
python-dotenv
langchain
google-generativeai
langchain_google_genai
flask
```

### backend/api.py

```python
from flask import Flask, request, jsonify
from recipe_list import generate_recipe_list
from step_gen import generate_steps

app = Flask(__name__)

final_steps = ""

@app.route('/get_recipe_list', methods=['POST'])
def get_recipe_list():
    data = request.files
    file = data.get('image')
    result = generate_recipe_list(file.stream)
    return result.strip(" \n`json")

@app.route('/get_instructions', methods=['POST'])
def get_instructions():
    global final_steps
    data = request.get_json()
    recipe = data.get('recipe')
    ingredients = data.get('ingredients')
    result = generate_steps(recipe, ingredients)
    final_steps = result.strip(" \n`json")
    return result.strip(" \n`json")


if __name__ == "__main__":
    app.run(host='localhost', port=8000)

```

### backend/recipe_list.py

```python
import google.generativeai as genai
import os

genai.configure(api_key=os.environ["GEMINI_API_KEY"])

def generate_recipe_list(filepath):
    model = genai.GenerativeModel("gemini-1.5-pro-002")
    file = genai.upload_file(filepath, mime_type="image/jpeg")
    template = '''
    Generate a list of all possible recipes using only the ingredients in the image.
    Group recipes by time of day.
    Omit all instructions, only give names.
    Add the preparation time to each recipe.
    Keep in mind that the recipes are for a college student, they should be easy to make.
    Format your response as a JSON, using the following template:
    {{
    "detected_ingredients": [
    <strings>,
    ],
    "breakfast": [
    {{"recipe": <name of dish>, "prep_time": <prep time in minutes>}},
    ],
    "lunch": [
    {{"recipe": <name of dish>, "prep_time": <prep time in minutes>}},
    ],
    "dinner": [
    {{"recipe": <name of dish>, "prep_time": <prep time in minutes>}},
    ],
    "snacks": [
    {{"recipe": <name of dish>, "prep_time": <prep time in minutes>}},
    ]
    }}
    '''

    result = model.generate_content(
        [file, '\n\n', template]
    )
    return result.text


if __name__ == '__main__':
    result = generate_recipe_list('data/groceries2.jpg')
    with open("Output.txt","w") as file:
        file.write(result)
```

### backend/tts.py

```python
import os 
from dotenv import load_dotenv
import asyncio
from lmnt.api import Speech
import json

load_dotenv()
LMNT_API_KEY = os.getenv("LMNT_API_KEY")

with open("Output2.txt","r") as file:
    result = json.load(file)

TEXT_TO_SPEECH = result['instructions']

VOICE_ID = 'lily'

async def main():
    async with Speech() as speech:
        connection = await speech.synthesize_streaming(VOICE_ID)
        t1 = asyncio.create_task(reader_task(connection))
        t2 = asyncio.create_task(writer_task(connection))
        await asyncio.gather(t1, t2)

async def reader_task(connection):
    """Streams audio data from LMNT and writes it to `output.mp3`."""
    with open('output.mp3', 'wb') as f:
        async for message in connection:
            f.write(message['audio'])

async def writer_task(connection):
    """Sends each string individually from a list to LMNT for speech synthesis, with a delay."""
    for instruction in TEXT_TO_SPEECH:

        # Append each string (text) to the connection one by one
        await connection.append_text(instruction)
        print(f"Speaking: {instruction}")  # Optionally print each string being processed
        
        # Simulate waiting for your "next" command by pausing for 5 seconds
        print("Waiting for 'next' command...")
        await asyncio.sleep(5)  # Simulating wait time

    # After all the strings are sent, finish the connection
    await connection.finish()


asyncio.run(main())
```

### backend/step_gen.py

```python
import os
from dotenv import load_dotenv
from google.generativeai.types.content_types import *
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

load_dotenv()
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")

parser = StrOutputParser()
llm = ChatGoogleGenerativeAI(model="gemini-1.5-pro-002", api_key=GEMINI_API_KEY)

def generate_steps(recipe, ingredients):
    template = """
    Give a 1-2 line description of the dish
    Detail the recipe to bake this item, for a serving size of one person. Include item names and quantities for the recipe.
    The recipe that I need instructions for is {recipe},
    using only the ingredients: {ingredients}.
    Keep in mind that the recipe is for a college student, it should be easy to make.
    Format your response as a JSON, using the following template:
    {{
    "name": <name of dish>,
    "description": <1-2 line summary about the dish>,
    "ingredients": {{
        <ingredient name>: <quantity>,
    }},
    "instructions": [
        <strings>,
    ]
    }}
    """

    chatPrompt = ChatPromptTemplate.from_template(template)
    chain = chatPrompt | llm | parser

    result = chain.invoke({"recipe":recipe, "ingredients":ingredients})
    return result


if __name__ == '__main__':
    recipe = "Enchiladas with black beans and sweet potato"
    ingredients = '["cut and peel carrots","brussels sprouts","sweet potatoes","romaine hearts","shishito peppers","cauliflower","peanut butter filled pretzel nuggets","blueberries","raspberries","dark sweet cherries","jasmine rice","whole wheat tortillas","farro","nonfat greek yogurt","high protein organic tofu","soy sauce","enchilada sauce","black beans","garbanzo beans","apples","bananas"]'
    result = generate_steps(recipe, ingredients)
    with open("Output2.txt","w") as file:
        file.write(result)
```

### backend/stt.py

```python
import os
from dotenv import load_dotenv
import json
from deepgram import (
    DeepgramClient,
    PrerecordedOptions,
    FileSource,
)
from google.generativeai.types.content_types import *
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser


load_dotenv()

# Path to the audio file (placeholder, will wait on user input)
AUDIO_FILE = "Output.mp3"

DEEPGRAM_API_KEY = os.getenv("DEEPGRAM_API_KEY")
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
parser = StrOutputParser()
llm = ChatGoogleGenerativeAI(model="gemini-1.5-flash-002", api_key=GEMINI_API_KEY)
template =  """You are a fast and accurate text analysis model. Your job is to analyse
a short sentence. The sentence will be spoken in coherent english. The output must be 
chosen from 1 of 5 possible keywords: 
1)START 
2) RESTART
3) NEXT
4) BACK 
5) REPLAY
USE THIS AS AN ABSOLUTE LAST RESORT, but if you dare feel ambiguity, then you
can merely return the keyword "UNINTELLIGIBLE" if you feel you dont understand 
what is being said or how to comprehend it. The response you have to analyse is {response}
THE OUTPUT MUST BE ONE OF THE ABOVE MENTIONED KEYWORDS."""

def callUserInput():
    try:
        # STEP 1 Create a Deepgram client using the API key
        deepgram = DeepgramClient(DEEPGRAM_API_KEY)

        with open(AUDIO_FILE, "rb") as file:
            buffer_data = file.read()

        payload: FileSource = {
            "buffer": buffer_data,
        }

        #STEP 2: Configure Deepgram options for audio analysis
        options = PrerecordedOptions(
            model="nova-2",
            smart_format=True,
        )

        # STEP 3: Call the transcribe_file method with the text payload and options
        response = deepgram.listen.rest.v("1").transcribe_file(payload, options)

        chatPrompt = ChatPromptTemplate.from_template(template)
        chain = chatPrompt | llm | parser

        result = chain.invoke({"response":response})
        # STEP 4: Save the response for later use
        with open("response.json","w") as file:
            data = result.to_json(indent=4)
            json.dump(data, file, indent = 4)
        #response.json now has one of the 6 keywords
    except Exception as e:
        print(f"Exception: {e}")


if __name__ == "__main__":
    callUserInput()

```

### backend/addData.py

```python
import pymysql
import os
from dotenv import load_dotenv
from datetime import datetime
import json

# Load environment variables
load_dotenv()

# Database connection details
connection = pymysql.connect(
    host=os.getenv("MUNCHDB_SERVER"),
    user='admin',
    password=os.getenv("MUNCHDB_PASS"),
    database='munchdbdb',
    port=3306,
    ssl={'ca': 'singlestore_bundle.pem'},
)

# Function to add or update a recipe
def add_or_update_recipe(person_id, person_name, recipe_id, recipe_desc):
    try:
        with connection.cursor() as cursor:
            # Convert recipe_desc from string to dictionary
            recipe_dict = json.loads(recipe_desc)
            # Convert dictionary back to JSON string for storage
            recipe_json_str = json.dumps(recipe_dict)

            # Check if the recipe already exists based on recipe_id
            check_sql = "SELECT recipe_id FROM recipes WHERE recipe_id = %s AND person_id = %s"
            cursor.execute(check_sql, (recipe_id, person_id))
            result = cursor.fetchone()

            current_time = datetime.now()

            if result:
                # Update the recipe while preserving existing information
                update_sql = """
                    UPDATE recipes
                    SET person_name = %s, recipe_desc = %s, last_used = %s
                    WHERE recipe_id = %s AND person_id = %s
                """
                cursor.execute(update_sql, (person_name, recipe_json_str, current_time, recipe_id, person_id))
                print(f"Updated existing recipe for user: {person_name} with recipe ID: {recipe_id}")
            else:
                # Insert new recipe if it doesn't exist
                insert_sql = """
                    INSERT INTO recipes (person_id, recipe_id, person_name, recipe_desc, last_used)
                    VALUES (%s, %s, %s, %s, %s)
                """
                cursor.execute(insert_sql, (person_id, recipe_id, person_name, recipe_json_str, current_time))
                print(f"Inserted new recipe for user: {person_name} with recipe ID: {recipe_id}")

        connection.commit()  # Save the changes to the database
        print("Transaction committed successfully!")

    except Exception as e:
        print(f"Error: {e}")

# Example Usage
recipe_description = """{
  "name": "Quick Scrambled Eggs with Tomatoes and Onions",
  "description": "A simple and satisfying breakfast or light meal featuring scrambled eggs with sautéed tomatoes and onions, topped with cheese.",
  "ingredients": {
    "Eggs": 2,
    "Tomatoes": 0.5,
    "Cheese": "1/4 cup (shredded)",
    "Onions": 0.25,
    "Bread": "1 slice",
    "Jalapenos": "Optional, to taste (1/2 - 1 sliced)"
  },
  "instructions": [
    "Dice the onion and tomato. If using jalapenos, thinly slice them.",
    "Heat a small pan with a little oil or butter over medium heat.",
    "Add the onions to the pan and sauté for 2-3 minutes until softened.",
    "Add the tomatoes (and jalapenos if using) and cook for another 2-3 minutes.",
    "In a bowl, whisk the eggs with a fork. Season with salt and pepper.",
    "Pour the egg mixture into the pan with the vegetables. Stir gently as the eggs cook.",
    "Once the eggs are mostly set but still slightly moist, sprinkle the cheese on top.",
    "Remove from heat and let the cheese melt slightly from the residual heat.",
    "Toast the bread (optional).",
    "Serve the scrambled eggs with the toast. Enjoy!"
  ]
}

"""

# Add or update the recipe
add_or_update_recipe(1, 'Mohak', 101, recipe_description)  # Example recipe_id

# Close the database connection when done
connection.close()

```

### frontend/munch/analysis_options.yaml

```yaml
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
  # The lint rules applied to this project can be customized in the
  # section below to disable rules from the `package:flutter_lints/flutter.yaml`
  # included above or to enable additional rules. A list of all available lints
  # and their documentation is published at https://dart.dev/lints.
  #
  # Instead of disabling a lint rule for the entire project in the
  # section below, it can also be suppressed for a single line of code
  # or a specific dart file by using the `// ignore: name_of_lint` and
  # `// ignore_for_file: name_of_lint` syntax on the line or in the file
  # producing the lint.
  rules:
    # avoid_print: false  # Uncomment to disable the `avoid_print` rule
    # prefer_single_quotes: true  # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

```

### frontend/munch/pubspec.yaml

```yaml
name: munch
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1

environment:
  sdk: ^3.5.1

# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
  flutter:
    sdk: flutter
  
  http: ^0.13.5


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.6
  web_socket_channel: ^3.0.1
  record: ^5.1.2
  audioplayers: ^6.1.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^3.0.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter packages.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  assets:
    - images/shutter_button.png
    - images/groceries2.jpg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages

```

### frontend/munch/linux/main.cc

```c++
#include "my_application.h"

int main(int argc, char** argv) {
  g_autoptr(MyApplication) app = my_application_new();
  return g_application_run(G_APPLICATION(app), argc, argv);
}

```

[35 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]