{"version":3,"sources":["jsdelivr-header.js","/npm/tap-payment-popupjs@2.0.5/index.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gOCNA,MAAM,EAES,mCAIf,MAAM,EAKJ,WAAA,CAAY,GACV,KAAK,OAAS,KACd,KAAK,WAAa,KAClB,KAAK,cAAe,EACpB,KAAK,oBAAsB,EAC3B,KAAK,iBAAkB,EACvB,KAAK,SAqXT,WACE,MAAM,EAAgB,WAAY,SAAS,cAAc,UACzD,OAAK,GACH,QAAQ,KACN,uEAGI,CACV,CA7XoB,GAChB,KAAK,eAAiB,KAEtB,KAAK,qBACL,KAAK,iBACN,CAOD,cAAA,CAAe,GACT,KAAK,qBAAqB,KAAK,gBACnC,KAAK,oBAAsB,EAC3B,KAAK,cACN,CAKD,kBAAA,GACE,KAAK,uBACN,CAOD,wBAAA,GACE,IAAK,KAAK,oBAAqB,OAAO,KAKtC,OAiWJ,SAAoB,EAAQ,GAC1B,MAAM,EAAe,KAAK,MAAM,KAAK,UAAU,IAE/C,OAAA,EAAW,SAAS,WACX,EAAa,EAAG,IAGzB,OAAO,KAAK,GAAc,SAAS,KAET,OAAtB,EAAa,SACS,IAAtB,EAAa,IACgB,IAA7B,EAAa,GAAK,gBAEX,EAAa,EAAG,IAIpB,CACT,CArXwB,CAAW,KAAK,oBADb,CAAC,UAAW,YAIpC,CAKD,YAAA,GACE,MAAM,EAAwB,KAAK,2BAEnC,YAAW,KACT,KAAK,OAAO,cAAc,YACxB,CACE,OAAQ,GAEV,IACR,GACO,IACJ,CAKD,eAAA,GACE,KAAK,eAAkB,IAChB,KAAK,iBACR,KAAK,qBAAqB,EAAK,EAGnC,OAAO,iBAAiB,UAAW,KAAK,gBAAgB,EACzD,CAKD,UAAA,GACE,KAAK,cACN,CAMD,qBAAA,GACE,MAAM,EAAa,SAAS,cAAc,UAC1C,EAAW,aAAa,cAAe,KACvC,EAAW,aAAa,oBAAqB,QAC7C,EAAW,GAAK,IAChB,EAAW,KAAO,uBAAyB,EAAW,GACtD,EAAW,MAAM,QAAU,+UAe3B,KAAK,WAAa,EAClB,SAAS,KAAK,YAAY,GAG1B,MAAM,EAAiB,KAAK,WAAW,cAAc,SACrD,EAAe,OACf,EAAe,MAmcV,4uBAlcL,EAAe,QAGf,MAAM,EAAiB,SAAS,cAAc,UAC9C,EAAe,aAAa,cAAe,KAC3C,EAAe,aAAa,oBAAqB,QACjD,EAAe,aAAa,sBAAuB,QACnD,EAAe,GAAK,IACpB,EAAe,KAAO,YAAc,EAAe,GACnD,EAAe,MAAM,QAAU,sSAc/B,EAAe,IAAM,EAAqB,QAC1C,KAAK,OAAS,EACd,SAAS,KAAK,YAAY,EAC3B,CAKD,YAAA,IACO,KAAK,QAAU,KAAK,eAEzB,KAAK,WAAW,MAAM,QAAU,GAChC,KAAK,WAAW,MAAM,WAAa,UACnC,KAAK,OAAO,MAAM,QAAU,GAC5B,KAAK,OAAO,cAAc,YAAY,SAAU,KAChD,KAAK,cAAe,EACrB,CAKD,YAAA,GACE,KAAK,OAAO,MAAM,WAAa,UAC/B,MAAM,EACJ,KAAK,WAAW,cAAc,SAAS,eAAe,cACpD,IACF,EAAO,MAAM,QAAU,OAE1B,CAMD,oBAAA,CAAqB,GACnB,GACE,EAAM,OAAS,MAAQ,GACvB,KAAK,OAAO,gBAAkB,EAAM,OACpC,CACA,MAAM,EAAO,EAAM,MAAQ,EAAM,QACjC,IACM,GAAyC,IAAjC,EAAK,SAAS,QAAQ,SAChC,KAAK,eAAc,GACnB,KAAK,cAAc,GAE7B,OAAwB,CAElB,OAAQ,GACN,IAAK,qBACH,KAAK,eACL,MACF,IAAK,QACH,KAAK,gBAIR,CAEJ,CAMD,aAAA,CAAc,GAAU,GACtB,KAAK,WAAW,MAAM,QAAU,EAChC,KAAK,OAAO,MAAM,QAAU,OAC5B,KAAK,OAAO,cAAc,YAAY,QAAS,KAC/C,KAAK,cAAe,GAEf,GAAW,KAAK,oBAAoB,SACvC,KAAK,oBAAoB,QAAQ,KAAK,MAGxC,YAAW,KACT,KAAK,iBAAe,GACnB,IACJ,CAKD,aAAA,GACE,KAAK,cACL,KAAK,iBACN,CAKD,WAAA,GACE,KAAK,OAAO,MAAM,WAAa,SAC/B,KAAK,oBAAsB,KAC3B,KAAK,cACN,CAKD,eAAA,GACE,KAAK,WAAW,MAAM,QAAU,OAChC,KAAK,WAAW,MAAM,QAAU,EAChC,KAAK,WAAW,cAAc,SAAS,eACrC,cACA,MAAM,QAAU,OACnB,CAMD,aAAA,CAAc,GACR,KAAK,oBAAoB,UAC3B,KAAK,oBAAoB,SAAS,KAAK,KAAM,EAEhD,CAKD,OAAA,GACM,KAAK,iBACP,OAAO,oBAAoB,UAAW,KAAK,gBAC3C,KAAK,eAAiB,MAGpB,KAAK,SACP,KAAK,OAAO,SACZ,KAAK,OAAS,MAGZ,KAAK,aACP,KAAK,WAAW,SAChB,KAAK,WAAa,MAGpB,KAAK,cAAe,EACpB,KAAK,iBAAkB,CACxB,EAGH,IAAI,EAKQ,MAAC,EAAgB,CAC3B,eAAe,EAKf,UAAA,CAAW,GACT,EAAwB,IAAI,EAAc,GAC1C,QAAQ,IAAI,6BAA+B,KAAK,eAAgB,CACjE,EAOD,KAAA,CAAM,GACJ,MAAM,EAAoB,CACxB,OAAQ,EAAmB,QAAU,GACrC,QAAS,EAAmB,SAAW,GACvC,OAAQ,EAAmB,QAAU,GACrC,MAAO,EAAmB,OAAS,GACnC,IAAK,EAAmB,KAAO,GAC/B,MAAO,EAAmB,OAAS,GACnC,cAAe,EAAmB,eAAiB,GACnD,mBAAoB,EAAmB,qBAAsB,EAC7D,kBAAmB,EAAmB,mBAAqB,GAC3D,QAAS,EAAmB,SAAW,GACvC,SAAU,EAAmB,UAAY,GACzC,cAAe,CACb,MAAO,EAAmB,SACtB,EAAmB,eAAiB,KAI5C,GAyGJ,SAAkC,GAGhC,GAiCF,SAA4B,GAC1B,MAAM,EAAgB,CACpB,MAAO,QACP,OAAQ,SACR,cAAe,SACf,QAAS,WACT,SAAU,YAGZ,UAAW,KAAO,EACZ,EAAE,eAAe,IACnB,EAAU,EAAK,EAAE,IAIrB,SAAS,EAAU,EAAK,GACtB,GAAI,EAAc,IAAQ,EACxB,OAAQ,EAAc,IACpB,IAAK,SA8Bb,SAAsB,GAEpB,MADmB,6BACD,KAAK,EACzB,EAhCU,CAAa,IAAU,EAAqB,GAC5C,MACF,IAAK,UAqCb,SAAuB,GAErB,MAAM,EAAuB,iBAAV,EAAqB,WAAW,GAAS,EAC5D,OAAQ,MAAM,IAAQ,SAAS,IAAQ,EAAM,CAC/C,EAxCU,CAAc,IAAU,EAAqB,GAC7C,MACF,IAAK,YAsDb,SAAoB,GAClB,MAAqB,mBAAP,CAChB,EAvDU,CAAW,IAAU,EAAqB,GAC1C,MACF,IAAK,UA4Db,SAAkB,GAChB,OAAe,OAAR,GAA+B,iBAAR,CAChC,EA7DU,CAAS,IAAU,EAAqB,GACxC,MACF,IAAK,SAkEb,SAAiB,GACf,OAAO,MAAM,QAAQ,EACvB,EAnEU,CAAQ,IAAU,EAAqB,GAG9C,CAED,SAAS,EAAqB,GAC5B,MAAM,EAAO,EAAc,GAC3B,MAAA,MAAM,aAAa,qBAAuB,KACpC,IAAI,MAAM,aAAa,qBAAuB,IACrD,CACH,CA5EE,CAAmB,IAEd,EAAO,OACV,MAAM,IAAI,MAAM,wDAGlB,IAAK,EAAO,OACV,MAAM,IAAI,MAAM,oDAGlB,IAAK,EAAO,MACV,MAAM,IAAI,MACR,yEAIJ,GAAI,EAAO,mBAAoB,CAC7B,IAAK,EAAO,kBACV,MAAM,IAAI,MACR,qEAGJ,IAAK,EAAO,MACV,MAAM,IAAI,MAAM,wDAAuD,CAI3E,OAAO,CACT,CAtIQ,CAAyB,GAC3B,OAAI,KAAK,eACP,QAAQ,IAAI,kCACZ,EAAsB,eAAe,KAErC,QAAQ,IAAI,+CACZ,KAAK,WAAW,IAEX,CAEV,EAKD,OAAA,GACM,IACF,EAAsB,UACtB,EAAwB,MAE1B,KAAK,eAAgB,CACtB,GAOH,SAAS,IACP,cAAc,OAAW,IAAc,OAAS,EAClD,CAEA,UAAW,IAAoB,IAAa,CAC1C,MAAM,EAAa,IACnB,EAAW,cAAgB,EAE3B,EAAW,OAAS,KACb,EAAc,eACjB,EAAc,YAAU,CAE9B,CAOA,SAAS,IACP,IAAI,EAAK,GACT,MAAM,EACJ,iEAEF,QAAS,EAAI,EAAG,EAAI,EAAG,IACrB,GAAM,EAAW,OAAO,KAAK,MAAsB,GAAhB,KAAK,WAG1C,OAAO,CACT,CA+MA,EAAA,cAAA,EAAA,OAAA,eAAA,EAAA,OAAA,YAAA,CAAA,MAAA","file":"/npm/tap-payment-popupjs@2.0.5/dist/umd/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/tap-payment-popupjs@2.0.5/dist/umd/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","const config = {\n  // checkoutURL: \"https://tap-checkout.netlify.app/\",\n  checkoutURL: \"https://checkout.touchandpay.me/\",\n  // checkoutURL: \"http://localhost:3050/\",\n};\n\nclass InlinePayment {\n  /**\n   * Constructor for the InlinePayment class.\n   * @param {object} transactionDefaults - Default transaction parameters.\n   */\n  constructor(transactionDefaults) {\n    this.iframe = null;\n    this.background = null;\n    this.isIframeOpen = false;\n    this.transactionDefaults = transactionDefaults;\n    this.checkoutRemoved = false;\n    this.fallback = noBrowserIframeSupport();\n    this.messageHandler = null; // To hold the event listener function\n\n    this.initializeCheckout();\n    this.listenForEvents();\n  }\n\n  /**\n   * Sets new transaction parameters and updates the iframe.\n   * If a transaction already exists, it resets the checkout before setting the new one.\n   * @param {object} transactionDefaults - The new transaction parameters.\n   */\n  setTransaction(transactionDefaults) {\n    if (this.transactionDefaults) this.resetCheckout();\n    this.transactionDefaults = transactionDefaults;\n    this.updateIframe();\n  }\n\n  /**\n   * Initializes the checkout by creating the popup background.\n   */\n  initializeCheckout() {\n    this.createPopupBackground();\n  }\n\n  /**\n   * Prepares and returns the transaction parameters to be sent to the iframe.\n   * It excludes internal fields and formats metadata and split fields.\n   * @returns {object|null} The transaction parameters or null if not set.\n   */\n  getTransactionParameters() {\n    if (!this.transactionDefaults) return null;\n\n    const excludedFields = [\"onClose\", \"callback\"];\n    const transaction = omitFields(this.transactionDefaults, excludedFields);\n\n    return transaction;\n  }\n\n  /**\n   * Sends a message to the iframe to update its content with new transaction details.\n   */\n  updateIframe() {\n    const transactionParameters = this.getTransactionParameters();\n\n    setTimeout(() => {\n      this.iframe.contentWindow.postMessage(\n        {\n          params: transactionParameters,\n        },\n        \"*\"\n      );\n    }, 3000);\n  }\n\n  /**\n   * Sets up a window event listener to handle messages from the checkout iframe.\n   */\n  listenForEvents() {\n    this.messageHandler = (event) => {\n      if (!this.checkoutRemoved) {\n        this.handleCheckoutEvents(event);\n      }\n    };\n    window.addEventListener(\"message\", this.messageHandler, false);\n  }\n\n  /**\n   * Opens the iframe to start a new checkout process.\n   */\n  openIframe() {\n    this.showCheckout();\n  }\n\n  /**\n   * Creates the background and checkout iframes and appends them to the document body.\n   * The background iframe contains a loading spinner.\n   */\n  createPopupBackground() {\n    const background = document.createElement(\"iframe\");\n    background.setAttribute(\"frameBorder\", \"0\");\n    background.setAttribute(\"allowtransparency\", \"true\");\n    background.id = generateRandomId();\n    background.name = \"checkout-background-\" + background.id;\n    background.style.cssText = `\n      z-index: 999999999999999;\n      background: rgba(0, 0, 0, 0.75);\n      border: none;\n      overflow-x: hidden;\n      overflow-y: hidden;\n      position: fixed;\n      left: 0;\n      top: 0;\n      width: 100%;\n      height: 100%;\n      visibility: hidden;\n      display: none;\n      transition: opacity 0.3s;\n    `;\n    this.background = background;\n    document.body.appendChild(background);\n\n    // Inject loading spinner into the background iframe\n    const loaderDocument = this.background.contentWindow.document;\n    loaderDocument.open();\n    loaderDocument.write(getLoaderHTML());\n    loaderDocument.close();\n\n    // Create the checkout iframe\n    const checkoutIframe = document.createElement(\"iframe\");\n    checkoutIframe.setAttribute(\"frameBorder\", \"0\");\n    checkoutIframe.setAttribute(\"allowtransparency\", \"true\");\n    checkoutIframe.setAttribute(\"allowpaymentrequest\", \"true\");\n    checkoutIframe.id = generateRandomId();\n    checkoutIframe.name = \"checkout-\" + checkoutIframe.id;\n    checkoutIframe.style.cssText = `\n      z-index: 999999999999999;\n      background: transparent;\n      border: none;\n      overflow-x: hidden;\n      overflow-y: hidden;\n      position: fixed;\n      left: 0;\n      top: 0;\n      width: 100%;\n      height: 100%;\n      visibility: hidden;\n      display: none;\n    `;\n    checkoutIframe.src = config.checkoutURL + \"popup\";\n    this.iframe = checkoutIframe;\n    document.body.appendChild(checkoutIframe);\n  }\n\n  /**\n   * Displays the checkout iframe and the background overlay.\n   */\n  showCheckout() {\n    if (!this.iframe || this.isIframeOpen) return;\n\n    this.background.style.display = \"\";\n    this.background.style.visibility = \"visible\";\n    this.iframe.style.display = \"\";\n    this.iframe.contentWindow.postMessage(\"render\", \"*\");\n    this.isIframeOpen = true;\n  }\n\n  /**\n   * Hides the loading spinner in the background iframe once the transaction is loaded.\n   */\n  removeLoader() {\n    this.iframe.style.visibility = \"visible\";\n    const loader =\n      this.background.contentWindow.document.getElementById(\"app-loader\");\n    if (loader) {\n      loader.style.display = \"none\";\n    }\n  }\n\n  /**\n   * Handles events received from the checkout iframe, such as success or close events.\n   * @param {MessageEvent} event - The event object from the message listener.\n   */\n  handleCheckoutEvents(event) {\n    if (\n      event.origin + \"/\" === config.checkoutURL &&\n      this.iframe.contentWindow === event.source\n    ) {\n      const data = event.data || event.message;\n      try {\n        if (data && data.response.success.status === 1) {\n          this.closeCheckout(true);\n          this.handleSuccess(data);\n        }\n      } catch (error) {}\n\n      switch (data) {\n        case \"loaded:transaction\":\n          this.removeLoader();\n          break;\n        case \"close\":\n          this.closeCheckout();\n          break;\n        default:\n          break;\n      }\n    }\n  }\n\n  /**\n   * Closes the checkout iframe and hides the background.\n   * @param {boolean} [success=false] - Indicates if the checkout was closed due to a successful transaction.\n   */\n  closeCheckout(success = false) {\n    this.background.style.opacity = 0;\n    this.iframe.style.display = \"none\";\n    this.iframe.contentWindow.postMessage(\"close\", \"*\");\n    this.isIframeOpen = false;\n\n    if (!success && this.transactionDefaults.onClose) {\n      this.transactionDefaults.onClose.call(this);\n    }\n\n    setTimeout(() => {\n      this.resetBackground();\n    }, 300);\n  }\n\n  /**\n   * Resets the iframe and background to their initial states.\n   */\n  resetCheckout() {\n    this.resetIframe();\n    this.resetBackground();\n  }\n\n  /**\n   * Resets the main checkout iframe's visibility and clears transaction data.\n   */\n  resetIframe() {\n    this.iframe.style.visibility = \"hidden\";\n    this.transactionDefaults = null;\n    this.updateIframe();\n  }\n\n  /**\n   * Resets the background iframe to its initial state, showing the loader.\n   */\n  resetBackground() {\n    this.background.style.display = \"none\";\n    this.background.style.opacity = 1;\n    this.background.contentWindow.document.getElementById(\n      \"app-loader\"\n    ).style.display = \"block\";\n  }\n\n  /**\n   * Handles the callback for a successful transaction.\n   * @param {object} response - The success response from the checkout iframe.\n   */\n  handleSuccess(response) {\n    if (this.transactionDefaults.callback) {\n      this.transactionDefaults.callback.call(this, response);\n    }\n  }\n\n  /**\n   * Cleans up all resources, removing event listeners and DOM elements.\n   */\n  destroy() {\n    if (this.messageHandler) {\n      window.removeEventListener(\"message\", this.messageHandler);\n      this.messageHandler = null;\n    }\n\n    if (this.iframe) {\n      this.iframe.remove();\n      this.iframe = null;\n    }\n\n    if (this.background) {\n      this.background.remove();\n      this.background = null;\n    }\n\n    this.isIframeOpen = false;\n    this.checkoutRemoved = true; // Mark as removed\n  }\n}\n\nlet inlinePaymentInstance;\n\n/**\n * Public interface for interacting with the inline payment system.\n */\nexport const TAPPaymentPop = {\n  isInitialized: false,\n  /**\n   * Initializes the inline payment system with default transaction parameters.\n   * @param {object} transactionDefaults - Default transaction parameters.\n   */\n  initialize(transactionDefaults) {\n    inlinePaymentInstance = new InlinePayment(transactionDefaults);\n    console.log(\"TAPPaymentPop initialized\"), (this.isInitialized = true);\n  },\n\n  /**\n   * Sets up a new transaction. If not initialized, it will initialize first.\n   * @param {object} transactionDetails - The details for the transaction.\n   * @returns {InlinePayment|undefined} The instance of InlinePayment or undefined.\n   */\n  setup(transactionDetails) {\n    const transactionParams = {\n      apiKey: transactionDetails.apiKey || \"\", // required\n      transID: transactionDetails.transID || \"\", // required\n      amount: transactionDetails.amount || \"\", // required\n      email: transactionDetails.email || \"\", // required\n      env: transactionDetails.env || \"\",\n      phone: transactionDetails.phone || \"\",\n      superAgentFee: transactionDetails.superAgentFee || \"\",\n      savePaymentDetails: transactionDetails.savePaymentDetails || false,\n      customerReference: transactionDetails.customerReference || \"\",\n      onClose: transactionDetails.onClose || \"\",\n      callback: transactionDetails.callback || \"\",\n      customPayload: {\n        email: transactionDetails.email,\n        ...(transactionDetails.customPayload || {}), // Ensure customPayload is an object\n      },\n    };\n\n    if (isValidTransactionParams(transactionParams)) {\n      if (this.isInitialized) {\n        console.log(\"Setting transaction parameters\");\n        inlinePaymentInstance.setTransaction(transactionParams);\n      } else {\n        console.log(\"Initializing inline payment with parameters\");\n        this.initialize(transactionParams);\n      }\n      return inlinePaymentInstance;\n    }\n  },\n\n  /**\n   * Destroys the current inline payment instance and cleans up resources.\n   */\n  destroy() {\n    if (inlinePaymentInstance) {\n      inlinePaymentInstance.destroy();\n      inlinePaymentInstance = null;\n    }\n    this.isInitialized = false;\n  },\n};\n\n/**\n * Safely gets the window object, returning an empty object in non-browser environments.\n * @returns {Window|object} The window object or an empty object.\n */\nfunction getSafeWindow() {\n  return typeof window !== \"undefined\" ? window : {};\n}\n\nif (typeof getSafeWindow() !== \"undefined\") {\n  const safeWindow = getSafeWindow();\n  safeWindow.TAPPaymentPop = TAPPaymentPop;\n\n  safeWindow.onload = () => {\n    if (!TAPPaymentPop.isInitialized) {\n      TAPPaymentPop.initialize();\n    }\n  };\n}\n\n/**\n * Generates a random 5-character string ID for DOM elements.\n * @returns {string} A random ID.\n */\nfunction generateRandomId() {\n  let id = \"\";\n  const characters =\n    \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n  for (let i = 0; i < 5; i++) {\n    id += characters.charAt(Math.floor(Math.random() * characters.length));\n  }\n\n  return id;\n}\n\n/**\n * Checks if the current browser supports iframes.\n * @returns {boolean} True if iframes are not supported, false otherwise.\n */\nfunction noBrowserIframeSupport() {\n  const iframeSupport = \"onload\" in document.createElement(\"iframe\");\n  if (!iframeSupport) {\n    console.warn(\n      \"This browser does not support iframes. Please redirect to standard\"\n    );\n  }\n  return !iframeSupport;\n}\n\n/**\n * Creates a new object, omitting specified keys and any keys with empty/null/undefined values.\n * @param {object} object - The source object.\n * @param {string[]} keysToOmit - An array of keys to exclude.\n * @returns {object} A new object with the specified keys removed.\n */\nfunction omitFields(object, keysToOmit) {\n  const clonedObject = JSON.parse(JSON.stringify(object));\n\n  keysToOmit.forEach((key) => {\n    delete clonedObject[key];\n  });\n\n  Object.keys(clonedObject).forEach((key) => {\n    if (\n      clonedObject[key] === null ||\n      clonedObject[key] === undefined ||\n      clonedObject[key].length === 0\n    ) {\n      delete clonedObject[key];\n    }\n  });\n\n  return clonedObject;\n}\n\n/**\n * Validates that essential transaction parameters are present and correct.\n * @param {object} params - The transaction parameters to validate.\n * @returns {boolean} True if the parameters are valid.\n * @throws {Error} If a required parameter is missing or invalid.\n */\nfunction isValidTransactionParams(params) {\n  validateInputTypes(params);\n\n  if (!params.apiKey) {\n    throw new Error(\"Please provide your public key via the key attribute\");\n  }\n\n  if (!params.amount) {\n    throw new Error(\"Please provide transaction amount via the amount\");\n  }\n\n  if (!params.email) {\n    throw new Error(\n      \"Please provide customer email via the email or customerCode attribute\"\n    );\n  }\n\n  if (params.savePaymentDetails) {\n    if (!params.customerReference) {\n      throw new Error(\n        \"Please provide customerReference when savePaymentDetails is true.\"\n      );\n    }\n    if (!params.phone) {\n      throw new Error(\"Please provide phone when savePaymentDetails is true.\");\n    }\n  }\n\n  return true;\n}\n\n/**\n * Validates the data types of various input parameters.\n * @param {object} t - The object containing parameters to validate.\n * @throws {Error} If a parameter has an invalid type.\n */\nfunction validateInputTypes(t) {\n  const expectedTypes = {\n    email: \"email\",\n    amount: \"number\",\n    superAgentFee: \"number\",\n    onClose: \"function\",\n    callback: \"function\",\n  };\n\n  for (const key in t) {\n    if (t.hasOwnProperty(key)) {\n      checkType(key, t[key]);\n    }\n  }\n\n  function checkType(key, value) {\n    if (expectedTypes[key] && value) {\n      switch (expectedTypes[key]) {\n        case \"email\":\n          isValidEmail(value) || throwValidationError(key);\n          break;\n        case \"number\":\n          isValidNumber(value) || throwValidationError(key);\n          break;\n        case \"function\":\n          isFunction(value) || throwValidationError(key);\n          break;\n        case \"object\":\n          isObject(value) || throwValidationError(key);\n          break;\n        case \"array\":\n          isArray(value) || throwValidationError(key);\n      }\n    }\n  }\n\n  function throwValidationError(key) {\n    const type = expectedTypes[key];\n    alert(`Attribute ${key} must be a valid ${type}`);\n    throw new Error(`Attribute ${key} must be a valid ${type}`);\n  }\n}\n\n/**\n * Validates if a string is a valid email address.\n * @param {string} email - The email string to validate.\n * @returns {boolean} True if the email is valid.\n */\nfunction isValidEmail(email) {\n  const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n  return emailRegex.test(email);\n}\n\n/**\n * Checks if a value is a valid number (integer or decimal).\n * @param {string|number} value - The value to check.\n * @returns {boolean} True if the value is a valid number.\n */\nfunction isValidNumber(value) {\n  // Handle both string and number inputs\n  const num = typeof value === \"string\" ? parseFloat(value) : value;\n  return !isNaN(num) && isFinite(num) && num > 0;\n}\n\n/**\n * Checks if a value is a string containing only digits (a normal integer).\n * @param {string|number} value - The value to check.\n * @returns {boolean} True if the value is a string of digits.\n */\nfunction isNormalInteger(value) {\n  return /^\\d+$/.test(value);\n}\n\n/**\n * Checks if a variable is a function.\n * @param {*} fn - The variable to check.\n * @returns {boolean} True if the variable is a function.\n */\nfunction isFunction(fn) {\n  return typeof fn === \"function\";\n}\n\n/**\n * Checks if a variable is an object (and not null).\n * @param {*} obj - The variable to check.\n * @returns {boolean} True if the variable is an object.\n */\nfunction isObject(obj) {\n  return obj !== null && typeof obj === \"object\";\n}\n\n/**\n * Checks if a variable is an array.\n * @param {*} arr - The variable to check.\n * @returns {boolean} True if the variable is an array.\n */\nfunction isArray(arr) {\n  return Array.isArray(arr);\n}\n\n/**\n * Returns the HTML content for the loading spinner to be displayed in the background iframe.\n * @returns {string} The HTML string for the loader.\n */\nfunction getLoaderHTML() {\n  return `\n    <!DOCTYPE html>\n    <html lang=\"en\">\n    <head>\n      <meta charset=\"UTF-8\" />\n      <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n      <title>Loading...</title>\n      <style>\n        * { margin: 0; padding: 0; box-sizing: border-box; }\n        body { display: flex; justify-content: center; align-items: center; height: 100vh; background: rgba(0, 0, 0, 0.50); }\n        .loader { width: 50px; height: 50px; border: 5px solid white; border-top-color: transparent; border-radius: 50%; animation: spin 1s linear infinite; }\n        @keyframes spin { to { transform: rotate(360deg); } }\n      </style>\n    </head>\n    <body>\n      <div class=\"loader\" id=\"app-loader\"></div>\n    </body>\n    </html>`;\n}\n"]}