i cant input into the data points (read only) fix and set default to 150 (decrementPoints is not defined (set to 100)
    the legend overflows to the bottom, end its height with the plot bottom border.
    the plot is too small, allow to view in 80%x80% of the screen in an overlay

import os
from flask import Flask, request, jsonify
from openai import OpenAI
import json
import numpy as np
from sklearn.decomposition import PCA
from scipy.spatial import ConvexHull

app = Flask(__name__)

# Initialize OpenAI client (Ensure you have set the OPENAI_API_KEY environment variable)
client = OpenAI()

def get_embedding(text, model="text-embedding-ada-002"):
    """
    Retrieve the embedding for a given text using OpenAI's API.
    """
    text = text.replace("\n", " ")
    response = client.embeddings.create(input=[text], model=model)
    embedding = response.data[0].embedding
    print(f"Retrieved embedding of length {len(embedding)} for text: '{text}'")  # Debug statement
    return embedding

def get_related_phrases(string_pair, num_related=500):
    """
    Retrieve related phrases based on the input string pair.
    Generates a large number of phrases by combining inputs with various templates.
    
    **Note:** This is a placeholder implementation.
    Replace this with actual logic to fetch related phrases, 
    such as querying a database, using another API, or applying semantic similarity.
    """
    string1, string2 = string_pair
    templates = [
        f"{string1} and {string2} insights",
        f"{string1} strategies near {string2}",
        f"Enhancing {string1} with {string2} data",
        f"Integrating {string1} and {string2} processes",
        f"Optimizing {string1} through {string2}",
        f"Developing {string1} aligned with {string2}",
        f"Analyzing {string1} in the context of {string2}",
        f"Leveraging {string1} for better {string2}",
        f"Implementing {string1} solutions for {string2}",
        f"Evaluating {string1}'s impact on {string2}",
        f"Promoting {string1} alongside {string2}",
        f"Facilitating {string1} and {string2} collaborations",
        f"Supporting {string1} initiatives in {string2}",
        f"Advancing {string1} research related to {string2}",
        f"Charting the course for {string1} and {string2}",
        f"Mapping {string1} trends with {string2}",
        f"Navigating {string1} challenges in {string2}",
        f"Building bridges between {string1} and {string2}",
        f"Creating synergy between {string1} and {string2}",
        f"Fostering innovation in {string1} and {string2}",
        # Add more templates as needed
    ]
    related = []
    for i in range(num_related):
        template = templates[i % len(templates)]
        related.append(f"{template}")  # Removed numbering
    return related

def generate_axis_names(pca_components, context="distance from a natural location to a financial establishment"):
    """
    Generate meaningful axis names using an LLM based on PCA components and context.
    """
    prompt = (
        f"Given the PCA components: {pca_components.tolist()}, and the context of '{context}', "
        "provide three meaningful and significant axis names for a 3D plot. "
        "Respond exactly in JSON format as follows:\n"
        "{\n"
        '  "x_axis": "Axis Name 1",\n'
        '  "y_axis": "Axis Name 2",\n'
        '  "z_axis": "Axis Name 3"\n'
        "}"
    )
    
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "You are an assistant that creates meaningful axis names based on PCA components and context."},
            {"role": "user", "content": prompt}
        ],
        max_tokens=150,
        temperature=0.3,
    )
    
    try:
        axis_names = response['choices'][0]['message']['content']
        axis_dict = json.loads(axis_names)  # Safely parse JSON
        return axis_dict
    except Exception as e:
        print(f"Error parsing axis names from LLM: {e}")
        # Fallback axis names
        return {"x_axis": "Business Growth", "y_axis": "Market Expansion", "z_axis": "Financial Stability"}


@app.route('/')
def index():
    """
    Serve the HTML page for the application.
    """
    html = '''
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Interactive 3D Vector Visualizer</title>
        <style>
            body {
                font-family: Arial, sans-serif;
                background-color: #000000; /* Black background */
                color: #ffffff; /* White text for contrast */
                margin: 0;
                padding: 0;
                display: flex;
                flex-direction: column;
                align-items: center;
                height: 100vh;
                overflow: hidden;
            }
            .container {
                text-align: center;
                margin-top: 20px;
            }
            .input-box {
                margin: 10px;
            }
            #result-container {
                display: flex;
                justify-content: center;
                align-items: flex-start;
                margin-top: 30px;
                width: 90%;
                height: 800px;
            }
            #result {
                width: 800px;      /* Set width to 800px */
                height: 800px;     /* Set height to 800px */
            }
            #legend {
                width: 250px;
                height: 800px;
                overflow-y: scroll; /* Enable scrolling */
                margin-left: 20px;
                background-color: #1a1a1a;
                padding: 10px;
                border-radius: 8px;
                color: #ffffff;
            }
            /* Dark scrollbar */
            #legend::-webkit-scrollbar {
                width: 8px;
            }
            #legend::-webkit-scrollbar-track {
                background: #1a1a1a; 
                border-radius: 4px;
            }
            #legend::-webkit-scrollbar-thumb {
                background: #555555; 
                border-radius: 4px;
            }
            #legend::-webkit-scrollbar-thumb:hover {
                background: #777777; 
            }
            #legend-list {
                list-style: none; /* Remove bullets */
                padding: 0;
                margin: 0;
            }
            #legend-list li {
                margin-bottom: 5px;
                cursor: pointer;
                padding: 5px;
                border-radius: 4px;
                transition: background-color 0.3s;
                color: #ffffff;
            }
            #legend-list li:hover {
                background-color: #333333;
            }
            .collapsible {
                background-color: #1a1a1a;
                color: #ffffff;
                cursor: pointer;
                padding: 10px;
                width: 100%;
                border: none;
                text-align: left;
                outline: none;
                font-size: 16px;
                border-radius: 4px;
                transition: background-color 0.3s;
            }
            .active, .collapsible:hover {
                background-color: #333333;
            }
            .content {
                padding-left: 15px;
                display: none;
                overflow: hidden;
                background-color: #242424;
                border-radius: 4px;
            }
            .content li {
                padding: 5px;
                margin: 3px 0;
                border-radius: 4px;
                transition: background-color 0.3s;
                color: #dddddd;
                font-size: 14px;
            }
            .content li:hover {
                background-color: #555555;
                color: #ffffff;
            }
            input[type="text"] {
                padding: 8px;
                width: 300px;
                border: none;
                border-radius: 4px;
                margin-left: 10px;
                font-size: 1em;
                background-color: #1a1a1a;
                color: #ffffff;
            }
            .num-points {
                display: flex;
                align-items: center;
                justify-content: center;
                margin-top: 10px;
            }
            .num-points button {
                width: 30px;
                height: 30px;
                background-color: #333333;
                border: none;
                color: #ffffff;
                font-size: 1.2em;
                cursor: pointer;
                border-radius: 4px;
                margin: 0 5px;
            }
            .num-points button:hover {
                background-color: #555555;
            }
            .num-points label {
                margin-left: 10px;
                font-size: 1em;
                color: #ffffff;
            }
            button.submit-button {
                padding: 10px 20px;
                background-color: #00ffff; /* Neon Cyan */
                border: none;
                border-radius: 4px;
                cursor: pointer;
                font-weight: bold;
                margin-top: 20px;
                font-size: 1em;
            }
            button.submit-button:hover {
                background-color: #00cccc;
            }
            h1 {
                color: #00ffea; /* Neon-like title color */
                text-shadow: 0 0 10px #00ffea, 0 0 20px #00ffea;
            }
            label {
                color: #ffffff;
                font-size: 1.1em;
            }
            /* Directional Control Panel Styles */
            .control-panel {
                position: absolute;
                bottom: 20px;
                left: 50%;
                transform: translateX(-50%);
                display: flex;
                gap: 10px;
            }
            .control-button {
                width: 50px;
                height: 50px;
                background-color: #333333;
                border: none;
                border-radius: 50%;
                cursor: pointer;
                display: flex;
                align-items: center;
                justify-content: center;
            }
            .control-button img {
                width: 24px;
                height: 24px;
            }
            .control-button:hover {
                background-color: #555555;
            }
            /* Responsive Adjustments */
            @media (max-width: 1200px) {
                #result-container {
                    flex-direction: column;
                    align-items: center;
                }
                #legend {
                    width: 90%;
                    height: 200px;
                    margin-left: 0;
                    margin-top: 20px;
                }
                #result {
                    width: 90%;
                    height: 600px;
                }
            }
        </style>
        <!-- Include Plotly.js -->
        <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    </head>
    <body>
    <div class="container">
        <h1>Interactive 3D Vector Visualizer</h1>
        <div class="input-box">
            <label for="string1">Input String 1:</label>
            <input type="text" id="string1" name="string1" placeholder="e.g., financial river bank institute">
        </div>
        <div class="input-box">
            <label for="string2">Input String 2:</label>
            <input type="text" id="string2" name="string2" placeholder="e.g., river bank place by the river">
        </div>
        <div class="input-box">
            <label for="string3">Input String 3:</label>
            <input type="text" id="string3" name="string3" placeholder="e.g., sustainability initiatives">
        </div>
        <div class="input-box">
            <label for="string4">Input String 4:</label>
            <input type="text" id="string4" name="string4" placeholder="e.g., community outreach programs">
        </div>
        <div class="num-points">
            <button onclick="decrementPoints()" title="Decrease number of data points">-</button>
            <input type="number" id="numPoints" name="numPoints" value="500" min="2" max="1000" title="Number of data points" readonly>
            <button onclick="incrementPoints()" title="Increase number of data points">+</button>
            <label for="numPoints">Data Points</label>
        </div>
        <button class="submit-button" onclick="submitStrings()" title="Generate and visualize data points">Submit</button>
        <div id="result-container">
            <div id="result"></div>
            <div id="legend">
                <ul id="legend-list"></ul>
            </div>
        </div>
    </div>
    
    <!-- Directional Control Panel -->
    <div class="control-panel">
        <button class="control-button" onclick="rotateLeft()" title="Rotate left">
            <img src="https://img.icons8.com/ios-filled/50/ffffff/left.png" alt="Left">
        </button>
        <button class="control-button" onclick="rotateRight()" title="Rotate right">
            <img src="https://img.icons8.com/ios-filled/50/ffffff/right.png" alt="Right">
        </button>
        <button class="control-button" onclick="zoomIn()" title="Zoom in">
            <img src="https://img.icons8.com/ios-filled/50/ffffff/zoom-in.png" alt="Zoom In">
        </button>
        <button class="control-button" onclick="zoomOut()" title="Zoom out">
            <img src="https://img.icons8.com/ios-filled/50/ffffff/zoom-out.png" alt="Zoom Out">
        </button>
        <button class="control-button" onclick="panUp()" title="Pan up">
            <img src="https://img.icons8.com/ios-filled/50/ffffff/up-left.png" alt="Pan Up">
        </button>
        <button class="control-button" onclick="panDown()" title="Pan down">
            <img src="https://img.icons8.com/ios-filled/50/ffffff/down-left.png" alt="Pan Down">
        </button>
        <button class="control-button" onclick="changeView()" title="Change view perspective">
            <img src="https://img.icons8.com/ios-filled/50/ffffff/repeat.png" alt="Change View">
        </button>
    </div>
    
    <script>
        let currentHighlightedIndex = null;
        let originalData = null;
        let currentView = 0; // 0: Original, 1: Swap X and Y, 2: Swap X and Z
    
        function decrementPoints() {
            const numPointsInput = document.getElementById('numPoints');
            let currentValue = parseInt(numPointsInput.value);
            if (currentValue > 10) {
                numPointsInput.value = currentValue - 10;
            }
        }
    
        function incrementPoints() {
            const numPointsInput = document.getElementById('numPoints');
            let currentValue = parseInt(numPointsInput.value);
            if (currentValue < 1000) {
                numPointsInput.value = currentValue + 10;
            }
        }
    
        async function submitStrings() {
            const string1 = document.getElementById('string1').value.trim();
            const string2 = document.getElementById('string2').value.trim();
            const string3 = document.getElementById('string3').value.trim();
            const string4 = document.getElementById('string4').value.trim();
            const numPoints = parseInt(document.getElementById('numPoints').value);
    
            if (!string1 || !string2 || !string3 || !string4) {
                alert('Please provide all four input strings.');
                return;
            }
    
            if (isNaN(numPoints) || numPoints < 2 || numPoints > 1000) {
                alert('Please enter a valid number of data points between 2 and 1000.');
                return;
            }
    
            try {
                const response = await fetch('/compute', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ 
                        string1, 
                        string2, 
                        string3, 
                        string4, 
                        num_points: numPoints 
                    })
                });
    
                if (!response.ok) {
                    const errorData = await response.json();
                    alert(`Error: ${errorData.error}`);
                    return;
                }
    
                const result = await response.json();
                originalData = JSON.parse(JSON.stringify(result.data)); // Deep copy for view changes
                renderPlot(result.data);
                populateLegend(result.data.legend);
            } catch (error) {
                console.error('Error:', error);
                alert('An error occurred while processing your request.');
            }
        }
    
        function renderPlot(data) {
            const trace1 = {
                x: data.x1,
                y: data.y1,
                z: data.z1,
                mode: 'markers+lines',
                type: 'scatter3d',
                marker: {
                    size: 4,
                    color: 'cyan',
                    line: {
                        color: 'white',
                        width: 0.5
                    }
                },
                line: {
                    color: 'magenta',
                    width: 1
                },
                hoverinfo: 'text',
                text: data.hover_text1,
                name: data.legend[0]
            };
    
            const trace2 = {
                x: data.x2,
                y: data.y2,
                z: data.z2,
                mode: 'markers+lines',
                type: 'scatter3d',
                marker: {
                    size: 4,
                    color: 'orange',
                    line: {
                        color: 'white',
                        width: 0.5
                    }
                },
                line: {
                    color: 'blue',
                    width: 1
                },
                hoverinfo: 'text',
                text: data.hover_text2,
                name: data.legend[1]
            };
    
            const plotData = [trace1, trace2];
    
            const layout = {
                paper_bgcolor: 'black',
                plot_bgcolor: 'black',
                scene: {
                    xaxis: { color: 'white', title: data.axis_names.x_axis },
                    yaxis: { color: 'white', title: data.axis_names.y_axis },
                    zaxis: { color: 'white', title: data.axis_names.z_axis },
                },
                margin: { l: 0, r: 20, b: 0, t: 0 }
            };
    
            Plotly.newPlot('result', plotData, layout, {responsive: true, displayModeBar: false});
        }
    
        function populateLegend(labels) {
            const legendList = document.getElementById('legend-list');
            legendList.innerHTML = '';
    
            labels.forEach((label, setIndex) => {
                // Create main set list item
                const setItem = document.createElement('li');
                setItem.textContent = label;
                setItem.classList.add('collapsible');
                setItem.dataset.setIndex = setIndex;
    
                // Create nested list for phrases
                const phrasesList = document.createElement('ul');
                phrasesList.classList.add('content');
    
                if (setIndex === 0) {
                    originalData.x1.forEach((x, i) => {
                        const phraseItem = document.createElement('li');
                        phraseItem.textContent = originalData.labels1[i];
                        phraseItem.dataset.trace = 0; // Trace 1
                        phraseItem.dataset.point = i;
                        phraseItem.addEventListener('click', () => highlightPoint(setIndex, i));
                        phrasesList.appendChild(phraseItem);
                    });
                } else if (setIndex === 1) {
                    originalData.x2.forEach((x, i) => {
                        const phraseItem = document.createElement('li');
                        phraseItem.textContent = originalData.labels2[i];
                        phraseItem.dataset.trace = 1; // Trace 2
                        phraseItem.dataset.point = i;
                        phraseItem.addEventListener('click', () => highlightPoint(setIndex, i));
                        phrasesList.appendChild(phraseItem);
                    });
                }
    
                setItem.appendChild(phrasesList);
                legendList.appendChild(setItem);
    
                // Add event listener to toggle visibility of phrases
                setItem.addEventListener('click', function() {
                    this.classList.toggle('active');
                    const content = this.querySelector('.content');
                    if (content.style.display === "block") {
                        content.style.display = "none";
                    } else {
                        content.style.display = "block";
                    }
                });
            });
        }
    
        function highlightPoint(setIndex, pointIndex) {
            // Reset previous highlights
            Plotly.restyle('result', {
                'marker.color': ['cyan', 'orange'],
                'marker.size': [4, 4],
                'line.color': ['magenta', 'blue']
            }, [0,1]);
    
            // Highlight selected point
            Plotly.restyle('result', {
                'marker.color': [`rgba(255,0,0,1)`, `rgba(255,0,0,1)`],
                'marker.size': [6, 6],
                'line.color': ['yellow', 'yellow']
            }, [setIndex, setIndex]);
        }
    
        function removeHighlight() {
            if (currentHighlightedIndex !== null) {
                Plotly.restyle('result', {
                    'marker.color': ['cyan', 'orange'],
                    'marker.size': [4, 4],
                    'line.color': ['magenta', 'blue']
                }, [0,1]);
                currentHighlightedIndex = null;
            }
        }
    
        function changeView() {
            if (!originalData) return;
    
            currentView = (currentView + 1) % 3; // Cycle through 0,1,2
    
            let newData = JSON.parse(JSON.stringify(originalData)); // Deep copy
    
            if (currentView === 1) { // Swap X and Y
                [newData.x1, newData.y1] = [newData.y1, newData.x1];
                [newData.x2, newData.y2] = [newData.y2, newData.x2];
                Plotly.relayout('result', {
                    'scene.xaxis.title.text': newData.axis_names.y_axis,
                    'scene.yaxis.title.text': newData.axis_names.x_axis
                });
            } else if (currentView === 2) { // Swap X and Z
                [newData.x1, newData.z1] = [newData.z1, newData.x1];
                [newData.x2, newData.z2] = [newData.z2, newData.x2];
                Plotly.relayout('result', {
                    'scene.xaxis.title.text': newData.axis_names.z_axis,
                    'scene.zaxis.title.text': newData.axis_names.x_axis
                });
            } else { // Original
                Plotly.relayout('result', {
                    'scene.xaxis.title.text': newData.axis_names.x_axis,
                    'scene.yaxis.title.text': newData.axis_names.y_axis,
                    'scene.zaxis.title.text': newData.axis_names.z_axis,
                });
            }
    
            Plotly.restyle('result', {
                'x': [newData.x1, newData.x2],
                'y': [newData.y1, newData.y2],
                'z': [newData.z1, newData.z2],
                'text': [newData.hover_text1, newData.hover_text2]
            }, [0,1]);
        }
    
        // Control Panel Functions with Increased Precision
        function rotateLeft() {
            const layout = document.getElementById('result')._fullLayout;
            const camera = layout.scene.camera.eye;
            const newX = camera.x + 0.01;  // Increased precision
            const newZ = camera.z + 0.01;  # Adjust Z for more natural rotation
            Plotly.relayout('result', {
                'scene.camera.eye.x': newX,
                'scene.camera.eye.z': newZ
            });
        }
    
        function rotateRight() {
            const layout = document.getElementById('result')._fullLayout;
            const camera = layout.scene.camera.eye;
            const newX = camera.x - 0.01;  # Increased precision
            const newZ = camera.z - 0.01;  # Adjust Z for more natural rotation
            Plotly.relayout('result', {
                'scene.camera.eye.x': newX,
                'scene.camera.eye.z': newZ
            });
        }
    
        function zoomIn() {
            const layout = document.getElementById('result')._fullLayout;
            const zoom = layout.scene.camera.zoom;
            Plotly.relayout('result', {
                'scene.camera.zoom': zoom * 0.99  # Smaller zoom step
            });
        }
    
        function zoomOut() {
            const layout = document.getElementById('result')._fullLayout;
            const zoom = layout.scene.camera.zoom;
            Plotly.relayout('result', {
                'scene.camera.zoom': zoom * 1.01  # Smaller zoom step
            });
        }
    
        function panUp() {
            const layout = document.getElementById('result')._fullLayout;
            const centerY = layout.scene.camera.center.y;
            Plotly.relayout('result', {
                'scene.camera.center.y': centerY + 0.01  # Increased precision
            });
        }
    
        function panDown() {
            const layout = document.getElementById('result')._fullLayout;
            const centerY = layout.scene.camera.center.y;
            Plotly.relayout('result', {
                'scene.camera.center.y': centerY - 0.01  # Increased precision
            });
        }
    </script>
    </body>
    </html>
    '''
    return html


@app.route('/compute', methods=['POST'])
def compute():
    """
    Handle computation and return the processed data for plotting.
    Expecting four input strings and the number of data points.
    """
    data = request.json
    string1 = data.get('string1', '').strip()
    string2 = data.get('string2', '').strip()
    string3 = data.get('string3', '').strip()
    string4 = data.get('string4', '').strip()
    num_points = data.get('num_points', 500)

    # Ensure all four strings are provided
    if not string1 or not string2 or not string3 or not string4:
        return jsonify({'error': 'All four input strings must be provided.'}), 400

    if not isinstance(num_points, int) or num_points < 2 or num_points > 1000:
        return jsonify({'error': 'num_points must be an integer between 2 and 1000.'}), 400

    try:
        # Prepare datasets
        datasets = []
        colors = ['cyan', 'orange']  # Colors for the two datasets
        labels_group = ['Correlation Set 1', 'Correlation Set 2']

        # Set 1: string1 and string2
        related_phrases1 = get_related_phrases((string1, string2), num_related=num_points)
        embeddings1 = [get_embedding(phrase) for phrase in related_phrases1]
        labels1 = related_phrases1

        datasets.append({
            'x': [emb[0] for emb in embeddings1],
            'y': [emb[1] for emb in embeddings1],
            'z': [emb[2] for emb in embeddings1],
            'labels': labels1,
            'color': colors[0],
            'group': labels_group[0]
        })

        # Set 2: string3 and string4
        related_phrases2 = get_related_phrases((string3, string4), num_related=num_points)
        embeddings2 = [get_embedding(phrase) for phrase in related_phrases2]
        labels2 = related_phrases2

        datasets.append({
            'x': [emb[0] for emb in embeddings2],
            'y': [emb[1] for emb in embeddings2],
            'z': [emb[2] for emb in embeddings2],
            'labels': labels2,
            'color': colors[1],
            'group': labels_group[1]
        })

        # Combine all data for PCA
        all_x = []
        all_y = []
        all_z = []
        all_labels = []
        group_labels = []

        for dataset in datasets:
            all_x.extend(dataset['x'])
            all_y.extend(dataset['y'])
            all_z.extend(dataset['z'])
            all_labels.extend(dataset['labels'])
            group_labels.extend([dataset['group']] * len(dataset['labels']))

        combined_embeddings = np.column_stack((all_x, all_y, all_z))

        # Perform PCA
        pca = PCA(n_components=3)
        reduced_embeddings = pca.fit_transform(combined_embeddings)

        # Generate axis names using LLM
        axis_names = generate_axis_names(pca.components_, context="distance from a natural location to a financial establishment")

        # Assign the reduced embeddings back to datasets
        start = 0
        for dataset in datasets:
            end = start + len(dataset['x'])
            dataset['x'] = reduced_embeddings[start:end, 0].tolist()
            dataset['y'] = reduced_embeddings[start:end, 1].tolist()
            dataset['z'] = reduced_embeddings[start:end, 2].tolist()
            dataset['hover_text'] = [
                f"X: {item[0]:.4f}<br>Y: {item[1]:.4f}<br>Z: {item[2]:.4f}<br>Content: {content}"
                for item, content in zip(
                    reduced_embeddings[start:end, :],
                    dataset['labels']
                )
            ]
            start = end

        # Prepare legend items
        legend_items = [dataset['group'] for dataset in datasets]

        # Prepare response data
        response_data = {
            'axis_names': axis_names,
            'x1': datasets[0]['x'],
            'y1': datasets[0]['y'],
            'z1': datasets[0]['z'],
            'hover_text1': datasets[0]['hover_text'],
            'x2': datasets[1]['x'],
            'y2': datasets[1]['y'],
            'z2': datasets[1]['z'],
            'hover_text2': datasets[1]['hover_text'],
            'legend': legend_items,
            'labels1': labels1,
            'labels2': labels2
        }

        return jsonify({'data': response_data})
    except Exception as e:
        print(f"Error during computation: {e}")  # Debug statement
        return jsonify({'error': 'An internal error occurred. Please try again later.'}), 500


@app.route('/axis_names', methods=['POST'])
def axis_names_endpoint():
    """
    Optional endpoint to fetch axis names separately if needed.
    """
    pass  # Not used in current implementation


if __name__ == '__main__':
    # Run the Flask app
    app.run(port=5005, debug=True)