this is my js of my app. What changes must doing in prompt for generate dialogues so that they are based on the output from the previous generate story?  <script>
    // Check if html2canvas is loaded
    if (typeof html2canvas === 'undefined') {
      console.error('html2canvas library not loaded');
      // Fallback to load the library dynamically if needed
      const script = document.createElement('script');
      script.src = 'https://html2canvas.hertzen.com/dist/html2canvas.min.js';
      script.onload = () => console.log('html2canvas loaded dynamically');
      document.head.appendChild(script);
    }

    // Convert RGB color to Hex
    const rgbToHex = (rgb) => {
      // If already hex, return as is
      if (rgb.startsWith('#')) return rgb;
      
      // Extract RGB values
      const rgbMatch = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)/i);
      if (!rgbMatch) return '#000000'; // Default to black if invalid

      const r = parseInt(rgbMatch[1]);
      const g = parseInt(rgbMatch[2]);
      const b = parseInt(rgbMatch[3]);

      // Convert to hex
      const toHex = (n) => {
        const hex = n.toString(16);
        return hex.length === 1 ? '0' + hex : hex;
      };

      return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
    };

    // Utility Function for Displaying Messages
    const displayMessage = (element, message, type) => {
      element.textContent = message;
      element.style.display = 'block';
      element.className = type === 'error' ? 'error-message' : 'success-message';
      setTimeout(() => {
        element.style.display = 'none';
      }, 5000);
    };

    // Validate Form Inputs
    const validateForm = () => {
      const form = document.getElementById('comic-form');
      const requiredFields = form.querySelectorAll('[required]:not(#art-style)'); // Exclude art style
      let isValid = true;
      requiredFields.forEach(field => {
        if (!field.value.trim()) {
          isValid = false;
          field.classList.add('input-error');
        } else {
          field.classList.remove('input-error');
        }
      });
      return isValid;
    };

    // Fetch API Wrapper with Error Handling
    const fetchAPI = async (url, options) => {
      try {
        const response = await fetch(url, options);
        if (!response.ok) throw new Error(`Error: ${response.status} ${response.statusText}`);
        return response;
      } catch (error) {
        throw error;
      }
    };

    // Function to Generate Story
    const generateStory = async () => {
      const errorMessage = document.getElementById('error-message');
      const successMessage = document.getElementById('success-message');
      const loading = document.getElementById('loading-story');
      const storyPreview = document.getElementById('story-preview');
      const generateImageBtn = document.getElementById('generate-combined-image');

      errorMessage.style.display = 'none';
      successMessage.style.display = 'none';
      storyPreview.style.display = 'none';
      generateImageBtn.style.display = 'none';

      if (!validateForm()) {
        displayMessage(errorMessage, 'Please fill in all required fields correctly.', 'error');
        return;
      }

      loading.style.display = 'block';

      try {
        const char1Name = document.getElementById('char1-name').value.trim();
        const char1Desc = document.getElementById('char1-description').value.trim();
        const char2Name = document.getElementById('char2-name').value.trim();
        const char2Desc = document.getElementById('char2-description').value.trim();
        const storyOutline = document.getElementById('story-outline').value.trim();
        const sceneDesc = document.getElementById('scene-description').value.trim();

        const prompt = `Compose a 4-panel strip story featuring two characters: ${char1Name} (${char1Desc}) and ${char2Name} (${char2Desc}). Based on the following inputs:

- **Story Outline:** ${storyOutline}
- **Scene Description:** ${sceneDesc}

Please create a cohesive and engaging narrative broken down into four distinct visual scenes without any dialogue. Each panel should clearly depict a sequential part of the story, emphasizing the characters' actions and emotions.`;

        const response = await fetchAPI('https://text.pollinations.ai/', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            messages: [
              { role: 'system', content: 'You are a creative story strip writer.' },
              { role: 'user', content: prompt }
            ],
            model: 'openai',
            jsonMode: false
          }),
        });

        const data = await response.text();

        // Display the generated story
        storyPreview.querySelector('p').innerHTML = data.replace(/\n/g, '<br>');
        storyPreview.style.display = 'block';
        
        // Show art style section along with generate comic strip button
        document.getElementById('art-style-section').style.display = 'block';
        generateImageBtn.style.display = 'inline-block';
        
        window.storyData = data; // Store story data globally
        displayMessage(successMessage, 'Story generated successfully!', 'success');
      } catch (error) {
        displayMessage(errorMessage, error.message || 'Failed to generate story. Please try again.', 'error');
        console.error('Error:', error);
      } finally {
        loading.style.display = 'none';
      }
    };

    // Function to Generate Combined Image
    const generateCombinedImage = () => {
      const loadingImage = document.getElementById('loading-image');
      const combinedImageContainer = document.getElementById('combined-image-container');
      const combinedComicImage = document.getElementById('combined-comic-image');
      const errorMessage = document.getElementById('error-message');
      const successMessage = document.getElementById('success-message');
      const generateDialoguesBtn = document.getElementById('generate-dialogues');

      errorMessage.style.display = 'none';
      successMessage.style.display = 'none';
      combinedImageContainer.style.display = 'none';
      generateDialoguesBtn.style.display = 'none';

      try {
        const artStyle = document.getElementById('art-style').value;
        const char1Name = document.getElementById('char1-name').value.trim();
        const char2Name = document.getElementById('char2-name').value.trim();

        const scenes = window.storyData.split('\n').filter(scene => scene.trim()).slice(0, 4);
        if (scenes.length < 4) {
          throw new Error('Insufficient number of scenes to create a 4-panel story.');
        }

        const prompt = `Generate a single high-resolution image (1024x1024 pixels) of a 4-panel story strip arranged in a 2x2 grid, featuring two characters: ${char1Name} and ${char2Name} in the ${artStyle} style. Based on the following scene descriptions:

- **Panel 1:** ${scenes[0]}
- **Panel 2:** ${scenes[1]}
- **Panel 3:** ${scenes[2]}
- **Panel 4:** ${scenes[3]}

Ensure that:

1. **Consistent Design:** Both characters maintain consistent appearances, expressions, and postures across all panels.
2. **Art Style Adherence:** The entire strip adheres to the specified ${artStyle}, reflecting its unique aesthetic.
3. **Seamless Transitions:** Scenes flow logically from one panel to the next, showcasing a coherent and engaging storyline.
4. **No Text or Dialogues:** Exclude any textual elements, speech bubbles, or dialogues from the image.
5. **Visual Clarity:** Each panel should clearly represent the described scene with distinct and recognizable actions and emotions.
6. **High Quality:** The final image should be free from logos, watermarks, and maintain high visual fidelity.

Provide the 4 panel image without any annotations or additional elements outside the specified parameters.`;

        const encodedPrompt = encodeURIComponent(prompt);
        const imageUrl = `https://image.pollinations.ai/prompt/${encodedPrompt}?model=flux&width=1024&height=1024&nologo=true&private=true`;

        // Display the loading indicator
        loadingImage.style.display = 'block';

        // Once the image is loaded, display it
        combinedComicImage.onload = () => {
          loadingImage.style.display = 'none';
          combinedImageContainer.style.display = 'block';
          
          // Hide generate comic strip button and show generate dialogues button
          document.getElementById('generate-combined-image').style.display = 'none';
          generateDialoguesBtn.style.display = 'inline-block';
          
          displayMessage(successMessage, 'Comic strip generated successfully!', 'success');
        };

        combinedComicImage.onerror = () => {
          loadingImage.style.display = 'none';
          displayMessage(errorMessage, 'Failed to load the comic strip image. Please try again.', 'error');
        };

        // Set the image source
        combinedComicImage.src = imageUrl;

      } catch (error) {
        displayMessage(errorMessage, error.message || 'Failed to generate the combined comic image.', 'error');
        console.error('Error generating combined image:', error);
      }
    };

    // Function to Generate Dialogues
    const generateDialogues = async () => {
      const errorMessage = document.getElementById('error-message');
      const successMessage = document.getElementById('success-message');
      const loading = document.getElementById('loading-dialogues');
      const dialogues = [];
      
      errorMessage.style.display = 'none';
      
      try {
        loading.style.display = 'block';
        
        // Extract necessary data
        const storyData = window.storyData; // Assuming this contains the generated story
        const panels = window.storyData.split('\n').filter(scene => scene.trim()).slice(0, 4);
        const artStyle = document.getElementById('art-style').value;
        const char1Name = document.getElementById('char1-name').value.trim();
        const char1Desc = document.getElementById('char1-description').value.trim();
        const char2Name = document.getElementById('char2-name').value.trim();
        const char2Desc = document.getElementById('char2-description').value.trim();
        
        // Generate dialogues for each panel
        for (let i = 0; i < panels.length; i++) {
          const prompt = `For Panel ${i + 1} of a 4-panel comic strip featuring ${char1Name} (${char1Desc}) and ${char2Name} (${char2Desc}) in the ${artStyle} style, based on the following scene description:

"${panels[i]}"

Generate a concise and contextually appropriate dialogue between ${char1Name} and ${char2Name}. The dialogue should reflect the characters' personalities and emotions conveyed in the scene, matching the overall narrative style. Limit the dialogue to 2 lines maximum.`;

          const response = await fetchAPI('https://text.pollinations.ai/', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              messages: [
                { role: 'system', content: 'You are a skilled dialogue writer for comic strips.' },
                { role: 'user', content: prompt }
              ],
              model: 'openai',
              jsonMode: true
            }),
          });
          
          const data = await response.text();
          dialogues.push(data.trim());
        }
        
        // Store dialogues globally
        window.dialogueData = dialogues;

        // After successfully generating dialogues, hide the generate dialogues button
        document.getElementById('generate-dialogues').style.display = 'none';
        
        // Show customization panel
        const customizationPanel = document.getElementById('customization-panel');
        customizationPanel.style.display = 'block';

        // Render dialogues on the comic strip
        renderDialogues(dialogues);
        displayMessage(successMessage, 'Dialogues generated successfully!', 'success');
        
      } catch (error) {
        displayMessage(errorMessage, error.message || 'Failed to generate dialogues. Please try again.', 'error');
        console.error('Error:', error);
      } finally {
        loading.style.display = 'none';
      }
    };

    // Function to Render Dialogues
    const renderDialogues = (dialogues) => {
      const combinedComicImage = document.getElementById('combined-comic-image');
      
      // Ensure the image container is positioned relatively to place absolute elements inside
      const container = document.getElementById('combined-image-container');
      container.style.position = 'relative';
      
      // Create a separate container for dialogues over the image
      const dialoguesContainer = document.createElement('div');
      dialoguesContainer.id = 'dialogues-container';
      dialoguesContainer.style.position = 'absolute';
      dialoguesContainer.style.top = '0';
      dialoguesContainer.style.left = '0';
      dialoguesContainer.style.width = '100%';
      dialoguesContainer.style.height = '100%';
      // Removed pointer-events: none to allow interaction with bubbles
      container.appendChild(dialoguesContainer);

      // Clear existing dialogue bubbles if any
      const existingBubbles = container.querySelectorAll('.dialogue-bubble');
      existingBubbles.forEach(bubble => bubble.remove());
      
      // Create dialogue bubbles for each panel
      dialogues.forEach((dialogue, index) => {
        const bubble = document.createElement('div');
        bubble.className = 'dialogue-bubble speech tail-down'; // Default style and tail direction
        bubble.style.backgroundColor = `rgba(255, 255, 255, 0.85)`; // Apply fixed opacity
        bubble.setAttribute('data-bubble-style', 'speech'); // Default style attribute
        bubble.setAttribute('data-id', `bubble-${Date.now()}-${index}`); // Unique ID for tracking
        bubble.contentEditable = 'true';
        bubble.innerText = dialogue;
        
        // Add Delete Button
        const deleteBtn = document.createElement('button');
        deleteBtn.className = 'delete-button';
        deleteBtn.innerHTML = '&times;';
        deleteBtn.title = 'Delete Bubble';
        bubble.appendChild(deleteBtn);
        
        // Positioning logic based on panel
        // Assuming panels are laid out in a 2x2 grid
        // Adjust positions as needed
        switch(index) {
          case 0:
            bubble.style.top = '10%';
            bubble.style.left = '10%';
            break;
          case 1:
            bubble.style.top = '10%';
            bubble.style.right = '10%';
            break;
          case 2:
            bubble.style.bottom = '10%';
            bubble.style.left = '10%';
            break;
          case 3:
            bubble.style.bottom = '10%';
            bubble.style.right = '10%';
            break;
          default:
            bubble.style.top = '10%';
            bubble.style.left = '10%';
        }
        
        dialoguesContainer.appendChild(bubble);
        
        // Make the bubble draggable and resizable
        makeInteractive(bubble);
        
        // Event Listener for Delete Button
        deleteBtn.addEventListener('click', (e) => {
          e.stopPropagation(); // Prevent triggering bubble selection
          bubble.remove();
        });
        
        // Event Listener for Selecting a Bubble
        bubble.addEventListener('click', (e) => {
          e.stopPropagation(); // Prevent event bubbling
          document.querySelectorAll('.dialogue-bubble').forEach(b => b.classList.remove('selected'));
          bubble.classList.add('selected');
          openCustomizationPanel(bubble);
        });
        
        // Optional: Double-Click to Open Customization Panel
        bubble.addEventListener('dblclick', (e) => {
          e.stopPropagation();
          openCustomizationPanel(bubble);
        });
      });
    };

    // Function to Make Dialogue Bubbles Interactive
    const makeInteractive = (element) => {
      interact(element)
        .draggable({
          inertia: true,
          modifiers: [
            interact.modifiers.restrictRect({
              restriction: 'parent',
              endOnly: true
            })
          ],
          autoScroll: true,
          listeners: {
            move: dragMoveListener,
            end(event) {
              // Reset the position attributes after dragging ends
              const target = event.target;
              const x = parseFloat(target.getAttribute('data-x')) || 0;
              const y = parseFloat(target.getAttribute('data-y')) || 0;

              target.style.transform = `translate(${x}px, ${y}px)`;
            }
          }
        })
        .resizable({
          edges: { left: true, right: true, bottom: true, top: true },
          inertia: true,
          modifiers: [
            interact.modifiers.restrictSize({
              min: { width: 80, height: 40 },
              max: { width: 400, height: 200 }
            })
          ],
          listeners: {
            move: resizeMoveListener,
            end(event) {
              const target = event.target;
              // Reset the position attributes after resizing ends
              const x = parseFloat(target.getAttribute('data-x')) || 0;
              const y = parseFloat(target.getAttribute('data-y')) || 0;

              target.style.transform = `translate(${x}px, ${y}px)`;
            }
          }
        });
    };

    // Drag Move Listener
    const dragMoveListener = (event) => {
      const target = event.target;
      // Keep the dragged position in the data attribute
      const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
      const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

      // Translate the element
      target.style.transform = `translate(${x}px, ${y}px)`;
      
      // Update the position attributes
      target.setAttribute('data-x', x);
      target.setAttribute('data-y', y);
    };

    // Resize Move Listener
    const resizeMoveListener = (event) => {
      const target = event.target;
      
      // Update the element's style
      let { width, height } = event.rect;
      target.style.width = `${width}px`;
      target.style.height = `${height}px`;
      
      // Change the position based on event.delta
      let x = parseFloat(target.getAttribute('data-x')) || 0;
      let y = parseFloat(target.getAttribute('data-y')) || 0;

      target.style.transform = `translate(${x}px, ${y}px)`;
    };

    // Function to Open the Customization Panel
    const openCustomizationPanel = (bubble) => {
      const customizationPanel = document.getElementById('customization-panel');
      
      // Populate the customization panel with current styles
      const fontStyle = window.getComputedStyle(bubble).fontFamily.replace(/['"]/g, "");
      const fontSize = parseInt(window.getComputedStyle(bubble).fontSize);
      const textColor = rgbToHex(window.getComputedStyle(bubble).color);
      const bubbleColor = window.getComputedStyle(bubble).backgroundColor;
      
      // Set font style
      const fonts = document.getElementById('font-style');
      if ([...fonts.options].some(option => option.value === fontStyle)) {
        fonts.value = fontStyle;
      } else {
        fonts.value = 'Poppins'; // Default if selected font is not available
      }

      // Set font size
      document.getElementById('font-size').value = fontSize;

      // Set text color
      document.getElementById('text-color').value = rgbToHex(window.getComputedStyle(bubble).color);

      // Set bubble background color (without opacity)
      const rgbMatch = bubbleColor.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+),\s*(\d+\.?\d*)\)/i);
      if (rgbMatch) {
        const bgColor = `#${((1 << 24) + (parseInt(rgbMatch[1]) << 16) + (parseInt(rgbMatch[2]) << 8) + parseInt(rgbMatch[3])).toString(16).slice(1)}`;
        document.getElementById('bubble-color').value = bgColor;
      } else {
        document.getElementById('bubble-color').value = '#FFFFFF';
      }
      
      // Set bubble style
      const currentBubbleStyle = bubble.getAttribute('data-bubble-style') || 'speech';
      document.getElementById('bubble-style').value = currentBubbleStyle;

      // Set tail direction
      const currentTailDirection = getTailDirection(bubble);
      document.getElementById('tail-direction').value = currentTailDirection;
      
      // Show the customization panel
      customizationPanel.style.display = 'block';
      customizationPanel.setAttribute('aria-hidden', 'false');
    };

    // Function to Get Current Tail Direction
    const getTailDirection = (bubble) => {
      if (bubble.classList.contains('tail-top')) return 'top';
      if (bubble.classList.contains('tail-down')) return 'down';
      if (bubble.classList.contains('tail-left')) return 'left';
      if (bubble.classList.contains('tail-right')) return 'right';
      return 'down'; // Default
    };

    // Function to Close the Customization Panel
    const closeCustomizationPanel = () => {
      const customizationPanel = document.getElementById('customization-panel');
      customizationPanel.style.display = 'none';
      // Remove selected state from all bubbles
      document.querySelectorAll('.dialogue-bubble').forEach(bubble => bubble.classList.remove('selected'));
    };

    // Make customization panel draggable
    const makeCustomizationPanelDraggable = () => {
      const panel = document.getElementById('customization-panel');
      const header = panel.querySelector('.panel-header');
      let isDragging = false;
      let currentX;
      let currentY;
      let initialX;
      let initialY;
      let xOffset = 0;
      let yOffset = 0;

      const dragStart = (e) => {
        e.preventDefault();
        if (e.type === "touchstart") {
          initialX = e.touches[0].clientX - xOffset;
          initialY = e.touches[0].clientY - yOffset;
        } else {
          initialX = e.clientX - xOffset;
          initialY = e.clientY - yOffset;
        }

        if (e.target === header || e.target.parentNode === header) {
          isDragging = true;
        }
      };

      const dragEnd = () => {
        isDragging = false;
      };

      const drag = (e) => {
        if (isDragging) {
          e.preventDefault();

          if (e.type === "touchmove") {
            currentX = e.touches[0].clientX - initialX;
            currentY = e.touches[0].clientY - initialY;
          } else {
            currentX = e.clientX - initialX;
            currentY = e.clientY - initialY;
          }

          xOffset = currentX;
          yOffset = currentY;

          panel.style.transform = `translate(${currentX}px, ${currentY}px)`;
        }
      };

      // Add event listeners
      header.addEventListener('mousedown', dragStart);
      document.addEventListener('mousemove', drag);
      document.addEventListener('mouseup', dragEnd);
      header.addEventListener('touchstart', dragStart);
      document.addEventListener('touchmove', drag);
      document.addEventListener('touchend', dragEnd);

      // Add close button functionality
      const closeButton = panel.querySelector('.close-button');
      closeButton.addEventListener('click', () => {
        closeCustomizationPanel();
      });
    };

    // Call this function when the page loads
    window.addEventListener('load', () => {
      makeCustomizationPanelDraggable();
    });

    // Function to Apply Customizations
    const applyCustomizations = () => {
      const selectedBubble = document.querySelector('.dialogue-bubble.selected');
      if (!selectedBubble) return;

      // Get customization values
      const fontStyle = document.getElementById('font-style').value;
      const fontSize = document.getElementById('font-size').value;
      const textColor = document.getElementById('text-color').value;
      const bubbleColor = document.getElementById('bubble-color').value;
      const bubbleStyle = document.getElementById('bubble-style').value;
      const tailDirection = document.getElementById('tail-direction').value;

      // Apply styles
      selectedBubble.style.fontFamily = fontStyle;
      selectedBubble.style.fontSize = `${fontSize}px`;
      selectedBubble.style.color = textColor;
      selectedBubble.style.backgroundColor = hexToRGBA(bubbleColor, 0.80); // Fixed opacity at 0.80

      // Apply bubble style and tail direction
      selectedBubble.classList.remove('speech', 'thought', 'narration', 'tail-down', 'tail-left', 'tail-right', 'tail-top');
      selectedBubble.classList.add(bubbleStyle);

      if (bubbleStyle === 'speech' || bubbleStyle === 'thought') {
        selectedBubble.classList.add(`tail-${tailDirection}`);
      }

      selectedBubble.setAttribute('data-bubble-style', bubbleStyle);

      // Close the customization panel
      closeCustomizationPanel();
    };

    // Function to Reset Customizations
    const resetCustomizations = () => {
      const selectedBubble = document.querySelector('.dialogue-bubble.selected');
      if (!selectedBubble) return;

      // Reset to default styles
      selectedBubble.style.fontFamily = 'Poppins';
      selectedBubble.style.fontSize = '14px';
      selectedBubble.style.color = '#000000';
      selectedBubble.style.backgroundColor = 'rgba(255, 255, 255, 0.80)';

      selectedBubble.classList.remove('speech', 'thought', 'narration', 'tail-down', 'tail-left', 'tail-right', 'tail-top');
      selectedBubble.classList.add('speech', 'tail-down');
      selectedBubble.setAttribute('data-bubble-style', 'speech');

      // Close the customization panel
      closeCustomizationPanel();
    };

    // Function to Convert Hex to RGBA
    const hexToRGBA = (hex, opacity) => {
      const bigint = parseInt(hex.slice(1), 16);
      const r = (bigint >> 16) & 255;
      const g = (bigint >> 8) & 255;
      const b = bigint & 255;

      return `rgba(${r}, ${g}, ${b}, ${opacity})`;
    };

    // Event Listener for Apply Button in Customization Panel
    document.getElementById('apply-customization').addEventListener('click', applyCustomizations);

    // Event Listener for Reset Button in Customization Panel
    document.getElementById('reset-customization').addEventListener('click', resetCustomizations);

    // Function to Initialize Event Listeners for Story Generation
    const generateStoryFunction = async () => {
      const generateStoryButton = document.getElementById('generate-story');
      generateStoryButton.addEventListener('click', generateStory);
    };

    // Function to Initialize Event Listeners for Combined Image Generation
    const generateCombinedImageFunction = () => {
      const generateImageButton = document.getElementById('generate-combined-image');
      generateImageButton.addEventListener('click', generateCombinedImage);
    };

    // Function to Initialize Event Listeners for Dialogues Generation
    const generateDialoguesFunction = () => {
      const generateDialoguesButton = document.getElementById('generate-dialogues');
      generateDialoguesButton.addEventListener('click', generateDialogues);
    };

    // Initialize All Event Listeners
    const initializeApp = () => {
      generateStoryFunction();
      generateCombinedImageFunction();
      generateDialoguesFunction();
    };

    // Call Initialize Function on Page Load
    window.onload = initializeApp;

    // Close customization panel when clicking outside of it
    document.addEventListener('click', (e) => {
      const customizationPanel = document.getElementById('customization-panel');
      const isClickInsidePanel = customizationPanel.contains(e.target);
      const isClickOnBubble = e.target.classList.contains('dialogue-bubble');

      if (!isClickInsidePanel && !isClickOnBubble) {
        customizationPanel.style.display = 'none';
        // Remove selected state from all bubbles
        document.querySelectorAll('.dialogue-bubble').forEach(bubble => bubble.classList.remove('selected'));
      }
    });
  </script>