{"version":3,"sources":["jsdelivr-header.js","/npm/1ff-chat-ui@1.0.47/src/lib/chat-ui.js"],"names":[],"mappings":"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","file":"/npm/1ff-chat-ui@1.0.47/src/lib/chat-ui.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.19.2.\n * Original file: /npm/1ff-chat-ui@1.0.47/src/lib/chat-ui.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import { io } from 'socket.io-client';\nimport {\n  chatMarkup,\n  getDisplayInfo,\n  imageMarkup,\n  initiatorProfile,\n  paymentHeader,\n  rolesHTML,\n  timeMarkup,\n  getPopUp,\n  videoMarkup,\n} from './chat-widgets';\nimport { styles } from './styles';\nimport { assistant } from './config/assistant';\nimport { events } from './config/events';\nimport { roles } from './config/roles';\nimport { socketConfig } from './config/socket';\nimport { theme } from './config/theme';\nimport { translations } from './config/translations';\nimport cssMinify from './css-minify';\nimport {\n  constructLink,\n  extractStringWithBrackets,\n  getAnswerConfig,\n  getTerm,\n  getUserId,\n  initializeAddClassMethod,\n  isExpired,\n  splitText,\n  clearCarets,\n  getStringInAngleBrackets,\n} from './helpers';\nimport { emailLoader, errorMessage, input, loadingDots, resendButton, scroll } from './utils';\nimport {\n  onChatHistory,\n  onConnect,\n  onDisconnect,\n  onStreamData,\n  onStreamEnd,\n  onStreamError,\n  onStreamStart,\n  socketEmitChat,\n} from './socket-services';\nimport { actionService } from './action-service';\nimport { customEventTypes, standardEventTypes } from './custom/tracking-events';\nimport { experimentsPrompt } from '../../src/lib/config/prompts-affected';\n\nconst nodeEvents = require('events');\n\nexport const intentions = new nodeEvents.EventEmitter();\nexport const STORAGE_KEY = 'history';\nexport const CHAT_SEEN_KEY = 'chatSeen';\nexport const ALREADY_REGISTERED_KEY = 'showAlreadyRegisteredUser';\nexport const SHOW_PAYMENT_BUTTON_KEY = 'showPaymentButton';\nexport const SOCKET_IO_URL = 'http://localhost:5000';\nexport const UNSENT_MESSAGES_KEY = 'unsent';\nexport const GO_THROUGH_QUIZ_KEY = 'hasToGoThroughQuiz';\nexport const EXISTING_PRODUCT_LINK_KEY = 'existingProductLink';\n\nexport const intentionType = {\n  email: 'email_intent',\n  payment: 'payment_intent',\n  emailError: 'email_validation_error',\n  emailSuccess: 'email_validation_success',\n};\n\nconst ChatUi = {\n  theme,\n  assistant,\n  events,\n  roles,\n  socketConfig,\n  translations,\n  socket: null,\n  elements: null,\n  userId: null,\n  term: null,\n  url: null,\n  link: null,\n  initialHeight: null,\n  containerId: 'chatbot-container',\n  typingEvents: [],\n  timeStart: null,\n  timerId: null,\n  typingTimerIds: [],\n  answersFromStream: '',\n  boldedText: '',\n  video: '',\n  showModalForRegisteredUser: '',\n  showPaymentButton: '',\n  lastQuestionData: {\n    term: '',\n    user_id: '',\n    message: '',\n    role: roles.user,\n  },\n  /**\n   * Initializes the chat module.\n   * @param {object} config - The configuration object.\n   * @example\n   * // Example usage:\n   * const config = {\n   *   url: 'http://localhost:5000',\n   *   assistantConfig: {\n   *      image: 'https://assets.appsforfit.com/assets/avatars/practitioner-1.png',\n   *      role: 'Lead Nutrition Expert, PhD',\n   *      name: 'Jenny Wilson',\n   *      welcome: 'Chat for 1 min, and get diet advise for free!',\n   *      ctaTextContent: 'Customize Your Plan!',\n   *   },\n   *   customTheme: {\n   *      '--lumina': '#f0f2f5',\n   *      '--whisper': '#ffffff',\n   *      '--seraph': '#21bb5a',\n   *      '--ember': '#cacadb',\n   *      '--zephyr': '43, 49, 57',\n   *      '--enigma': '#FFAE19',\n   *   },\n   * };\n   * init(config);\n   */\n  init(config = {}) {\n    if (this.shouldHideChat()) {\n      this.closeSocket();\n      return;\n    }\n    this.setConfig(config);\n    this.setMessageObject();\n    this.setCustomVars();\n    this.setDomContent();\n    this.setSocket();\n    this.setIntentionEvents();\n    this.setImageFullScreen();\n  },\n  setImageFullScreen() {\n    document.querySelector('body').addEventListener('click', (e) => {\n      console.log('document', document);\n      if (e.target.classList.contains('media-image')) {\n        const fullScreen = document.querySelector('.fullscreen-background-filter');\n        fullScreen.querySelector('img').src = e.target.src;\n        fullScreen.classList.toggle('show-image');\n      }\n    });\n  },\n  setIntentionEvents() {\n    intentions.on(intentionType.emailError, (response) => {\n      emailLoader.hide();\n      this.elements.emailInput.disabled = false;\n      this.elements.sendButton.style.pointerEvents = 'auto';\n      this.lastQuestionData.message = '';\n\n      if (response.status === 409) {\n        this.track(customEventTypes.emailExist);\n        localStorage.setItem(ALREADY_REGISTERED_KEY, 'true');\n        this.showOptionsForRegisteredUser();\n        return;\n      }\n\n      if (response.status === 422) {\n        this.elements.errorEmail.textContent = response.errors.email[0];\n        this.elements.errorEmail.classList.remove('hidden');\n        this.track(customEventTypes.emailWrong);\n      }\n    });\n\n    intentions.on(intentionType.emailSuccess, () => {\n      this.lastQuestionData.message = this.elements.emailInput.value;\n      this.appendHtml({ role: roles.user, content: this.elements.emailInput.value });\n      socketEmitChat(this);\n      emailLoader.hide();\n\n      input.hide(this);\n      store.set('answers', { 'saved-email': this.elements.emailInput.value });\n      this.elements.emailInput.value = '';\n      this.elements.emailInput.addClass('hidden');\n      this.track(customEventTypes.emailEntered);\n    });\n  },\n  setConfig(config) {\n    this.url = config.url || SOCKET_IO_URL;\n    this.containerId = config.containerId || this.containerId;\n    // optional parts of the config that need to be initialized as object at least\n    config.assistantConfig = config.assistantConfig || {};\n    config.customTheme = config.customTheme || {};\n    config.translations = config.translations || {};\n\n    this.socketConfig = config.socketConfig || this.socketConfig;\n    this.theme = { ...this.theme, ...config.customTheme };\n    this.assistant = { ...this.assistant, ...config.assistantConfig };\n    this.mainContainer = document.getElementById(this.containerId);\n    this.translations = { ...this.translations, ...config.translations };\n    this.showModalForRegisteredUser = localStorage.getItem(ALREADY_REGISTERED_KEY);\n    this.showPaymentButton = localStorage.getItem(SHOW_PAYMENT_BUTTON_KEY);\n    this.hasToGoThroughQuiz = localStorage.getItem(GO_THROUGH_QUIZ_KEY);\n  },\n  setMessageObject() {\n    this.lastQuestionData.term = getTerm();\n    this.lastQuestionData.user_id = getUserId();\n  },\n  loadUserHistory(history) {\n    input.show(this);\n    this.elements.messageIncrementor.appendChild(timeMarkup(history[0].time));\n\n    this.historyTraverse(history);\n\n    const { content } = history.pop();\n    const lastMessageByAssistant = this.getLastMessageElement('.assistant');\n    this.link = lastMessageByAssistant.querySelector('a');\n\n    if (this.hasToGoThroughQuiz) {\n      this.showSuccessfulPaymentMessage();\n      return;\n    }\n\n    if (this.link) {\n      this.setCtaButton();\n      if(getTerm() === experimentsPrompt.finalPage){\n        this.link.remove();\n      }\n    }\n\n    if (content.includes(intentionType.email)) {\n      this.setEmailVisibility();\n    }\n\n    if (this.showModalForRegisteredUser) {\n      this.showOptionsForRegisteredUser();\n    }\n\n    if (content.includes(intentionType.payment) || this.showPaymentButton) {\n      this.setPaymentIntent();\n    }\n  },\n  historyTraverse(history) {\n    let counter = 1;\n    let isLastMessage = false;\n    history.forEach((data) => {\n      let appended = false;\n\n      if (counter > 1) {\n        let updatedContent = actionService.clearButtonCodes(data.content);\n        updatedContent = clearCarets(updatedContent);\n        data.content = updatedContent;\n      }\n      if (counter === history.length) {\n        isLastMessage = true;\n      }\n      if (counter === 1) {\n        if (data.content.includes('^')) {\n          appended = true;\n          this.initMedia(data.content);\n          this.initNewLine(data, isLastMessage);\n        }\n      }\n      if (!appended) {\n        this.appendHtml(data, isLastMessage);\n        this.initMedia(data.content);\n      }\n\n      counter++;\n    });\n  },\n  initNewLine(data, isLastMessage) {\n    const splittedContent = splitText(data.content, '^');\n\n    for (let i = 0; i < splittedContent.length; i++) {\n      data.content = splittedContent[i];\n      const newData = {\n        ...data,\n        content: splittedContent[i],\n      };\n      this.appendHtml(newData, isLastMessage);\n    }\n  },\n  initMedia(content) {\n    const link = getStringInAngleBrackets(content);\n    const extractedLink = link[0];\n    if (extractedLink) {\n      this.appendMedia(extractedLink);\n    }\n  },\n  appendUnsentMessage() {\n    const data = {\n      content: localStorage.getItem(UNSENT_MESSAGES_KEY),\n      time: new Date().toISOString(),\n      role: roles.user,\n    };\n    this.appendHtml(data);\n    this.onError();\n  },\n  shouldHideChat() {\n    const { time } = this.getLastUserMessage();\n    let hasExpired;\n\n    if (time) {\n      hasExpired = isExpired(time);\n    }\n\n    // when time has expired chatSeen must be removed from localStorage\n    if (hasExpired) {\n      localStorage.removeItem(CHAT_SEEN_KEY);\n    }\n\n    // when user has clicked on ctaButton chatSeen is being set to true\n    const chatSeen = localStorage.getItem(CHAT_SEEN_KEY);\n\n    return chatSeen === 'true' ? true : false;\n  },\n  getLastUserMessage() {\n    const messages = JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];\n    const messageFound = messages.reverse().find((message) => message.role === roles.user);\n    const lastMessage = messageFound ? messageFound : {};\n\n    return lastMessage;\n  },\n  /**\n   * Closes the socket connection if it is open.\n   *\n   * @returns {void}\n   */\n  closeSocket() {\n    this.socket && this.socket.close();\n  },\n  /**\n   * Initializes the socket connection with the server.\n   * It connects to the server using the specified URL and socket options.\n   * Sets up event listeners for all events defined\n   *\n   * @returns {void}\n   */\n  setSocket() {\n    this.socket = io.connect(this.url, this.socketConfig);\n    this.socket.on(this.events.connect, onConnect.bind(this));\n    this.socket.on(this.events.disconnect, onDisconnect.bind(this));\n    this.socket.on(this.events.chatHistory, onChatHistory.bind(this));\n    this.socket.on(this.events.streamStart, onStreamStart.bind(this));\n    this.socket.on(this.events.streamData, onStreamData.bind(this));\n    this.socket.on(this.events.streamEnd, onStreamEnd.bind(this));\n    this.socket.on(this.events.streamError, onStreamError.bind(this));\n    // TODO do something on server error\n    // this.socket.on(\"error\", (reason) => {});\n  },\n  processTextInCaseOfSquareBrackets() {\n    if (this.chunk.includes('[')) {\n      this.answersFromStream = this.chunk;\n    } else if (this.answersFromStream) {\n      this.answersFromStream += this.chunk;\n    }\n\n    if (this.answersFromStream.includes(']')) {\n      if (this.answersFromStream.includes(intentionType.payment)) {\n        this.setPaymentIntent();\n        return;\n      }\n\n      if (this.answersFromStream.includes(intentionType.email)) {\n        this.setEmailVisibility();\n        return;\n      }\n\n      this.answersFromStream = actionService.clearButtonCodes(this.answersFromStream);\n      this.addOptions();\n      this.chunk = '';\n    }\n  },\n  processTextInCaseOfCurlyBrackets() {\n    if (this.chunk.includes('{')) {\n      this.boldedText = this.chunk;\n      this.chunk = '';\n    }\n\n    if (this.boldedText || (this.boldedText && this.chunk.includes('}'))) {\n      this.boldedText += this.chunk;\n      this.chunk = '';\n    }\n\n    if (this.boldedText.includes('}')) {\n      this.link = constructLink(this.boldedText);\n      if (this.link) {\n        this.setCtaButton();\n      }\n\n      let strongTaggedText = this.boldedText.replace('{', '').replace('}', '');\n      strongTaggedText = `<strong>${strongTaggedText}</strong>`;\n      const lastMessageTextContainer = this.getLastMessageElement('.assistant .js-assistant-message');\n      lastMessageTextContainer.innerHTML += strongTaggedText;\n      this.boldedText = '';\n    }\n  },\n  processStringInCaseOfAngleBrackets() {\n    if (this.chunk.includes('<')) {\n      this.answersFromStream = this.chunk;\n    }\n\n    if (this.answersFromStream.includes('>')) {\n      this.answersFromStream = this.answersFromStream.replace('<', '').replace('>', '');\n      console.log('this.answersFromStream', this.answersFromStream);\n      this.appendMedia(this.answersFromStream);\n      this.answersFromStream = '';\n      this.chunk = '';\n    }\n  },\n  refreshLocalStorageHistory(history) {\n    localStorage.setItem(STORAGE_KEY, JSON.stringify(history));\n  },\n  singleChoice(e) {\n    let textContent = e.currentTarget.textContent;\n    this.lastQuestionData.message = textContent;\n    const data = {\n      role: roles.user,\n      content: textContent,\n      time: new Date().toISOString(),\n    };\n    if (this.isFirstUserMessage()) {\n      this.track(customEventTypes.firstMessage);\n      this.track(customEventTypes.buttonClick + e.currentTarget.dataset.sequence);\n    }\n    socketEmitChat(this);\n    this.appendHtml(data);\n\n    const answersContainer = document.querySelector('.answers-container');\n\n    if (answersContainer) {\n      answersContainer.remove();\n    }\n  },\n  addOptions() {\n    const element = this.getLastMessageElementConsistingMessage('.assistant');\n    const answerConfig = getAnswerConfig(this.answersFromStream);\n    const answersContainer = document.createElement('div');\n    const moveBtnNumber = '10';\n    answersContainer.classList.add('answers-container');\n    [...answerConfig.list].forEach((answer, index) => {\n      let optionElement = document.createElement('div');\n      optionElement.textContent = answer.content;\n      optionElement.setAttribute('data-sequence', (index + 1).toString());\n      optionElement = actionService.handleAction(optionElement, answer.actions, answersContainer);\n      optionElement.addEventListener('click', this[answerConfig.answersType].bind(this));\n      answersContainer.appendChild(optionElement);\n    });\n    this.answersFromStream = '';\n\n    [...answerConfig.list].forEach((btn) => {\n      if (!btn.actions.includes(moveBtnNumber)) {\n        element.appendChild(answersContainer);\n      }\n    });\n  },\n  getLastMessageElement(role) {\n    return this.elements.messageIncrementor.querySelectorAll(role)[\n      this.elements.messageIncrementor.querySelectorAll(role).length - 1\n    ];\n  },\n  getLastMessageElementConsistingMessage(role) {\n    const parentElements = this.elements.messageIncrementor.querySelectorAll(role);\n    var lastElement = null;\n\n    for (let i = parentElements.length - 1; i >= 0; i--) {\n      const parent = parentElements[i];\n      const child1 = parent.querySelector('.js-assistant-message');\n      if (child1) {\n        lastElement = parent;\n        break; // Exit the loop as soon as a match is found\n      }\n    }\n\n    return lastElement;\n  },\n  isFirstUserMessage() {\n    let history = JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];\n\n    return !history.find((obj) => {\n      return obj.role === roles.user;\n    });\n  },\n  /**\n   * It shows the CTA button, sets the href attribute to the link, and hides the prompt container.\n   *\n   * @param {string} link - The link to be set.\n   * @returns {void}\n   */\n  setCtaButton() {\n    this.elements.ctaButton.classList.remove('hidden');\n    this.attachLinkEventListener();\n    if (getTerm() === experimentsPrompt.finalPage) {\n      this.setCtaButtonToClose();\n    } else {\n      this.elements.ctaButton.setAttribute('href', this.link);\n    }\n    input.hide(this);\n    this.track(customEventTypes.linkProvided);\n    this.elements.ctaButton.addEventListener('click', () => {\n      this.track(customEventTypes.linkClicked);\n    });\n  },\n\n  setCtaButtonToClose(){\n    this.elements.ctaButton.setAttribute('href', 'javascript:void(0)');\n\n    this.elements.ctaButton.addEventListener('click', (e) => {\n      e.preventDefault();\n      this.closeWidget();\n    });\n  },\n\n  attachLinkEventListener() {\n    const links = document.querySelectorAll('.js-assistant-message a');\n    const link = links[links.length - 1];\n\n    if (link) {\n      link.addEventListener('click', () => {\n        this.track(customEventTypes.linkClicked);\n        this.closeWidget();\n      });\n    }\n  },\n\n  /**\n   * Sets custom variables and applies them to the main container element and font family.\n   * Theme-specific properties are handled separately.\n   *\n   * @returns {void}\n   */\n  setCustomVars() {\n    Object.entries(this.theme).forEach(([property, value]) => {\n      this.mainContainer.style.setProperty(property, value);\n    });\n  },\n  /**\n   * Sets the DOM content of the chat widget by creating and appending the necessary HTML elements,\n   * applying the provided styles, setting up the widget elements, and attaching event listeners.\n   *\n   * @returns {void}\n   */\n  setDomContent() {\n    const style = document.createElement('style');\n    this.initialHeight = window.innerHeight;\n    style.textContent = cssMinify(styles(this.initialHeight));\n    this.mainContainer.classList.add('chat-container');\n    this.mainContainer.innerHTML += chatMarkup(this);\n    this.mainContainer.appendChild(style);\n    this.setElements();\n    this.elements.messageIncrementor.appendChild(initiatorProfile(this));\n    scroll.remove();\n    this.attachListeners();\n    initializeAddClassMethod();\n  },\n  setElements() {\n    this.elements = {\n      chatbotContainer: document.getElementById('chatbot-container'),\n      messageInput: document.getElementById('chat-prompt'),\n      sendButton: document.getElementById('send-button'),\n      messageIncrementor: document.getElementById('message-incrementor'),\n      closeButton: document.getElementById('close-widget'),\n      ctaButton: document.getElementById('cta-button'),\n      promptContainer: document.getElementById('prompt-container'),\n      loadingDots: document.querySelector('.js-wave'),\n      paymentButton: document.getElementById('chat-pay'),\n      paymentContainer: document.getElementById('primer-form-container'),\n      closePaymentButton: document.querySelector('.close-payment-form'),\n      paymentViewForm: document.getElementById('chat-payment-view'),\n      emailInput: document.getElementById('chat-email'),\n      errorEmail: document.querySelector('.js-error-email'),\n      paymentFormLoader: document.querySelector('.js-payment-form-loader'),\n    };\n  },\n  /**\n   * Appends the HTML content to the chat message container.\n   *\n   * @param {Object} data - The chat message data object.\n   * @returns {void}\n   */\n  appendHtml(data, isLastMessage = false) {\n    const { role, content } = data;\n    const result = rolesHTML[role](content);\n    this.elements.messageIncrementor.appendChild(result.element || result);\n    this.setLastMessageButtons(result.extractedString, isLastMessage);\n  },\n  // logic with last message buttons should be refactored\n  setLastMessageButtons(extractedString, isLastMessage) {\n    if ([intentionType.payment, intentionType.email].includes(extractedString)) {\n      return;\n    }\n    if (extractedString && extractedString !== '' && isLastMessage) {\n      input.hide(this);\n      this.answersFromStream = '[' + extractedString + ']';\n      this.addOptions();\n    }\n  },\n  /**\n   * Sends the initial message to the socket server.\n   * If the socket is connected, it emits the chat event with the last question data.\n   * If the socket is disconnected, it appends the last question data to the local storage history.\n   *\n   * @returns {void}\n   */\n  sendAssistantInitialMessage() {\n    this.assistant.initialMessage.content = this.formatInitialMessage(this.assistant.initialMessage.content);\n\n    const data = {\n      ...this.lastQuestionData,\n      role: roles.assistant,\n      message: this.assistant.initialMessage.content,\n    };\n\n    this.socket.emit(this.events.chat, data);\n  },\n\n  /**\n   * Loads initial message from the assistant object and checks if the message contains any brackets.\n   * If it does, it extracts the string between the brackets and sets the initial message to the extracted string.\n   * It also adds the options to the chat widget.\n   * If the message doesn't contain any brackets, it sets the initial message to the message content.\n   * It also hides the input field and adds the options to the chat widget.media-image\n   *\n   * @returns {void}\n   */\n  async loadAssistantInitialMessage() {\n    await this.loadInitialMessageSettings();\n\n    loadingDots.show();\n    this.sendAssistantInitialMessage();\n\n    await this.delay(1500);\n\n    loadingDots.hide();\n    const { extractedString, updatedMessage } = extractStringWithBrackets(this.assistant.initialMessage.content);\n    const link = getStringInAngleBrackets(this.assistant.initialMessage.content);\n    const extractedLink = link[0];\n\n    const data = {\n      content: updatedMessage,\n      ...this.assistant.initialMessage,\n    };\n    this.elements.messageIncrementor.appendChild(timeMarkup(data.time));\n    if (extractedLink) {\n      this.appendMedia(extractedLink);\n    }\n    if (data.content.includes('^')) {\n      const splitMessage = splitText(data.content, '^');\n      await this.appendHtmlInChunks(splitMessage, data);\n    } else {\n      this.appendHtml(data);\n    }\n\n    // this.addImageAction();\n    if (extractedString) {\n      this.hideInput(extractedString);\n    }\n  },\n\n  async loadInitialMessageSettings() {\n    let actionCodes = actionService.getActionCodes(\n      this.assistant.initialMessage.content,\n      actionService.ACTION_CODE_REGEX,\n    );\n\n    let popUpHtml = getPopUp(actionCodes[0]);\n\n    if (popUpHtml) {\n      this.elements.chatbotContainer.appendChild(popUpHtml);\n      setTimeout(() => {\n        document.querySelector('.modal-wrapper').classList.add('hidden');\n      }, 3000);\n\n      await this.delay(3000);\n    }\n  },\n\n  /**\n   *\n   * @param {*} extractedLink\n   * appends the media (image/video) to the initial message\n   */\n  appendMedia(extractedLink) {\n    const mediaBody = document.createElement('span');\n    mediaBody.classList.add('assistant');\n    if (extractedLink.includes('www.youtube.com')) {\n      mediaBody.appendChild(videoMarkup(extractedLink));\n    } else {\n      mediaBody.appendChild(imageMarkup(extractedLink));\n    }\n    this.elements.messageIncrementor.appendChild(mediaBody);\n  },\n\n  /**\n   * adds new message to lastQuestionData.message, clears the input field and visualizes it\n   *\n   * @returns {void}\n   */\n  addNewMessage() {\n    if (!this.elements.emailInput.classList.contains('hidden')) {\n      this.emailSendHandler();\n      return;\n    }\n\n    if (this.isFirstUserMessage()) {\n      this.track(customEventTypes.firstMessage);\n    }\n\n    const content = this.elements.messageInput.value.trim();\n    this.typingHandler();\n    input.focus(this);\n\n    if (content === '') {\n      return;\n    }\n\n    const data = { role: roles.user, content, time: new Date().toISOString() };\n    const lastMessages = this.lastQuestionData.message ? this.lastQuestionData.message.split('\\n') : [];\n    lastMessages.push(content);\n    this.lastQuestionData.message = lastMessages.join('\\n');\n\n    this.appendHtml(data);\n    this.elements.messageInput.value = '';\n  },\n  /**\n   * Handles the error event by updating the last user message element to allow resending the message.\n   * It adds a click event listener to the element and removes the hidden class from the resend icon.\n   *\n   * @returns {void}\n   */\n  onError() {\n    window.debugMode && console.log('onError: ', this);\n    loadingDots.hide();\n    errorMessage.show();\n    resendButton.hideAll();\n    const { content } = this.getLastUserMessage();\n    this.lastQuestionData.message = localStorage.getItem(UNSENT_MESSAGES_KEY) || content;\n    resendButton.show(this);\n  },\n  /**\n   * Retrieves the last user message element from the message incrementor.\n   * If the element exists, it clones and replaces it to ensure it is the latest instance.\n   *\n   * @returns {Element|null} - The last user message element if found, otherwise null.\n   */\n  getLastUserMessageElement() {\n    const oldChild = this.getLastMessageElement('.user');\n\n    if (oldChild) {\n      const newLast = oldChild.cloneNode(true);\n      oldChild.parentNode.replaceChild(newLast, oldChild);\n      return newLast;\n    }\n    return null;\n  },\n  /**\n   * Closes the widget by clearing the main container, closing the socket connection,\n   * and setting the chat as seen in localStorage.\n   *\n   * @returns {void}\n   */\n  closeWidget() {\n    this.mainContainer.innerHTML = '';\n    scroll.add();\n    this.closeSocket();\n    localStorage.setItem(CHAT_SEEN_KEY, true);\n  },\n  goBack() {\n    this.closeSocket();\n    history.back();\n  },\n  /**\n   * Attaches event listeners to the chat widget elements.\n   *\n   * @returns {void}\n   */\n  attachListeners() {\n    this.elements.closeButton?.addEventListener('click', this.goBack.bind(this));\n    this.elements.sendButton.addEventListener('click', this.addNewMessage.bind(this));\n    this.elements.ctaButton.addEventListener('click', this.closeWidget.bind(this));\n    this.elements.messageInput.addEventListener('keydown', this.onKeyDown.bind(this));\n    this.elements.emailInput.addEventListener('keydown', this.onKeyDownEmail.bind(this));\n    this.elements.paymentButton.addEventListener('click', this.emitPaymentIntentions.bind(this));\n    window.onresize = this.onResize;\n  },\n  onResize() {\n    const element = document.querySelector('.chat-widget');\n    const windowHeight = window.innerHeight;\n    element.style.height = windowHeight + 'px';\n  },\n  /**\n   * Handles the keydown event and sends a message when the Enter key is pressed.\n   *\n   * @param {KeyboardEvent} event - The keydown event object.\n   * @returns {void}\n   */\n  onKeyDown(event) {\n    if (event.key === 'Enter') {\n      event.preventDefault();\n      this.addNewMessage();\n    }\n    this.typingHandler();\n  },\n  typingHandler() {\n    const timerId = setTimeout(() => {\n      socketEmitChat(this);\n    }, 3000);\n\n    this.typingTimerIds.forEach((t) => clearTimeout(t));\n    this.typingTimerIds.push(timerId);\n  },\n  emailSendHandler() {\n    const data = this.getCurrentCustomerData();\n\n    emailLoader.show();\n    this.elements.emailInput.disabled = true;\n    this.elements.sendButton.style.pointerEvents = 'none';\n    intentions.emit(intentionType.email, data);\n  },\n  getCurrentCustomerData() {\n    const storedCustomerUuid = localStorage.getItem('__pd')\n      ? JSON.parse(localStorage.getItem('__pd')).customerUuid\n      : null;\n    const data = {\n      email: this.elements.emailInput.value,\n      customerUuid: storedCustomerUuid || this.lastQuestionData.user_id,\n    };\n\n    return data;\n  },\n  showSuccessfulPaymentMessage() {\n    localStorage.setItem(GO_THROUGH_QUIZ_KEY, true);\n    const { element } = rolesHTML[roles.assistant](this.translations.tm1226);\n    this.elements.messageIncrementor.appendChild(element);\n    const last = this.getLastMessageElement('.assistant');\n    const answersContainer = document.createElement('div');\n    answersContainer.classList.add('answers-container');\n    this.link = '/';\n    this.elements.ctaButton.textContent = this.translations.tm530;\n    this.setCtaButton();\n\n    this.elements.ctaButton.addEventListener('click', () => {\n      localStorage.removeItem(GO_THROUGH_QUIZ_KEY);\n    });\n\n    // in case the user does not click on take the quiz button\n    setTimeout(() => {\n      this.elements.ctaButton.click();\n    }, 7000);\n\n    last.appendChild(answersContainer);\n\n    this.elements.paymentViewForm.addClass('hidden');\n    this.elements.paymentButton.addClass('hidden');\n    this.elements.sendButton.addClass('hidden');\n    input.hide(this);\n  },\n  showOptionsForRegisteredUser() {\n    const buttonLink = localStorage.getItem(EXISTING_PRODUCT_LINK_KEY);\n    const { element } = rolesHTML[roles.assistant](this.translations.tm716);\n    this.elements.messageIncrementor.appendChild(element);\n    const last = this.getLastMessageElement('.assistant');\n    const answersContainer = document.createElement('div');\n    answersContainer.classList.add('answers-container');\n    const continueToMyPlanButton = document.createElement('a');\n    continueToMyPlanButton.href = buttonLink;\n    const enterNewEmail = document.createElement('div');\n    continueToMyPlanButton.textContent = this.translations.tm526;\n    enterNewEmail.textContent = this.translations.tm715;\n\n    this.elements.emailInput.disabled = true;\n    this.elements.sendButton.style.pointerEvents = 'none';\n\n    enterNewEmail.addEventListener('click', () => {\n      this.elements.emailInput.value = '';\n      this.elements.emailInput.disabled = false;\n      this.elements.sendButton.style.pointerEvents = 'auto';\n\n      // NOTE: this message is not being send to socket until valid;\n      this.lastQuestionData.message = this.elements.emailInput.value;\n      answersContainer.remove();\n      this.appendHtml({ role: roles.user, content: this.translations.tm715 });\n\n      localStorage.removeItem(ALREADY_REGISTERED_KEY);\n      localStorage.removeItem(EXISTING_PRODUCT_LINK_KEY);\n    });\n\n    continueToMyPlanButton.addEventListener('click', () => {\n      this.lastQuestionData.message = this.translations.tm526;\n      localStorage.removeItem(ALREADY_REGISTERED_KEY);\n      localStorage.removeItem(EXISTING_PRODUCT_LINK_KEY);\n    });\n\n    last.appendChild(answersContainer);\n    answersContainer.appendChild(continueToMyPlanButton);\n    answersContainer.appendChild(enterNewEmail);\n  },\n  emitPaymentIntentions() {\n    this.elements.paymentButton.disabled = true;\n    localStorage.setItem(SHOW_PAYMENT_BUTTON_KEY, true);\n    intentions.emit(intentionType.payment, {\n      ...this.elements,\n      paymentHeader,\n      onPaymentSuccess: this.showSuccessfulPaymentMessage.bind(this),\n    });\n  },\n  setPaymentIntent() {\n    // set chosen box\n    const lastMessageTextContainer = this.getLastMessageElement('.assistant .js-assistant-message');\n    const configuredOption = getDisplayInfo();\n    lastMessageTextContainer.innerHTML += configuredOption.price + ' ' + configuredOption.period;\n\n    input.hide(this);\n\n    //show payment button\n    this.elements.paymentButton.classList.remove('hidden');\n    this.elements.paymentButton.disabled = false;\n    this.answersFromStream = '';\n    this.chunk = '';\n    this.track(standardEventTypes.addToCart);\n    this.track(customEventTypes.priceSeen);\n  },\n  setEmailVisibility() {\n    this.elements.messageInput.addClass('hidden');\n    this.elements.emailInput.classList.remove('hidden');\n    this.answersFromStream = '';\n    this.chunk = '';\n    this.track(standardEventTypes.contact);\n    this.track(customEventTypes.emailField);\n  },\n  track(eventType) {\n    const event = tracking.event({\n      eventType: eventType,\n      systemType: backEndVars.systemType,\n      uri: window.location.pathname,\n      domain: window.location.hostname,\n      email: store.getAnswers()['saved-email'] || null,\n      phone: store.get('__ph') || null,\n      customerUuid: store.getCustomerUuid(),\n      additionalData: {},\n      utmParams: store.getMarketingInfo('lastUtmParams'),\n    });\n    tracking.trackClient(event);\n    trackEventInGTM(event);\n  },\n  onKeyDownEmail(event) {\n    if (event.key === 'Enter') {\n      event.preventDefault();\n      this.addNewMessage();\n    }\n    this.elements.errorEmail.addClass('hidden');\n  },\n  hideInput(extractedString) {\n    input.hide(this);\n    this.answersFromStream = extractedString;\n    this.addOptions();\n  },\n\n  //Returns a promise that is resolved after a given time parameter.\n  delay(ms) {\n    return new Promise((resolve) => setTimeout(resolve, ms));\n  },\n\n  //An async function, that appends the splitted message in chunks, with a total delay of 1000ms for each chunk.\n  async appendHtmlInChunks(splitMessage, data) {\n    for (let i = 0; i < splitMessage.length; i++) {\n      loadingDots.show();\n      await this.delay(500);\n      const newData = {\n        ...data,\n        content: splitMessage[i],\n      };\n\n      this.appendHtml(newData);\n      loadingDots.hide();\n      await this.delay(500);\n    }\n  },\n\n  //If the message contains \"^\" symbol and looks something like this \"^^ ^^ Do^^ you ^^^want^ ^^to ^^^ lose weight [Yes|No]^ ^ ^^^\n  //and returs it like this \"Do^ you^ want^ to^ lose weight [Yes|No]\"\n  formatInitialMessage(initialMessage) {\n    if (initialMessage.includes('^')) {\n      const splittedTextArr = splitText(initialMessage, '^');\n      initialMessage = this.rebuildInitialMessage(splittedTextArr);\n    }\n\n    return initialMessage;\n  },\n\n  //Takes an array and builds a string from it, and append a caret sign (^) at the end of each element;\n  rebuildInitialMessage(splittedTextArr) {\n    let formattedText = '';\n    for (let i = 0; i < splittedTextArr.length; i++) {\n      if (splittedTextArr[i] === splittedTextArr[splittedTextArr.length - 1]) {\n        formattedText += splittedTextArr[i];\n      } else {\n        formattedText += splittedTextArr[i] + '^ ';\n      }\n    }\n    return formattedText;\n  },\n};\n\nexport default ChatUi;\n"]}