UNPKG

apexcharts

Version:

A JavaScript Chart Library

34,070 lines 1.1 MB
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};
/*!
 * ApexCharts v5.11.0
 * (c) 2018-2026 ApexCharts
 */
class Environment {
  /**
   * Check if running in server-side rendering environment (Node.js)
   * @returns {boolean} True if in SSR/Node.js, false if in browser
   */
  static isSSR() {
    return typeof window === "undefined" || typeof document === "undefined";
  }
  /**
   * Check if running in browser environment
   * @returns {boolean} True if in browser, false if in SSR/Node.js
   */
  static isBrowser() {
    return !this.isSSR();
  }
  /**
   * Check if a specific browser API is available
   * @param {string} api - Name of the API to check (e.g., 'ResizeObserver')
   * @returns {boolean} True if API is available
   */
  static hasAPI(api) {
    if (this.isSSR()) return false;
    return typeof /** @type {any} */
    window[api] !== "undefined";
  }
  /**
   * Returns the global Apex config object regardless of environment.
   * In browser: window.Apex; in SSR/Node.js: global.Apex; fallback: {}.
   * @returns {any}
   */
  static getApex() {
    if (typeof window !== "undefined" && window.Apex) return window.Apex;
    if (typeof global !== "undefined" && global.Apex) return global.Apex;
    return {};
  }
}
class SSRElement {
  /**
   * @param {string} nodeName
   * @param {any} namespaceURI
   */
  constructor(nodeName, namespaceURI = null) {
    this.nodeName = nodeName;
    this.namespaceURI = namespaceURI;
    this.attributes = /* @__PURE__ */ new Map();
    this.children = [];
    this.textContent = "";
    this.style = {};
    this.classList = new SSRClassList();
    this.parentNode = /** @type {SSRElement | null} */
    null;
    this._ssrWidth = void 0;
    this._ssrHeight = void 0;
    this._ssrMode = void 0;
  }
  /**
   * @param {string} name
   * @param {any} value
   */
  setAttribute(name2, value) {
    this.attributes.set(name2, value);
  }
  /**
   * @param {string} name
   */
  getAttribute(name2) {
    return this.attributes.get(name2);
  }
  /**
   * @param {string} name
   */
  removeAttribute(name2) {
    this.attributes.delete(name2);
  }
  /**
   * @param {string} name
   */
  hasAttribute(name2) {
    return this.attributes.has(name2);
  }
  /**
   * @param {any} child
   */
  appendChild(child) {
    if (child && child !== this) {
      if (child.parentNode && child.parentNode !== this) {
        child.parentNode.removeChild(child);
      } else if (child.parentNode === this) {
        const index = this.children.indexOf(child);
        if (index !== -1) this.children.splice(index, 1);
      }
      child.parentNode = this;
      this.children.push(child);
    }
    return child;
  }
  /**
   * @param {any} child
   */
  removeChild(child) {
    const index = this.children.indexOf(child);
    if (index !== -1) {
      this.children.splice(index, 1);
      child.parentNode = null;
    }
    return child;
  }
  /**
   * @param {any} newNode
   * @param {any} referenceNode
   */
  insertBefore(newNode, referenceNode) {
    if (!referenceNode) {
      return this.appendChild(newNode);
    }
    if (newNode.parentNode && newNode.parentNode !== this) {
      newNode.parentNode.removeChild(newNode);
    } else if (newNode.parentNode === this) {
      const existingIndex = this.children.indexOf(newNode);
      if (existingIndex !== -1) this.children.splice(existingIndex, 1);
    }
    const index = this.children.indexOf(referenceNode);
    if (index !== -1) {
      newNode.parentNode = this;
      this.children.splice(index, 0, newNode);
    }
    return newNode;
  }
  cloneNode(deep = false) {
    const clone = new SSRElement(this.nodeName, this.namespaceURI);
    clone.textContent = this.textContent;
    this.attributes.forEach((value, key) => {
      clone.attributes.set(key, value);
    });
    Object.assign(clone.style, this.style);
    if (deep) {
      this.children.forEach((child) => {
        if (child.cloneNode) {
          clone.appendChild(child.cloneNode(true));
        }
      });
    }
    return clone;
  }
  getBoundingClientRect() {
    return {
      width: this._ssrWidth || 0,
      height: this._ssrHeight || 0,
      top: 0,
      left: 0,
      right: this._ssrWidth || 0,
      bottom: this._ssrHeight || 0,
      x: 0,
      y: 0
    };
  }
  getRootNode() {
    let root = this;
    while (root.parentNode) {
      root = root.parentNode;
    }
    return root;
  }
  querySelector() {
    return null;
  }
  querySelectorAll() {
    return [];
  }
  getElementsByClassName() {
    return [];
  }
  addEventListener() {
  }
  removeEventListener() {
  }
  get childNodes() {
    return this.children;
  }
  toString() {
    let attrs = "";
    this.attributes.forEach((value, key) => {
      attrs += ` ${key}="${value}"`;
    });
    if (this.children.length === 0 && !this.textContent) {
      return `<${this.nodeName}${attrs}/>`;
    }
    const childrenStr = this.children.map((c) => c.toString()).join("");
    return `<${this.nodeName}${attrs}>${this.textContent}${childrenStr}</${this.nodeName}>`;
  }
  // Property getters/setters
  get innerHTML() {
    return this.children.map((c) => c.toString()).join("");
  }
  set innerHTML(value) {
    this.children = [];
    this.textContent = value;
  }
  get outerHTML() {
    return this.toString();
  }
  get isConnected() {
    return true;
  }
}
class SSRClassList {
  constructor() {
    this.classes = /* @__PURE__ */ new Set();
  }
  add(...classNames) {
    classNames.forEach((name2) => this.classes.add(name2));
  }
  remove(...classNames) {
    classNames.forEach((name2) => this.classes.delete(name2));
  }
  /**
   * @param {string} className
   */
  contains(className) {
    return this.classes.has(className);
  }
  /**
   * @param {string} className
   * @param {any} force
   */
  toggle(className, force) {
    if (force === true) {
      this.classes.add(className);
      return true;
    } else if (force === false) {
      this.classes.delete(className);
      return false;
    } else {
      if (this.classes.has(className)) {
        this.classes.delete(className);
        return false;
      } else {
        this.classes.add(className);
        return true;
      }
    }
  }
  toString() {
    return Array.from(this.classes).join(" ");
  }
}
class SSRDOMShim {
  constructor() {
    this.SVGNS = "http://www.w3.org/2000/svg";
    this.XLINKNS = "http://www.w3.org/1999/xlink";
  }
  /**
   * Create SVG element with namespace
   * @param {string} namespaceURI - Namespace URI
   * @param {string} qualifiedName - Element tag name
   * @returns {SSRElement} Mock SVG element
   */
  createElementNS(namespaceURI, qualifiedName) {
    return new SSRElement(qualifiedName, namespaceURI);
  }
  /**
   * Create text node
   * @param {string} data - Text content
   * @returns {object} Text node mock
   */
  createTextNode(data) {
    const node = {
      nodeName: "#text",
      nodeType: 3,
      textContent: data,
      toString() {
        return node.textContent;
      }
    };
    return node;
  }
  /**
   * Query selector (returns null in SSR)
   * @returns {null}
   */
  querySelector() {
    return null;
  }
  /**
   * Query selector all (returns empty array in SSR)
   * @returns {any[]}
   */
  querySelectorAll() {
    return [];
  }
  /**
   * Get computed style (returns empty object in SSR)
   * @returns {object}
   */
  getComputedStyle() {
    return {};
  }
  /**
   * Get bounding client rect for element
   * @param {SSRElement} element - Element to measure
   * @returns {object} Mock dimensions
   */
  getBoundingClientRect(element) {
    if (element && element.getBoundingClientRect) {
      return element.getBoundingClientRect();
    }
    return {
      width: 0,
      height: 0,
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      x: 0,
      y: 0
    };
  }
  /**
   * Create mock XMLSerializer for SSR
   * @returns {object} XMLSerializer mock
   */
  createXMLSerializer() {
    return {
      /**
       * @param {Element} element
       */
      serializeToString(element) {
        return element.toString ? element.toString() : "";
      }
    };
  }
  /**
   * Create mock DOMParser for SSR
   * @returns {object} DOMParser mock
   */
  createDOMParser() {
    return {
      /**
       * @param {string} str
       * @param {string} _type
       */
      parseFromString(str, _type) {
        const root = new SSRElement("root");
        root.innerHTML = str;
        return {
          documentElement: root
        };
      }
    };
  }
}
let shim = null;
let xmlSerializerInstance = null;
let domParserInstance = null;
class BrowserAPIs {
  /**
   * Initialize the SSR shim if in SSR environment
   * Must be called before using other methods
   */
  static init() {
    if (Environment.isSSR() && !shim) {
      shim = new SSRDOMShim();
    }
  }
  /**
   * Create an HTML element
   * @param {string} tagName - Element tag name
   * @returns {HTMLElement} HTML element
   */
  static createElement(tagName) {
    if (Environment.isSSR()) {
      if (!shim) this.init();
      return shim.createElementNS(null, tagName);
    }
    return document.createElement(tagName);
  }
  /**
   * Create an SVG element with namespace
   * @param {string} namespaceURI - Namespace URI
   * @param {string} qualifiedName - Element tag name
   * @returns {HTMLElement} created element
   */
  static createElementNS(namespaceURI, qualifiedName) {
    if (Environment.isSSR()) {
      if (!shim) this.init();
      return shim.createElementNS(namespaceURI, qualifiedName);
    }
    return (
      /** @type {HTMLElement} */
      document.createElementNS(namespaceURI, qualifiedName)
    );
  }
  /**
   * Create a text node
   * @param {string} data - Text content
   * @returns {Text|object} Text node
   */
  static createTextNode(data) {
    if (Environment.isSSR()) {
      if (!shim) this.init();
      return shim.createTextNode(data);
    }
    return document.createTextNode(data);
  }
  /**
   * Query selector
   * @param {string} selector - CSS selector
   * @returns {Element|null}
   */
  static querySelector(selector) {
    if (Environment.isSSR()) {
      return null;
    }
    return document.querySelector(selector);
  }
  /**
   * Query selector all
   * @param {string} selector - CSS selector
   * @returns {NodeList|any[]}
   */
  static querySelectorAll(selector) {
    if (Environment.isSSR()) {
      return [];
    }
    return document.querySelectorAll(selector);
  }
  /**
   * Get computed style for an element
   * @param {Element} element - Element to get styles for
   * @returns {CSSStyleDeclaration|object}
   */
  static getComputedStyle(element) {
    if (Environment.isSSR()) {
      return {};
    }
    return window.getComputedStyle(element);
  }
  /**
   * Get bounding client rect for an element
   * @param {Element} element - Element to measure
   * @returns {DOMRect|object}
   */
  static getBoundingClientRect(element) {
    if (Environment.isSSR()) {
      if (!shim) this.init();
      return shim.getBoundingClientRect(element);
    }
    return element ? element.getBoundingClientRect() : {
      width: 0,
      height: 0,
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      x: 0,
      y: 0
    };
  }
  /**
   * Get XMLSerializer instance
   * @returns {XMLSerializer|object}
   */
  static getXMLSerializer() {
    if (Environment.isSSR()) {
      if (!shim) this.init();
      if (!xmlSerializerInstance) {
        xmlSerializerInstance = shim.createXMLSerializer();
      }
      return xmlSerializerInstance;
    }
    if (!xmlSerializerInstance) {
      xmlSerializerInstance = new XMLSerializer();
    }
    return xmlSerializerInstance;
  }
  /**
   * Get DOMParser instance
   * @returns {DOMParser|object}
   */
  static getDOMParser() {
    if (Environment.isSSR()) {
      if (!shim) this.init();
      if (!domParserInstance) {
        domParserInstance = shim.createDOMParser();
      }
      return domParserInstance;
    }
    if (!domParserInstance) {
      domParserInstance = new DOMParser();
    }
    return domParserInstance;
  }
  /**
   * Add event listener to window
   * @param {string} event - Event name
   * @param {EventListenerOrEventListenerObject} handler - Event handler
   * @param {object} options - Event options
   */
  static addWindowEventListener(event, handler, options2) {
    if (Environment.isBrowser()) {
      window.addEventListener(event, handler, options2);
    }
  }
  /**
   * Remove event listener from window
   * @param {string} event - Event name
   * @param {EventListenerOrEventListenerObject} handler - Event handler
   * @param {object} options - Event options
   */
  static removeWindowEventListener(event, handler, options2) {
    if (Environment.isBrowser()) {
      window.removeEventListener(event, handler, options2);
    }
  }
  /**
   * Request animation frame
   * @param {FrameRequestCallback} callback - Callback function
   * @returns {number|null}
   */
  static requestAnimationFrame(callback) {
    if (Environment.isBrowser()) {
      return window.requestAnimationFrame(callback);
    }
    callback(0);
    return null;
  }
  /**
   * Cancel animation frame
   * @param {number} id - Animation frame ID
   */
  static cancelAnimationFrame(id) {
    if (Environment.isBrowser() && id) {
      window.cancelAnimationFrame(id);
    }
  }
  /**
   * Check if element exists
   * @param {Element} element - Element to check
   * @returns {boolean}
   */
  static elementExists(element) {
    if (!element) return false;
    if (Environment.isSSR()) {
      return element._ssrMode === true || element.nodeName !== void 0;
    }
    return element.getRootNode ? element.getRootNode({ composed: true }) === document || element.isConnected : false;
  }
  /**
   * Get window object (or null in SSR)
   * @returns {Window|null}
   */
  static getWindow() {
    return Environment.isBrowser() ? window : null;
  }
  /**
   * Get document object (or null in SSR)
   * @returns {Document|null}
   */
  static getDocument() {
    return Environment.isBrowser() ? document : null;
  }
  /**
   * Get the shim instance (for testing purposes)
   * @returns {SSRDOMShim|null}
   */
  static _getShim() {
    return shim;
  }
  /**
   * Reset the shim instance (for testing purposes)
   */
  static _resetShim() {
    shim = null;
    xmlSerializerInstance = null;
    domParserInstance = null;
  }
}
let Utils$1 = class Utils {
  /**
   * @param {*} item
   */
  static isObject(item) {
    return item && typeof item === "object" && !Array.isArray(item);
  }
  // Type checking that works across different window objects
  /**
   * @param {string} type
   * @param {string} val
   */
  static is(type, val) {
    return Object.prototype.toString.call(val) === "[object " + type + "]";
  }
  static isSafari() {
    return Environment.isBrowser() && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
  }
  // to extend defaults with user options
  // credit: http://stackoverflow.com/questions/27936772/deep-object-merging-in-es6-es7#answer-34749873
  /**
   * @param {any} target
   * @param {any} source
   */
  static extend(target, source) {
    const output = Object.assign({}, target);
    if (this.isObject(target) && this.isObject(source)) {
      Object.keys(source).forEach((key) => {
        if (this.isObject(source[key])) {
          if (!(key in target)) {
            Object.assign(output, {
              [key]: source[key]
            });
          } else {
            output[key] = this.extend(target[key], source[key]);
          }
        } else {
          Object.assign(output, {
            [key]: source[key]
          });
        }
      });
    }
    return output;
  }
  /**
   * @param {any[]} arrToExtend
   * @param {any} resultArr
   */
  static extendArray(arrToExtend, resultArr) {
    const extendedArr = [];
    arrToExtend.map((item) => {
      extendedArr.push(Utils.extend(resultArr, item));
    });
    arrToExtend = extendedArr;
    return arrToExtend;
  }
  // If month counter exceeds 12, it starts again from 1
  /**
   * @param {number} month
   */
  static monthMod(month) {
    return month % 12;
  }
  /**
   * clone object with optional shallow copy for performance
   * @param {*} source - Source object to clone
   * @param {WeakMap<any, any>} visited - Circular reference tracker
   * @param {boolean} shallow - If true, performs shallow copy (default: false)
   * @returns {*} Cloned object
   */
  static clone(source, visited = /* @__PURE__ */ new WeakMap(), shallow = false) {
    if (source === null || typeof source !== "object") {
      return source;
    }
    if (visited.has(source)) {
      return visited.get(source);
    }
    let cloneResult;
    if (Array.isArray(source)) {
      if (shallow) {
        cloneResult = source.slice();
      } else {
        cloneResult = [];
        visited.set(source, cloneResult);
        for (let i = 0; i < source.length; i++) {
          cloneResult[i] = this.clone(source[i], visited, false);
        }
      }
    } else if (source instanceof Date) {
      cloneResult = new Date(source.getTime());
    } else {
      if (shallow) {
        cloneResult = Object.assign({}, source);
      } else {
        cloneResult = {};
        visited.set(source, cloneResult);
        for (const prop in source) {
          if (Object.prototype.hasOwnProperty.call(source, prop)) {
            cloneResult[prop] = this.clone(
              /** @type {Record<string,any>} */
              source[prop],
              visited,
              false
            );
          }
        }
      }
    }
    return cloneResult;
  }
  /**
   * Shallow clone for performance when deep clone isn't needed
   * @param {*} source - Source to clone
   * @returns {*} Shallow cloned object
   */
  static shallowClone(source) {
    if (source === null || typeof source !== "object") {
      return source;
    }
    if (Array.isArray(source)) {
      return source.slice();
    }
    return Object.assign({}, source);
  }
  /**
   * Fast shallow equality check for objects
   * @param {Object} obj1 - First object
   * @param {Object} obj2 - Second object
   * @returns {boolean} True if shallowly equal
   */
  static shallowEqual(obj1, obj2) {
    if (obj1 === obj2) return true;
    if (!obj1 || !obj2) return false;
    if (typeof obj1 !== "object" || typeof obj2 !== "object") {
      return obj1 === obj2;
    }
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);
    if (keys1.length !== keys2.length) return false;
    for (const key of keys1) {
      if (
        /** @type {Record<string,any>} */
        obj1[key] !== /** @type {Record<string,any>} */
        obj2[key]
      )
        return false;
    }
    return true;
  }
  /**
   * @param {number} x
   */
  static log10(x) {
    return Math.log(x) / Math.LN10;
  }
  /**
   * @param {number} x
   */
  static roundToBase10(x) {
    return Math.pow(10, Math.floor(Math.log10(x)));
  }
  /**
   * @param {number} x
   * @param {number} base
   */
  static roundToBase(x, base) {
    return Math.pow(base, Math.floor(Math.log(x) / Math.log(base)));
  }
  /**
   * @param {any} val
   */
  static parseNumber(val) {
    if (typeof val === "number" || val === null) return val;
    return parseFloat(val);
  }
  /**
   * @param {number} num
   */
  static stripNumber(num, precision = 2) {
    return Number.isInteger(num) ? num : parseFloat(num.toPrecision(precision));
  }
  static randomId() {
    return (Math.random() + 1).toString(36).substring(4);
  }
  /**
   * @param {number} num
   */
  static noExponents(num) {
    if (num.toString().includes("e")) {
      return Math.round(num);
    }
    return num;
  }
  /**
   * @param {any} element
   */
  static elementExists(element) {
    if (!element || !element.isConnected) {
      return false;
    }
    return true;
  }
  /**
   * detects if an element is inside a Shadow DOM
   * @param {any} el
   */
  static isInShadowDOM(el) {
    if (!el || !el.getRootNode) {
      return false;
    }
    const rootNode = el.getRootNode();
    return rootNode && rootNode !== document && Utils.is("ShadowRoot", rootNode);
  }
  /**
   * gets the shadow root host element
   * @param {any} el
   */
  static getShadowRootHost(el) {
    if (!Utils.isInShadowDOM(el)) {
      return null;
    }
    const rootNode = el.getRootNode();
    return rootNode.host || null;
  }
  /**
   * @param {any} el
   */
  static getDimensions(el) {
    if (!el) return [0, 0];
    if (Environment.isSSR()) {
      return [el._ssrWidth || 400, el._ssrHeight || 300];
    }
    let computedStyle;
    try {
      computedStyle = getComputedStyle(el, null);
    } catch (e) {
      return [el.clientWidth || 0, el.clientHeight || 0];
    }
    let elementWidth = el.clientWidth;
    let elementHeight = el.clientHeight;
    if (!elementWidth || !elementHeight) {
      const rect = el.getBoundingClientRect();
      elementWidth = elementWidth || rect.width;
      elementHeight = elementHeight || rect.height;
    }
    elementHeight -= parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom);
    elementWidth -= parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight);
    return [elementWidth, elementHeight];
  }
  /**
   * @returns {any}
   * @param {any} element
   */
  static getBoundingClientRect(element) {
    if (!element) {
      return {
        top: 0,
        right: 0,
        bottom: 0,
        left: 0,
        width: 0,
        height: 0,
        x: 0,
        y: 0
      };
    }
    if (Environment.isSSR()) {
      return BrowserAPIs.getBoundingClientRect(element);
    }
    const rect = element.getBoundingClientRect();
    return {
      top: rect.top,
      right: rect.right,
      bottom: rect.bottom,
      left: rect.left,
      width: element.clientWidth,
      height: element.clientHeight,
      x: rect.left,
      y: rect.top
    };
  }
  /**
   * @param {any[]} arr
   */
  static getLargestStringFromArr(arr) {
    return arr.reduce((a, b) => {
      if (Array.isArray(b)) {
        b = b.reduce((aa, bb) => aa.length > bb.length ? aa : bb);
      }
      return a.length > b.length ? a : b;
    }, 0);
  }
  // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb#answer-12342275
  static hexToRgba(hex = "#999999", opacity = 0.6) {
    if (hex.substring(0, 1) !== "#") {
      hex = "#999999";
    }
    const hexStr = hex.replace("#", "");
    const h = hexStr.match(new RegExp("(.{" + hexStr.length / 3 + "})", "g")) || [];
    for (let i = 0; i < h.length; i++) {
      h[i] = parseInt(h[i].length === 1 ? h[i] + h[i] : h[i], 16);
    }
    if (typeof opacity !== "undefined") h.push(opacity);
    return "rgba(" + h.join(",") + ")";
  }
  /**
   * @param {string} rgba
   */
  static getOpacityFromRGBA(rgba) {
    return parseFloat(rgba.replace(/^.*,(.+)\)/, "$1"));
  }
  /**
   * Parse a #RGB or #RRGGBB hex colour string into [r,g,b] in 0–255.
   * Returns null for invalid input. Used by getContrastRatio.
   * @param {string} hex
   * @returns {[number, number, number] | null}
   */
  static parseHex(hex) {
    if (typeof hex !== "string") return null;
    let h = hex.trim().replace("#", "");
    if (h.length === 3) {
      h = h.split("").map((c) => c + c).join("");
    }
    if (!/^[0-9a-fA-F]{6}$/.test(h)) return null;
    return [
      parseInt(h.slice(0, 2), 16),
      parseInt(h.slice(2, 4), 16),
      parseInt(h.slice(4, 6), 16)
    ];
  }
  /**
   * Relative luminance per WCAG 2.x (https://www.w3.org/TR/WCAG22/#dfn-relative-luminance).
   * @param {[number, number, number]} rgb 0–255 sRGB triplet
   * @returns {number} 0.0–1.0
   */
  static relativeLuminance([r, g, b]) {
    const channel = (c) => {
      const v = c / 255;
      return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
    };
    return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);
  }
  /**
   * WCAG contrast ratio between two hex colours. Returns 0 for invalid input.
   * Range: 1 (identical) … 21 (#000 vs #fff).
   * WCAG AA requires ≥ 4.5 for normal text and ≥ 3.0 for large text / UI components.
   * @param {string} hex1
   * @param {string} hex2
   * @returns {number}
   */
  static getContrastRatio(hex1, hex2) {
    const rgb1 = Utils.parseHex(hex1);
    const rgb2 = Utils.parseHex(hex2);
    if (!rgb1 || !rgb2) return 0;
    const l1 = Utils.relativeLuminance(rgb1);
    const l2 = Utils.relativeLuminance(rgb2);
    const lighter = Math.max(l1, l2);
    const darker = Math.min(l1, l2);
    return (lighter + 0.05) / (darker + 0.05);
  }
  /**
   * @param {any} rgb
   */
  static rgb2hex(rgb) {
    rgb = rgb.match(
      /^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i
    );
    return rgb && rgb.length === 4 ? "#" + ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : "";
  }
  /**
   * @param {number} percent
   * @param {string} color
   */
  shadeRGBColor(percent, color) {
    const f = color.split(","), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = parseInt(f[0].slice(4), 10), G = parseInt(f[1], 10), B = parseInt(f[2], 10);
    return "rgb(" + (Math.round((t - R) * p) + R) + "," + (Math.round((t - G) * p) + G) + "," + (Math.round((t - B) * p) + B) + ")";
  }
  /**
   * @param {number} percent
   * @param {string} color
   */
  shadeHexColor(percent, color) {
    const f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 255, B = f & 255;
    return "#" + (16777216 + (Math.round((t - R) * p) + R) * 65536 + (Math.round((t - G) * p) + G) * 256 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
  }
  // beautiful color shading blending code
  // http://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors
  /**
   * @param {number} p
   * @param {string} color
   */
  shadeColor(p, color) {
    if (Utils.isColorHex(color)) {
      return this.shadeHexColor(p, color);
    } else {
      return this.shadeRGBColor(p, color);
    }
  }
  /**
   * @param {string} color
   */
  static isColorHex(color) {
    return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)|(^#[0-9A-F]{8}$)/i.test(color);
  }
  /**
   * @param {string} color
   */
  static isCSSVariable(color) {
    if (typeof color !== "string") return false;
    const value = color.trim();
    return value.startsWith("var(") && value.endsWith(")");
  }
  /**
   * @param {string} color
   */
  static getThemeColor(color) {
    if (!Utils.isCSSVariable(color)) return color;
    if (Environment.isSSR()) return color;
    const tempElem = document.createElement("div");
    tempElem.style.cssText = "position:fixed; left: -9999px; visibility:hidden;";
    tempElem.style.color = color;
    document.body.appendChild(tempElem);
    let computedColor;
    try {
      computedColor = window.getComputedStyle(tempElem).color;
    } finally {
      if (tempElem.parentNode) {
        tempElem.parentNode.removeChild(tempElem);
      }
    }
    return computedColor;
  }
  /**
   * @param {string} color
   * @param {number} opacity
   */
  static applyOpacityToColor(color, opacity) {
    const value = Number(opacity);
    if (!Number.isFinite(value)) return color;
    if (value <= 0) return "transparent";
    if (value >= 1) return color;
    const percent = Math.round(value * 100);
    return `color-mix(in srgb, ${color} ${percent}%, transparent)`;
  }
  /**
   * @param {number} size
   * @param {number} dataPointsLen
   */
  static getPolygonPos(size, dataPointsLen) {
    const dotsArray = [];
    const angle = Math.PI * 2 / dataPointsLen;
    for (let i = 0; i < dataPointsLen; i++) {
      const curPos = {};
      curPos.x = size * Math.sin(i * angle);
      curPos.y = -size * Math.cos(i * angle);
      dotsArray.push(curPos);
    }
    return dotsArray;
  }
  /**
   * @param {number} centerX
   * @param {number} centerY
   * @param {number} radius
   * @param {number} angleInDegrees
   */
  static polarToCartesian(centerX, centerY, radius, angleInDegrees) {
    const angleInRadians = (angleInDegrees - 90) * Math.PI / 180;
    return {
      x: centerX + radius * Math.cos(angleInRadians),
      y: centerY + radius * Math.sin(angleInRadians)
    };
  }
  /**
   * @param {string} str
   */
  static escapeString(str, escapeWith = "x") {
    let newStr = str.toString().slice();
    newStr = newStr.replace(/[` ~!@#$%^&*()|+=?;:'",.<>{}[\]\\/]/gi, escapeWith);
    return newStr;
  }
  /**
   * @param {number} val
   */
  static negToZero(val) {
    return val < 0 ? 0 : val;
  }
  /**
   * @param {any[]} arr
   * @param {number} old_index
   * @param {number} new_index
   */
  static moveIndexInArray(arr, old_index, new_index) {
    if (new_index >= arr.length) {
      let k = new_index - arr.length + 1;
      while (k--) {
        arr.push(void 0);
      }
    }
    arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
    return arr;
  }
  /**
   * @param {string} s
   */
  static extractNumber(s) {
    return parseFloat(s.replace(/[^\d.]*/g, ""));
  }
  /**
   * @param {any} el
   * @param {string} cls
   */
  static findAncestor(el, cls) {
    while ((el = el.parentElement) && !el.classList.contains(cls)) ;
    return el;
  }
  /**
   * @param {any} el
   * @param {Record<string, any>} styles
   */
  static setELstyles(el, styles) {
    for (const key in styles) {
      if (Object.prototype.hasOwnProperty.call(styles, key)) {
        el.style.key = styles[key];
      }
    }
  }
  // prevents JS prevision errors when adding
  /**
   * @param {number} a
   * @param {number} b
   */
  static preciseAddition(a, b) {
    const aDecimals = (String(a).split(".")[1] || "").length;
    const bDecimals = (String(b).split(".")[1] || "").length;
    const factor = Math.pow(10, Math.max(aDecimals, bDecimals));
    return (Math.round(a * factor) + Math.round(b * factor)) / factor;
  }
  /**
   * @param {any} value
   */
  static isNumber(value) {
    return !isNaN(value) && parseFloat(String(Number(value))) === value && !isNaN(parseInt(value, 10));
  }
  /**
   * @param {number} n
   */
  static isFloat(n) {
    return Number(n) === n && n % 1 !== 0;
  }
  static isMsEdge() {
    if (Environment.isSSR()) return false;
    const ua = window.navigator.userAgent;
    const edge = ua.indexOf("Edge/");
    if (edge > 0) {
      return parseInt(ua.substring(edge + 5, ua.indexOf(".", edge)), 10);
    }
    return false;
  }
  //
  // Find the Greatest Common Divisor of two numbers
  //
  /**
   * @param {number} a
   * @param {number} b
   */
  static getGCD(a, b, p = 7) {
    let factor = Math.pow(10, p - Math.floor(Math.log10(Math.max(a, b))));
    if (factor > 1) {
      a = Math.round(Math.abs(a) * factor);
      b = Math.round(Math.abs(b) * factor);
    } else {
      factor = 1;
    }
    while (b) {
      const t = b;
      b = a % b;
      a = t;
    }
    return a / factor;
  }
  /**
   * @param {number} n
   */
  static getPrimeFactors(n) {
    const factors = [];
    let divisor = 2;
    while (n >= 2) {
      if (n % divisor == 0) {
        factors.push(divisor);
        n = n / divisor;
      } else {
        divisor++;
      }
    }
    return factors;
  }
  /**
   * @param {number} a
   * @param {number} b
   */
  static mod(a, b, p = 7) {
    const big = Math.pow(10, p - Math.floor(Math.log10(Math.max(a, b))));
    a = Math.round(Math.abs(a) * big);
    b = Math.round(Math.abs(b) * big);
    return a % b / big;
  }
};
class DateTime {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
    this.months31 = [1, 3, 5, 7, 8, 10, 12];
    this.months30 = [2, 4, 6, 9, 11];
    this.daysCntOfYear = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
  }
  /**
   * @param {any} date
   */
  isValidDate(date) {
    if (typeof date === "number") {
      return false;
    }
    return !isNaN(this.parseDate(date));
  }
  /**
   * @param {any} dateStr
   */
  getTimeStamp(dateStr) {
    if (!Date.parse(dateStr)) {
      return dateStr;
    }
    const utc = this.w.config.xaxis.labels.datetimeUTC;
    return !utc ? new Date(dateStr).getTime() : new Date(new Date(dateStr).toISOString().substr(0, 25)).getTime();
  }
  /**
   * @param {any} timestamp
   */
  getDate(timestamp) {
    const utc = this.w.config.xaxis.labels.datetimeUTC;
    return utc ? new Date(new Date(timestamp).toUTCString()) : new Date(timestamp);
  }
  /**
   * @param {string} dateStr
   */
  parseDate(dateStr) {
    const parsed = Date.parse(dateStr);
    if (!isNaN(parsed)) {
      return this.getTimeStamp(dateStr);
    }
    let output = Date.parse(dateStr.replace(/-/g, "/").replace(/[a-z]+/gi, " "));
    output = this.getTimeStamp(output);
    return output;
  }
  // This fixes the difference of x-axis labels between chrome/safari
  // Fixes #1726, #1544, #1485, #1255
  /**
   * @param {string} dateStr
   */
  parseDateWithTimezone(dateStr) {
    return Date.parse(dateStr.replace(/-/g, "/").replace(/[a-z]+/gi, " "));
  }
  // http://stackoverflow.com/questions/14638018/current-time-formatting-with-javascript#answer-14638191
  /**
   * @param {Date} date
   * @param {string} format
   */
  formatDate(date, format) {
    const locale = this.w.globals.locale;
    const utc = this.w.config.xaxis.labels.datetimeUTC;
    const MMMM = ["\0", ...locale.months];
    const MMM = ["", ...locale.shortMonths];
    const dddd = ["", ...locale.days];
    const ddd = ["", ...locale.shortDays];
    function ii(i, len = 2) {
      let s2 = i + "";
      while (s2.length < len) s2 = "0" + s2;
      return s2;
    }
    const y = utc ? date.getUTCFullYear() : date.getFullYear();
    format = format.replace(/(^|[^\\])yyyy+/g, "$1" + y);
    format = format.replace(/(^|[^\\])yy/g, "$1" + y.toString().substr(2, 2));
    format = format.replace(/(^|[^\\])y/g, "$1" + y);
    const M = (utc ? date.getUTCMonth() : date.getMonth()) + 1;
    format = format.replace(/(^|[^\\])MMMM+/g, "$1" + MMMM[0]);
    format = format.replace(/(^|[^\\])MMM/g, "$1" + MMM[0]);
    format = format.replace(/(^|[^\\])MM/g, "$1" + ii(M));
    format = format.replace(/(^|[^\\])M/g, "$1" + M);
    const d = utc ? date.getUTCDate() : date.getDate();
    format = format.replace(/(^|[^\\])dddd+/g, "$1" + dddd[0]);
    format = format.replace(/(^|[^\\])ddd/g, "$1" + ddd[0]);
    format = format.replace(/(^|[^\\])dd/g, "$1" + ii(d));
    format = format.replace(/(^|[^\\])d/g, "$1" + d);
    const H = utc ? date.getUTCHours() : date.getHours();
    format = format.replace(/(^|[^\\])HH+/g, "$1" + ii(H));
    format = format.replace(/(^|[^\\])H/g, "$1" + H);
    const h = H > 12 ? H - 12 : H === 0 ? 12 : H;
    format = format.replace(/(^|[^\\])hh+/g, "$1" + ii(h));
    format = format.replace(/(^|[^\\])h/g, "$1" + h);
    const m = utc ? date.getUTCMinutes() : date.getMinutes();
    format = format.replace(/(^|[^\\])mm+/g, "$1" + ii(m));
    format = format.replace(/(^|[^\\])m/g, "$1" + m);
    const s = utc ? date.getUTCSeconds() : date.getSeconds();
    format = format.replace(/(^|[^\\])ss+/g, "$1" + ii(s));
    format = format.replace(/(^|[^\\])s/g, "$1" + s);
    let f = utc ? date.getUTCMilliseconds() : date.getMilliseconds();
    format = format.replace(/(^|[^\\])fff+/g, "$1" + ii(f, 3));
    f = Math.round(f / 10);
    format = format.replace(/(^|[^\\])ff/g, "$1" + ii(f));
    f = Math.round(f / 10);
    format = format.replace(/(^|[^\\])f/g, "$1" + f);
    const T = H < 12 ? "AM" : "PM";
    format = format.replace(/(^|[^\\])TT+/g, "$1" + T);
    format = format.replace(/(^|[^\\])T/g, "$1" + T.charAt(0));
    const t = T.toLowerCase();
    format = format.replace(/(^|[^\\])tt+/g, "$1" + t);
    format = format.replace(/(^|[^\\])t/g, "$1" + t.charAt(0));
    let tz = -date.getTimezoneOffset();
    let K = utc || !tz ? "Z" : tz > 0 ? "+" : "-";
    if (!utc) {
      tz = Math.abs(tz);
      const tzHrs = Math.floor(tz / 60);
      const tzMin = tz % 60;
      K += ii(tzHrs) + ":" + ii(tzMin);
    }
    format = format.replace(/(^|[^\\])K/g, "$1" + K);
    const day = (utc ? date.getUTCDay() : date.getDay()) + 1;
    format = format.replace(new RegExp(dddd[0], "g"), dddd[day]);
    format = format.replace(new RegExp(ddd[0], "g"), ddd[day]);
    format = format.replace(new RegExp(MMMM[0], "g"), MMMM[M]);
    format = format.replace(new RegExp(MMM[0], "g"), MMM[M]);
    format = format.replace(/\\(.)/g, "$1");
    return format;
  }
  /**
   * @param {number} minX
   * @param {number} maxX
   */
  getTimeUnitsfromTimestamp(minX, maxX) {
    const w = this.w;
    if (w.config.xaxis.min !== void 0) {
      minX = w.config.xaxis.min;
    }
    if (w.config.xaxis.max !== void 0) {
      maxX = w.config.xaxis.max;
    }
    const tsMin = this.getDate(minX);
    const tsMax = this.getDate(maxX);
    const minD = this.formatDate(tsMin, "yyyy MM dd HH mm ss fff").split(" ");
    const maxD = this.formatDate(tsMax, "yyyy MM dd HH mm ss fff").split(" ");
    return {
      minMillisecond: parseInt(minD[6], 10),
      maxMillisecond: parseInt(maxD[6], 10),
      minSecond: parseInt(minD[5], 10),
      maxSecond: parseInt(maxD[5], 10),
      minMinute: parseInt(minD[4], 10),
      maxMinute: parseInt(maxD[4], 10),
      minHour: parseInt(minD[3], 10),
      maxHour: parseInt(maxD[3], 10),
      minDate: parseInt(minD[2], 10),
      maxDate: parseInt(maxD[2], 10),
      minMonth: parseInt(minD[1], 10) - 1,
      maxMonth: parseInt(maxD[1], 10) - 1,
      minYear: parseInt(minD[0], 10),
      maxYear: parseInt(maxD[0], 10)
    };
  }
  /**
   * @param {number} year
   */
  isLeapYear(year) {
    return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
  }
  /**
   * @param {number} month
   * @param {number} year
   * @param {number} subtract
   */
  calculcateLastDaysOfMonth(month, year, subtract) {
    const days = this.determineDaysOfMonths(month, year);
    return days - subtract;
  }
  /**
   * @param {number} year
   */
  determineDaysOfYear(year) {
    let days = 365;
    if (this.isLeapYear(year)) {
      days = 366;
    }
    return days;
  }
  /**
   * @param {number} year
   * @param {number} month
   * @param {number} date
   */
  determineRemainingDaysOfYear(year, month, date) {
    let dayOfYear = this.daysCntOfYear[month] + date;
    if (month > 1 && this.isLeapYear(year)) dayOfYear++;
    return dayOfYear;
  }
  /**
   * @param {number} month
   * @param {number} year
   */
  determineDaysOfMonths(month, year) {
    let days = 30;
    month = Utils$1.monthMod(month);
    switch (true) {
      case this.months30.indexOf(month) > -1:
        if (month === 2) {
          if (this.isLeapYear(year)) {
            days = 29;
          } else {
            days = 28;
          }
        }
        break;
      case this.months31.indexOf(month) > -1:
        days = 31;
        break;
      default:
        days = 31;
        break;
    }
    return days;
  }
}
class Formatters {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
    this.tooltipKeyFormat = "dd MMM";
  }
  /**
   * @param {Function} fn
   * @param {any} val
   * @param {any} timestamp
   * @param {any} _opts
   */
  xLabelFormat(fn, val, timestamp, _opts) {
    const w = this.w;
    if (w.config.xaxis.type === "datetime") {
      if (w.config.xaxis.labels.formatter === void 0) {
        if (w.config.tooltip.x.formatter === void 0) {
          const datetimeObj = new DateTime(this.w);
          return datetimeObj.formatDate(
            datetimeObj.getDate(val),
            w.config.tooltip.x.format
          );
        }
      }
    }
    return fn(val, timestamp, _opts);
  }
  /**
   * @param {any} val
   */
  defaultGeneralFormatter(val) {
    if (Array.isArray(val)) {
      return val.map((v) => {
        return v;
      });
    } else {
      return val;
    }
  }
  /**
   * @param {any} v
   * @param {ApexYAxis} yaxe
   */
  defaultYFormatter(v, yaxe) {
    const w = this.w;
    if (Utils$1.isNumber(v)) {
      if (w.globals.yValueDecimal !== 0) {
        v = v.toFixed(
          yaxe.decimalsInFloat !== void 0 ? yaxe.decimalsInFloat : w.globals.yValueDecimal
        );
      } else {
        const f = v.toFixed(0);
        v = Number(f) === v ? f : v.toFixed(1);
      }
    }
    return v;
  }
  setLabelFormatters() {
    const w = this.w;
    const fmt = w.formatters;
    fmt.xaxisTooltipFormatter = (val) => {
      return this.defaultGeneralFormatter(val);
    };
    fmt.ttKeyFormatter = (val) => {
      return this.defaultGeneralFormatter(val);
    };
    fmt.ttZFormatter = (val) => {
      return val;
    };
    fmt.legendFormatter = (val) => {
      return this.defaultGeneralFormatter(val);
    };
    if (w.config.xaxis.labels.formatter !== void 0) {
      fmt.xLabelFormatter = w.config.xaxis.labels.formatter;
    } else {
      fmt.xLabelFormatter = (val) => {
        if (Utils$1.isNumber(val)) {
          if (!w.config.xaxis.convertedCatToNumeric && w.config.xaxis.type === "numeric") {
            if (Utils$1.isNumber(w.config.xaxis.decimalsInFloat)) {
              return val.toFixed(w.config.xaxis.decimalsInFloat);
            } else {
              const diff = w.globals.maxX - w.globals.minX;
              if (diff > 0 && diff < 100) {
                return val.toFixed(1);
              }
              return val.toFixed(0);
            }
          }
          if (w.globals.isBarHorizontal) {
            const range = w.globals.maxY - /** @type {any} */
            w.globals.minYArr;
            if (range < 4) {
              return val.toFixed(1);
            }
          }
          return val.toFixed(0);
        }
        return val;
      };
    }
    if (typeof w.config.tooltip.x.formatter === "function") {
      fmt.ttKeyFormatter = w.config.tooltip.x.formatter;
    } else {
      fmt.ttKeyFormatter = fmt.xLabelFormatter;
    }
    if (typeof w.config.xaxis.tooltip.formatter === "function") {
      fmt.xaxisTooltipFormatter = w.config.xaxis.tooltip.formatter;
    }
    if (Array.isArray(w.config.tooltip.y)) {
      fmt.ttVal = w.config.tooltip.y;
    } else {
      if (w.config.tooltip.y.formatter !== void 0) {
        fmt.ttVal = w.config.tooltip.y;
      }
    }
    if (w.config.tooltip.z.formatter !== void 0) {
      fmt.ttZFormatter = w.config.tooltip.z.formatter;
    }
    if (w.config.legend.formatter !== void 0) {
      fmt.legendFormatter = w.config.legend.formatter;
    }
    fmt.yLabelFormatters = [];
    w.config.yaxis.forEach((yaxe, i) => {
      if (yaxe.labels.formatter !== void 0) {
        fmt.yLabelFormatters[i] = yaxe.labels.formatter;
      } else {
        fmt.yLabelFormatters[i] = (val) => {
          if (!w.globals.xyCharts) return val;
          if (Array.isArray(val)) {
            return val.map((v) => {
              return this.defaultYFormatter(v, yaxe);
            });
          } else {
            return this.defaultYFormatter(val, yaxe);
          }
        };
      }
    });
    return w.globals;
  }
  heatmapLabelFormatters() {
    const w = this.w;
    if (w.config.chart.type === "heatmap") {
      w.globals.yAxisScale[0].result = /** @type {any} */
      w.seriesData.seriesNames.slice();
      const longest = (
        /** @type {any} */
        w.seriesData.seriesNames.reduce(
          (a, b) => a.length > b.length ? a : b,
          0
        )
      );
      w.globals.yAxisScale[0].niceMax = longest;
      w.globals.yAxisScale[0].niceMin = longest;
    }
  }
}
const getRangeValues = ({
  isTimeline,
  seriesIndex,
  dataPointIndex,
  y1,
  y2,
  w
}) => {
  var _a;
  let start = w.rangeData.seriesRangeStart[seriesIndex][dataPointIndex];
  let end = w.rangeData.seriesRangeEnd[seriesIndex][dataPointIndex];
  let ylabel = w.labelData.labels[dataPointIndex];
  let seriesName = w.config.series[seriesIndex].name ? w.config.series[seriesIndex].name : "";
  const yLbFormatter = w.formatters.ttKeyFormatter;
  const yLbTitleFormatter = w.config.tooltip.y.title.formatter;
  const opts = {
    w,
    seriesIndex,
    dataPointIndex,
    start,
    end
  };
  if (typeof yLbTitleFormatter === "function") {
    seriesName = yLbTitleFormatter(seriesName, opts);
  }
  if ((_a = w.config.series[seriesIndex].data[dataPointIndex]) == null ? void 0 : _a.x) {
    ylabel = w.config.series[seriesIndex].data[dataPointIndex].x;
  }
  if (!isTimeline) {
    if (w.config.xaxis.type === "datetime") {
      const xFormat = new Formatters(w);
      ylabel = xFormat.xLabelFormat(
        w.formatters.ttKeyFormatter,
        ylabel,
        ylabel,
        {
          i: void 0,
          dateFormatter: new DateTime(w).formatDate,
          w
        }
      );
    }
  }
  if (typeof yLbFormatter === "function") {
    ylabel = yLbFormatter(ylabel, opts);
  }
  if (Number.isFinite(y1) && Number.isFinite(y2)) {
    start = y1;
    end = y2;
  }
  let startVal = "";
  let endVal = "";
  const color = w.globals.colors[seriesIndex];
  if (w.config.tooltip.x.formatter === void 0) {
    if (w.config.xaxis.type === "datetime") {
      const datetimeObj = new DateTime(w);
      startVal = datetimeObj.formatDate(
        datetimeObj.getDate(start),
        w.config.tooltip.x.format
      );
      endVal = datetimeObj.formatDate(
        datetimeObj.getDate(end),
        w.config.tooltip.x.format
      );
    } else {
      startVal = start;
      endVal = end;
    }
  } else {
    startVal = w.config.tooltip.x.formatter(start);
    endVal = w.config.tooltip.x.formatter(end);
  }
  return { start, end, startVal, endVal, ylabel, color, seriesName };
};
const buildRangeTooltipHTML = (opts) => {
  let { color, seriesName, ylabel, start, end, seriesIndex, dataPointIndex } = opts;
  const formatter = opts.w.globals.tooltip.tooltipLabels.getFormatters(seriesIndex);
  start = formatter.yLbFormatter(start);
  end = formatter.yLbFormatter(end);
  const val = formatter.yLbFormatter(
    opts.w.seriesData.series[seriesIndex][dataPointIndex]
  );
  let valueHTML = "";
  const rangeValues = `<span class="value start-value">
  ${start}
  </span> <span class="separator">-</span> <span class="value end-value">
  ${end}
  </span>`;
  if (opts.w.globals.comboCharts) {
    if (opts.w.config.series[seriesIndex].type === "rangeArea" || opts.w.config.series[seriesIndex].type === "rangeBar") {
      valueHTML = rangeValues;
    } else {
      valueHTML = `<span>${val}</span>`;
    }
  } else {
    valueHTML = rangeValues;
  }
  return '<div class="apexcharts-tooltip-rangebar"><div> <span class="series-name" style="color: ' + color + '">' + (seriesName ? seriesName : "") + '</span></div><div> <span class="category">' + ylabel + ": </span> " + valueHTML + " </div></div>";
};
class Defaults {
  /**
   * @param {Record<string, any>} opts
   */
  constructor(opts) {
    this.opts = opts;
  }
  hideYAxis() {
    this.opts.yaxis[0].show = false;
    this.opts.yaxis[0].title.text = "";
    this.opts.yaxis[0].axisBorder.show = false;
    this.opts.yaxis[0].axisTicks.show = false;
    this.opts.yaxis[0].floating = true;
  }
  line() {
    return {
      dataLabels: {
        enabled: false
      },
      stroke: {
        width: 5,
        curve: "straight"
      },
      markers: {
        size: 0,
        hover: {
          sizeOffset: 6
        }
      },
      xaxis: {
        crosshairs: {
          width: 1
        }
      }
    };
  }
  /**
   * @param {Record<string, any>} defaults
   */
  sparkline(defaults) {
    this.hideYAxis();
    const ret = {
      grid: {
        show: false,
        padding: {
          left: 0,
          right: 0,
          top: 0,
          bottom: 0
        }
      },
      legend: {
        show: false
      },
      xaxis: {
        labels: {
          show: false
        },
        tooltip: {
          enabled: false
        },
        axisBorder: {
          show: false
        },
        axisTicks: {
          show: false
        }
      },
      chart: {
        toolbar: {
          show: false
        },
        zoom: {
          enabled: false
        }
      },
      dataLabels: {
        enabled: false
      }
    };
    return Utils$1.extend(defaults, ret);
  }
  slope() {
    this.hideYAxis();
    return {
      chart: {
        toolbar: {
          show: false
        },
        zoom: {
          enabled: false
        }
      },
      dataLabels: {
        enabled: true,
        /**
         * @param {any} val
         * @param {Record<string, any>} opts
         */
        formatter(val, opts) {
          const seriesName = opts.w.config.series[opts.seriesIndex].name;
          return val !== null ? seriesName + ": " + val : "";
        },
        background: {
          enabled: false
        },
        offsetX: -5
      },
      grid: {
        xaxis: {
          lines: {
            show: true
          }
        },
        yaxis: {
          lines: {
            show: false
          }
        }
      },
      xaxis: {
        position: "top",
        labels: {
          style: {
            fontSize: 14,
            fontWeight: 900
          }
        },
        tooltip: {
          enabled: false
        },
        crosshairs: {
          show: false
        }
      },
      markers: {
        size: 8,
        hover: {
          sizeOffset: 1
        }
      },
      legend: {
        show: false
      },
      tooltip: {
        shared: false,
        intersect: true,
        followCursor: true
      },
      stroke: {
        width: 5,
        curve: "straight"
      }
    };
  }
  bar() {
    return {
      chart: {
        stacked: false
      },
      plotOptions: {
        bar: {
          dataLabels: {
            position: "center"
          }
        }
      },
      dataLabels: {
        style: {
          colors: ["#fff"]
        },
        background: {
          enabled: false
        }
      },
      stroke: {
        width: 0,
        lineCap: "square"
      },
      fill: {
        opacity: 0.85
      },
      legend: {
        markers: {
          shape: "square"
        }
      },
      tooltip: {
        shared: false,
        intersect: true
      },
      xaxis: {
        tooltip: {
          enabled: false
        },
        tickPlacement: "between",
        crosshairs: {
          width: "barWidth",
          position: "back",
          fill: {
            type: "gradient"
          },
          dropShadow: {
            enabled: false
          },
          stroke: {
            width: 0
          }
        }
      }
    };
  }
  funnel() {
    this.hideYAxis();
    return __spreadProps(__spreadValues({}, this.bar()), {
      chart: {
        animations: {
          speed: 800,
          animateGradually: {
            enabled: false
          }
        }
      },
      plotOptions: {
        bar: {
          horizontal: true,
          borderRadiusApplication: "around",
          borderRadius: 0,
          dataLabels: {
            position: "center"
          }
        }
      },
      grid: {
        show: false,
        padding: {
          left: 0,
          right: 0
        }
      },
      xaxis: {
        labels: {
          show: false
        },
        tooltip: {
          enabled: false
        },
        axisBorder: {
          show: false
        },
        axisTicks: {
          show: false
        }
      }
    });
  }
  candlestick() {
    return {
      stroke: {
        width: 1
      },
      fill: {
        opacity: 1
      },
      dataLabels: {
        enabled: false
      },
      tooltip: {
        shared: true,
        custom: ({ seriesIndex, dataPointIndex, w }) => {
          return this._getBoxTooltip(
            w,
            seriesIndex,
            dataPointIndex,
            ["Open", "High", "", "Low", "Close"],
            "candlestick"
          );
        }
      },
      states: {
        active: {
          filter: {
            type: "none"
          }
        }
      },
      xaxis: {
        crosshairs: {
          width: 1
        }
      }
    };
  }
  boxPlot() {
    return {
      chart: {
        animations: {
          dynamicAnimation: {
            enabled: false
          }
        }
      },
      stroke: {
        width: 1,
        colors: ["#24292e"]
      },
      dataLabels: {
        enabled: false
      },
      tooltip: {
        shared: true,
        custom: ({ seriesIndex, dataPointIndex, w }) => {
          return this._getBoxTooltip(
            w,
            seriesIndex,
            dataPointIndex,
            ["Minimum", "Q1", "Median", "Q3", "Maximum"],
            "boxPlot"
          );
        }
      },
      markers: {
        size: 7,
        strokeWidth: 1,
        strokeColors: "#111"
      },
      xaxis: {
        crosshairs: {
          width: 1
        }
      }
    };
  }
  rangeBar() {
    const handleTimelineTooltip = (opts) => {
      const { color, seriesName, ylabel, startVal, endVal } = getRangeValues(__spreadProps(__spreadValues({}, opts), {
        isTimeline: true
      }));
      return buildRangeTooltipHTML(__spreadProps(__spreadValues({}, opts), {
        color,
        seriesName,
        ylabel,
        start: startVal,
        end: endVal
      }));
    };
    const handleRangeColumnTooltip = (opts) => {
      const { color, seriesName, ylabel, start, end } = getRangeValues(opts);
      return buildRangeTooltipHTML(__spreadProps(__spreadValues({}, opts), {
        color,
        seriesName,
        ylabel,
        start,
        end
      }));
    };
    return {
      chart: {
        animations: {
          animateGradually: false
        }
      },
      stroke: {
        width: 0,
        lineCap: "square"
      },
      plotOptions: {
        bar: {
          borderRadius: 0,
          dataLabels: {
            position: "center"
          }
        }
      },
      dataLabels: {
        enabled: false,
        /**
         * @param {any} val
         */
        formatter(val, { seriesIndex, dataPointIndex, w }) {
          const getVal = () => {
            const start = w.rangeData.seriesRangeStart[seriesIndex][dataPointIndex];
            const end = w.rangeData.seriesRangeEnd[seriesIndex][dataPointIndex];
            return end - start;
          };
          if (w.globals.comboCharts) {
            if (w.config.series[seriesIndex].type === "rangeBar" || w.config.series[seriesIndex].type === "rangeArea") {
              return getVal();
            } else {
              return val;
            }
          } else {
            return getVal();
          }
        },
        background: {
          enabled: false
        },
        style: {
          colors: ["#fff"]
        }
      },
      markers: {
        size: 10
      },
      tooltip: {
        shared: false,
        followCursor: true,
        /**
         * @param {Record<string, any>} opts
         */
        custom(opts) {
          if (opts.w.config.plotOptions && opts.w.config.plotOptions.bar && opts.w.config.plotOptions.bar.horizontal) {
            return handleTimelineTooltip(opts);
          } else {
            return handleRangeColumnTooltip(opts);
          }
        }
      },
      xaxis: {
        tickPlacement: "between",
        tooltip: {
          enabled: false
        },
        crosshairs: {
          stroke: {
            width: 0
          }
        }
      }
    };
  }
  /**
   * @param {Record<string, any>} opts
   */
  dumbbell(opts) {
    var _a, _b;
    if (!((_a = opts.plotOptions.bar) == null ? void 0 : _a.barHeight)) {
      opts.plotOptions.bar.barHeight = 2;
    }
    if (!((_b = opts.plotOptions.bar) == null ? void 0 : _b.columnWidth)) {
      opts.plotOptions.bar.columnWidth = 2;
    }
    return opts;
  }
  area() {
    return {
      stroke: {
        width: 4,
        fill: {
          type: "solid",
          gradient: {
            inverseColors: false,
            shade: "light",
            type: "vertical",
            opacityFrom: 0.65,
            opacityTo: 0.5,
            stops: [0, 100, 100]
          }
        }
      },
      fill: {
        type: "gradient",
        gradient: {
          inverseColors: false,
          shade: "light",
          type: "vertical",
          opacityFrom: 0.65,
          opacityTo: 0.5,
          stops: [0, 100, 100]
        }
      },
      markers: {
        size: 0,
        hover: {
          sizeOffset: 6
        }
      },
      tooltip: {
        followCursor: false
      }
    };
  }
  rangeArea() {
    const handleRangeAreaTooltip = (opts) => {
      const { color, seriesName, ylabel, start, end } = getRangeValues(opts);
      return buildRangeTooltipHTML(__spreadProps(__spreadValues({}, opts), {
        color,
        seriesName,
        ylabel,
        start,
        end
      }));
    };
    return {
      stroke: {
        curve: "straight",
        width: 0
      },
      fill: {
        type: "solid",
        opacity: 0.6
      },
      markers: {
        size: 0
      },
      states: {
        hover: {
          filter: {
            type: "none"
          }
        },
        active: {
          filter: {
            type: "none"
          }
        }
      },
      tooltip: {
        intersect: false,
        shared: true,
        followCursor: true,
        /**
         * @param {Record<string, any>} opts
         */
        custom(opts) {
          return handleRangeAreaTooltip(opts);
        }
      }
    };
  }
  /**
   * @param {Record<string, any>} defaults
   */
  brush(defaults) {
    const ret = {
      chart: {
        toolbar: {
          autoSelected: "selection",
          show: false
        },
        zoom: {
          enabled: false
        }
      },
      dataLabels: {
        enabled: false
      },
      stroke: {
        width: 1
      },
      tooltip: {
        enabled: false
      },
      xaxis: {
        tooltip: {
          enabled: false
        }
      }
    };
    return Utils$1.extend(defaults, ret);
  }
  /**
   * @param {Record<string, any>} opts
   */
  stacked100(opts) {
    opts.dataLabels = opts.dataLabels || {};
    opts.dataLabels.formatter = opts.dataLabels.formatter || void 0;
    const existingDataLabelFormatter = opts.dataLabels.formatter;
    opts.yaxis.forEach((yaxe, index) => {
      opts.yaxis[index].min = 0;
      opts.yaxis[index].max = 100;
    });
    const isBar = opts.chart.type === "bar";
    if (isBar) {
      opts.dataLabels.formatter = existingDataLabelFormatter || /**
       * @param {any} val
       */
      function(val) {
        if (typeof val === "number") {
          return val ? val.toFixed(0) + "%" : val;
        }
        return val;
      };
    }
    return opts;
  }
  stackedBars() {
    const barDefaults = this.bar();
    return __spreadProps(__spreadValues({}, barDefaults), {
      plotOptions: __spreadProps(__spreadValues({}, barDefaults.plotOptions), {
        bar: __spreadProps(__spreadValues({}, barDefaults.plotOptions.bar), {
          borderRadiusApplication: "end",
          borderRadiusWhenStacked: "last"
        })
      })
    });
  }
  // This function removes the left and right spacing in chart for line/area/scatter if xaxis type = category for those charts by converting xaxis = numeric. Numeric/Datetime xaxis prevents the unnecessary spacing in the left/right of the chart area
  /**
   * @param {Record<string, any>} opts
   */
  convertCatToNumeric(opts) {
    opts.xaxis.convertedCatToNumeric = true;
    return opts;
  }
  /**
   * @param {Record<string, any>} opts
   * @param {any} cats
   */
  convertCatToNumericXaxis(opts, cats) {
    opts.xaxis.type = "numeric";
    opts.xaxis.labels = opts.xaxis.labels || {};
    opts.xaxis.labels.formatter = opts.xaxis.labels.formatter || /**
     * @param {any} val
     */
    function(val) {
      return Utils$1.isNumber(val) ? Math.floor(val) : val;
    };
    const defaultFormatter = opts.xaxis.labels.formatter;
    let labels = opts.xaxis.categories && opts.xaxis.categories.length ? opts.xaxis.categories : opts.labels;
    if (cats && cats.length) {
      labels = cats.map((c) => {
        return Array.isArray(c) ? c : String(c);
      });
    }
    if (labels && labels.length) {
      opts.xaxis.labels.formatter = function(val) {
        return Utils$1.isNumber(val) ? defaultFormatter(labels[Math.floor(val) - 1]) : defaultFormatter(val);
      };
    }
    opts.xaxis.categories = [];
    opts.labels = [];
    opts.xaxis.tickAmount = opts.xaxis.tickAmount || "dataPoints";
    return opts;
  }
  bubble() {
    return {
      dataLabels: {
        style: {
          colors: ["#fff"]
        }
      },
      tooltip: {
        shared: false,
        intersect: true
      },
      xaxis: {
        crosshairs: {
          width: 0
        }
      },
      fill: {
        type: "solid",
        gradient: {
          shade: "light",
          inverse: true,
          shadeIntensity: 0.55,
          opacityFrom: 0.4,
          opacityTo: 0.8
        }
      }
    };
  }
  scatter() {
    return {
      dataLabels: {
        enabled: false
      },
      tooltip: {
        shared: false,
        intersect: true
      },
      markers: {
        size: 6,
        strokeWidth: 1,
        hover: {
          sizeOffset: 2
        }
      }
    };
  }
  heatmap() {
    return {
      chart: {
        stacked: false
      },
      fill: {
        opacity: 1
      },
      dataLabels: {
        style: {
          colors: ["#fff"]
        }
      },
      stroke: {
        colors: ["#fff"]
      },
      tooltip: {
        followCursor: true,
        marker: {
          show: false
        },
        x: {
          show: false
        }
      },
      legend: {
        position: "top",
        markers: {
          shape: "square"
        }
      },
      grid: {
        padding: {
          right: 20
        }
      }
    };
  }
  treemap() {
    return {
      chart: {
        zoom: {
          enabled: false
        }
      },
      dataLabels: {
        style: {
          fontSize: 14,
          fontWeight: 600,
          colors: ["#fff"]
        }
      },
      stroke: {
        show: true,
        width: 2,
        colors: ["#fff"]
      },
      legend: {
        show: false
      },
      fill: {
        opacity: 1,
        gradient: {
          stops: [0, 100]
        }
      },
      tooltip: {
        followCursor: true,
        x: {
          show: false
        }
      },
      grid: {
        padding: {
          left: 0,
          right: 0
        }
      },
      xaxis: {
        crosshairs: {
          show: false
        },
        tooltip: {
          enabled: false
        }
      }
    };
  }
  pie() {
    return {
      chart: {
        toolbar: {
          show: false
        }
      },
      plotOptions: {
        pie: {
          donut: {
            labels: {
              show: false
            }
          }
        }
      },
      dataLabels: {
        /**
         * @param {number} val
         */
        formatter(val) {
          return val.toFixed(1) + "%";
        },
        style: {
          colors: ["#fff"]
        },
        background: {
          enabled: false
        },
        dropShadow: {
          enabled: true
        }
      },
      stroke: {
        colors: ["#fff"]
      },
      fill: {
        opacity: 1,
        gradient: {
          shade: "light",
          stops: [0, 100]
        }
      },
      tooltip: {
        theme: "dark",
        fillSeriesColor: true
      },
      legend: {
        position: "right"
      },
      grid: {
        padding: {
          left: 0,
          right: 0,
          top: 0,
          bottom: 0
        }
      }
    };
  }
  donut() {
    return {
      chart: {
        toolbar: {
          show: false
        }
      },
      dataLabels: {
        /**
         * @param {number} val
         */
        formatter(val) {
          return val.toFixed(1) + "%";
        },
        style: {
          colors: ["#fff"]
        },
        background: {
          enabled: false
        },
        dropShadow: {
          enabled: true
        }
      },
      stroke: {
        colors: ["#fff"]
      },
      fill: {
        opacity: 1,
        gradient: {
          shade: "light",
          shadeIntensity: 0.35,
          stops: [80, 100],
          opacityFrom: 1,
          opacityTo: 1
        }
      },
      tooltip: {
        theme: "dark",
        fillSeriesColor: true
      },
      legend: {
        position: "right"
      },
      grid: {
        padding: {
          left: 0,
          right: 0,
          top: 0,
          bottom: 0
        }
      }
    };
  }
  polarArea() {
    return {
      chart: {
        toolbar: {
          show: false
        }
      },
      dataLabels: {
        /**
         * @param {number} val
         */
        formatter(val) {
          return val.toFixed(1) + "%";
        },
        enabled: false
      },
      stroke: {
        show: true,
        width: 2
      },
      fill: {
        opacity: 0.7
      },
      tooltip: {
        theme: "dark",
        fillSeriesColor: true
      },
      legend: {
        position: "right"
      },
      grid: {
        padding: {
          left: 0,
          right: 0,
          top: 0,
          bottom: 0
        }
      }
    };
  }
  radar() {
    this.opts.yaxis[0].labels.offsetY = this.opts.yaxis[0].labels.offsetY ? this.opts.yaxis[0].labels.offsetY : 6;
    return {
      dataLabels: {
        enabled: false,
        style: {
          fontSize: "11px"
        }
      },
      stroke: {
        width: 2
      },
      markers: {
        size: 5,
        strokeWidth: 1,
        strokeOpacity: 1
      },
      fill: {
        opacity: 0.2
      },
      tooltip: {
        shared: false,
        intersect: true,
        followCursor: true
      },
      grid: {
        show: false,
        padding: {
          left: 0,
          right: 0,
          top: 0,
          bottom: 0
        }
      },
      xaxis: {
        labels: {
          formatter: (val) => val,
          style: {
            colors: ["#a8a8a8"],
            fontSize: "11px"
          }
        },
        tooltip: {
          enabled: false
        },
        crosshairs: {
          show: false
        }
      }
    };
  }
  radialBar() {
    return {
      chart: {
        animations: {
          dynamicAnimation: {
            enabled: true,
            speed: 800
          }
        },
        toolbar: {
          show: false
        }
      },
      fill: {
        gradient: {
          shade: "dark",
          shadeIntensity: 0.4,
          inverseColors: false,
          type: "diagonal2",
          opacityFrom: 1,
          opacityTo: 1,
          stops: [70, 98, 100]
        }
      },
      legend: {
        show: false,
        position: "right"
      },
      tooltip: {
        enabled: false,
        fillSeriesColor: true
      },
      grid: {
        padding: {
          left: 0,
          right: 0,
          top: 0,
          bottom: 0
        }
      }
    };
  }
  /**
   * @param {import('../../types/internal').ChartStateW} w
   * @param {number} seriesIndex
   * @param {number} dataPointIndex
   * @param {any[]} labels
   * @param {string} chartType
   */
  _getBoxTooltip(w, seriesIndex, dataPointIndex, labels, chartType) {
    const o = w.candleData.seriesCandleO[seriesIndex][dataPointIndex];
    const h = w.candleData.seriesCandleH[seriesIndex][dataPointIndex];
    const m = w.candleData.seriesCandleM[seriesIndex][dataPointIndex];
    const l = w.candleData.seriesCandleL[seriesIndex][dataPointIndex];
    const c = w.candleData.seriesCandleC[seriesIndex][dataPointIndex];
    const _si = (
      /** @type {Record<string,any>} */
      w.config.series[seriesIndex]
    );
    if (_si.type && _si.type !== chartType) {
      return `<div class="apexcharts-custom-tooltip">
          ${_si.name ? _si.name : "series-" + (seriesIndex + 1)}: <strong>${w.seriesData.series[seriesIndex][dataPointIndex]}</strong>
        </div>`;
    } else {
      return `<div class="apexcharts-tooltip-box apexcharts-tooltip-${w.config.chart.type}"><div>${labels[0]}: <span class="value">` + o + `</span></div><div>${labels[1]}: <span class="value">` + h + "</span></div>" + (m ? `<div>${labels[2]}: <span class="value">` + m + "</span></div>" : "") + `<div>${labels[3]}: <span class="value">` + l + `</span></div><div>${labels[4]}: <span class="value">` + c + "</span></div></div>";
    }
  }
}
const name = "en";
const options = { "months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], "shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], "days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], "shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], "toolbar": { "exportToSVG": "Download SVG", "exportToPNG": "Download PNG", "exportToCSV": "Download CSV", "menu": "Menu", "selection": "Selection", "selectionZoom": "Selection Zoom", "zoomIn": "Zoom In", "zoomOut": "Zoom Out", "pan": "Panning", "reset": "Reset Zoom" } };
const en = {
  name,
  options
};
class Options {
  constructor() {
    this.yAxis = {
      show: true,
      showAlways: false,
      showForNullSeries: true,
      seriesName: void 0,
      opposite: false,
      reversed: false,
      logarithmic: false,
      logBase: 10,
      tickAmount: void 0,
      stepSize: void 0,
      forceNiceScale: false,
      max: void 0,
      min: void 0,
      floating: false,
      decimalsInFloat: void 0,
      labels: {
        show: true,
        showDuplicates: false,
        minWidth: 0,
        maxWidth: 160,
        offsetX: 0,
        offsetY: 0,
        align: void 0,
        rotate: 0,
        padding: 20,
        style: {
          colors: [],
          fontSize: "11px",
          fontWeight: 400,
          fontFamily: void 0,
          cssClass: ""
        },
        formatter: void 0
      },
      axisBorder: {
        show: false,
        color: "#e0e0e0",
        width: 1,
        offsetX: 0,
        offsetY: 0
      },
      axisTicks: {
        show: false,
        color: "#e0e0e0",
        width: 6,
        offsetX: 0,
        offsetY: 0
      },
      title: {
        text: void 0,
        rotate: -90,
        offsetY: 0,
        offsetX: 0,
        style: {
          color: void 0,
          fontSize: "11px",
          fontWeight: 900,
          fontFamily: void 0,
          cssClass: ""
        }
      },
      tooltip: {
        enabled: false,
        offsetX: 0
      },
      crosshairs: {
        show: true,
        position: "front",
        stroke: {
          color: "#b6b6b6",
          width: 1,
          dashArray: 0
        }
      }
    };
    this.pointAnnotation = {
      id: void 0,
      x: 0,
      y: null,
      yAxisIndex: 0,
      seriesIndex: void 0,
      mouseEnter: void 0,
      mouseLeave: void 0,
      click: void 0,
      marker: {
        size: 4,
        fillColor: "#fff",
        strokeWidth: 2,
        strokeColor: "#333",
        shape: "circle",
        offsetX: 0,
        offsetY: 0,
        // radius: 2, // DEPRECATED
        cssClass: ""
      },
      label: {
        borderColor: "#c2c2c2",
        borderWidth: 1,
        borderRadius: 2,
        text: void 0,
        textAnchor: "middle",
        offsetX: 0,
        offsetY: 0,
        mouseEnter: void 0,
        mouseLeave: void 0,
        click: void 0,
        style: {
          background: "#fff",
          color: void 0,
          fontSize: "11px",
          fontFamily: void 0,
          fontWeight: 400,
          cssClass: "",
          padding: {
            left: 5,
            right: 5,
            top: 2,
            bottom: 2
          }
        }
      },
      customSVG: {
        // this will be deprecated in the next major version as it is going to be replaced with a better alternative below (image)
        SVG: void 0,
        cssClass: void 0,
        offsetX: 0,
        offsetY: 0
      },
      image: {
        path: void 0,
        width: 20,
        height: 20,
        offsetX: 0,
        offsetY: 0
      }
    };
    this.yAxisAnnotation = {
      id: void 0,
      y: 0,
      y2: null,
      strokeDashArray: 1,
      fillColor: "#c2c2c2",
      borderColor: "#c2c2c2",
      borderWidth: 1,
      opacity: 0.3,
      offsetX: 0,
      offsetY: 0,
      width: "100%",
      yAxisIndex: 0,
      label: {
        borderColor: "#c2c2c2",
        borderWidth: 1,
        borderRadius: 2,
        text: void 0,
        textAnchor: "end",
        position: "right",
        offsetX: 0,
        offsetY: -3,
        mouseEnter: void 0,
        mouseLeave: void 0,
        click: void 0,
        style: {
          background: "#fff",
          color: void 0,
          fontSize: "11px",
          fontFamily: void 0,
          fontWeight: 400,
          cssClass: "",
          padding: {
            left: 5,
            right: 5,
            top: 2,
            bottom: 2
          }
        }
      }
    };
    this.xAxisAnnotation = {
      id: void 0,
      x: 0,
      x2: null,
      strokeDashArray: 1,
      fillColor: "#c2c2c2",
      borderColor: "#c2c2c2",
      borderWidth: 1,
      opacity: 0.3,
      offsetX: 0,
      offsetY: 0,
      label: {
        borderColor: "#c2c2c2",
        borderWidth: 1,
        borderRadius: 2,
        text: void 0,
        textAnchor: "middle",
        orientation: "vertical",
        position: "top",
        offsetX: 0,
        offsetY: 0,
        mouseEnter: void 0,
        mouseLeave: void 0,
        click: void 0,
        style: {
          background: "#fff",
          color: void 0,
          fontSize: "11px",
          fontFamily: void 0,
          fontWeight: 400,
          cssClass: "",
          padding: {
            left: 5,
            right: 5,
            top: 2,
            bottom: 2
          }
        }
      }
    };
    this.text = {
      x: 0,
      y: 0,
      text: "",
      textAnchor: "start",
      foreColor: void 0,
      fontSize: "13px",
      fontFamily: void 0,
      fontWeight: 400,
      appendTo: ".apexcharts-annotations",
      backgroundColor: "transparent",
      borderColor: "#c2c2c2",
      borderRadius: 0,
      borderWidth: 0,
      paddingLeft: 4,
      paddingRight: 4,
      paddingTop: 2,
      paddingBottom: 2
    };
  }
  init() {
    return {
      annotations: {
        yaxis: [this.yAxisAnnotation],
        xaxis: [this.xAxisAnnotation],
        points: [this.pointAnnotation],
        texts: [],
        images: [],
        shapes: []
      },
      chart: {
        animations: {
          enabled: true,
          speed: 800,
          animateGradually: {
            delay: 150,
            enabled: true
          },
          dynamicAnimation: {
            enabled: true,
            speed: 350
          }
        },
        background: "",
        locales: [en],
        defaultLocale: "en",
        dropShadow: {
          enabled: false,
          enabledOnSeries: void 0,
          top: 2,
          left: 2,
          blur: 4,
          color: "#000",
          opacity: 0.7
        },
        events: {
          animationEnd: void 0,
          beforeMount: void 0,
          mounted: void 0,
          updated: void 0,
          click: void 0,
          mouseMove: void 0,
          mouseLeave: void 0,
          xAxisLabelClick: void 0,
          legendClick: void 0,
          markerClick: void 0,
          selection: void 0,
          dataPointSelection: void 0,
          dataPointMouseEnter: void 0,
          dataPointMouseLeave: void 0,
          beforeZoom: void 0,
          beforeResetZoom: void 0,
          zoomed: void 0,
          scrolled: void 0,
          brushScrolled: void 0,
          keyDown: void 0,
          keyUp: void 0
        },
        foreColor: "#373d3f",
        fontFamily: "Helvetica, Arial, sans-serif",
        height: "auto",
        parentHeightOffset: 15,
        redrawOnParentResize: true,
        redrawOnWindowResize: true,
        id: void 0,
        group: void 0,
        nonce: void 0,
        offsetX: 0,
        offsetY: 0,
        injectStyleSheet: true,
        selection: {
          enabled: false,
          type: "x",
          // selectedPoints: undefined, // default datapoints that should be selected automatically
          fill: {
            color: "#24292e",
            opacity: 0.1
          },
          stroke: {
            width: 1,
            color: "#24292e",
            opacity: 0.4,
            dashArray: 3
          },
          xaxis: {
            min: void 0,
            max: void 0
          },
          yaxis: {
            min: void 0,
            max: void 0
          }
        },
        sparkline: {
          enabled: false
        },
        brush: {
          enabled: false,
          autoScaleYaxis: true,
          target: void 0,
          targets: void 0
        },
        stacked: false,
        stackOnlyBar: true,
        // mixed chart with stacked bars and line series - incorrect line draw #907
        stackType: "normal",
        toolbar: {
          show: true,
          offsetX: 0,
          offsetY: 0,
          tools: {
            download: true,
            selection: true,
            zoom: true,
            zoomin: true,
            zoomout: true,
            pan: true,
            reset: true,
            customIcons: []
          },
          export: {
            csv: {
              filename: void 0,
              columnDelimiter: ",",
              headerCategory: "category",
              headerValue: "value",
              categoryFormatter: void 0,
              valueFormatter: void 0
            },
            png: {
              filename: void 0
            },
            svg: {
              filename: void 0
            },
            scale: void 0,
            width: void 0
          },
          autoSelected: "zoom"
          // accepts -> zoom, pan, selection
        },
        type: "line",
        width: "100%",
        zoom: {
          enabled: true,
          type: "x",
          autoScaleYaxis: false,
          allowMouseWheelZoom: true,
          zoomedArea: {
            fill: {
              color: "#90CAF9",
              opacity: 0.4
            },
            stroke: {
              color: "#0D47A1",
              opacity: 0.4,
              width: 1
            }
          }
        },
        accessibility: {
          enabled: true,
          description: void 0,
          announcements: {
            enabled: true
          },
          keyboard: {
            enabled: true,
            navigation: {
              enabled: true,
              wrapAround: false
            }
          }
        },
        dataReducer: {
          enabled: false,
          algorithm: "lttb",
          targetPoints: 250,
          threshold: 500
        }
      },
      parsing: {
        x: void 0,
        y: void 0
      },
      plotOptions: {
        line: {
          isSlopeChart: false,
          colors: {
            threshold: 0,
            colorAboveThreshold: void 0,
            colorBelowThreshold: void 0
          }
        },
        area: {
          fillTo: "origin"
        },
        bar: {
          horizontal: false,
          columnWidth: "70%",
          // should be in percent 0 - 100
          barHeight: "70%",
          // should be in percent 0 - 100
          distributed: false,
          borderRadius: 0,
          borderRadiusApplication: "around",
          // [around, end]
          borderRadiusWhenStacked: "last",
          // [all, last]
          rangeBarOverlap: true,
          rangeBarGroupRows: false,
          hideZeroBarsWhenGrouped: false,
          isDumbbell: false,
          dumbbellColors: void 0,
          isFunnel: false,
          isFunnel3d: true,
          colors: {
            ranges: [],
            backgroundBarColors: [],
            backgroundBarOpacity: 1,
            backgroundBarRadius: 0
          },
          dataLabels: {
            position: "top",
            // top, center, bottom
            maxItems: 100,
            hideOverflowingLabels: true,
            orientation: "horizontal",
            total: {
              enabled: false,
              formatter: void 0,
              offsetX: 0,
              offsetY: 0,
              style: {
                color: "#373d3f",
                fontSize: "12px",
                fontFamily: void 0,
                fontWeight: 600
              }
            }
          }
        },
        bubble: {
          zScaling: true,
          minBubbleRadius: void 0,
          maxBubbleRadius: void 0
        },
        candlestick: {
          colors: {
            upward: "#00B746",
            downward: "#EF403C"
          },
          wick: {
            useFillColor: true
          }
        },
        boxPlot: {
          colors: {
            upper: "#00E396",
            lower: "#008FFB"
          }
        },
        heatmap: {
          radius: 2,
          enableShades: true,
          shadeIntensity: 0.5,
          reverseNegativeShade: false,
          distributed: false,
          useFillColorAsStroke: false,
          colorScale: {
            inverse: false,
            ranges: [],
            min: void 0,
            max: void 0
          }
        },
        treemap: {
          enableShades: true,
          shadeIntensity: 0.5,
          distributed: false,
          reverseNegativeShade: false,
          useFillColorAsStroke: false,
          borderRadius: 4,
          dataLabels: {
            format: "scale"
            // scale | truncate
          },
          colorScale: {
            inverse: false,
            ranges: [],
            min: void 0,
            max: void 0
          },
          seriesTitle: {
            show: true,
            offsetY: 1,
            offsetX: 1,
            borderColor: "#000",
            borderWidth: 1,
            borderRadius: 2,
            style: {
              background: "rgba(0, 0, 0, 0.6)",
              color: "#fff",
              fontSize: "12px",
              fontFamily: void 0,
              fontWeight: 400,
              cssClass: "",
              padding: {
                left: 6,
                right: 6,
                top: 2,
                bottom: 2
              }
            }
          }
        },
        radialBar: {
          inverseOrder: false,
          startAngle: 0,
          endAngle: 360,
          offsetX: 0,
          offsetY: 0,
          hollow: {
            margin: 5,
            size: "50%",
            background: "transparent",
            image: void 0,
            imageWidth: 150,
            imageHeight: 150,
            imageOffsetX: 0,
            imageOffsetY: 0,
            imageClipped: true,
            position: "front",
            dropShadow: {
              enabled: false,
              top: 0,
              left: 0,
              blur: 3,
              color: "#000",
              opacity: 0.5
            }
          },
          track: {
            show: true,
            startAngle: void 0,
            endAngle: void 0,
            background: "#f2f2f2",
            strokeWidth: "97%",
            opacity: 1,
            margin: 5,
            // margin is in pixels
            dropShadow: {
              enabled: false,
              top: 0,
              left: 0,
              blur: 3,
              color: "#000",
              opacity: 0.5
            }
          },
          dataLabels: {
            show: true,
            name: {
              show: true,
              fontSize: "16px",
              fontFamily: void 0,
              fontWeight: 600,
              color: void 0,
              offsetY: 0,
              /**
               * @param {any} val
               */
              formatter(val) {
                return val;
              }
            },
            value: {
              show: true,
              fontSize: "14px",
              fontFamily: void 0,
              fontWeight: 400,
              color: void 0,
              offsetY: 16,
              /**
               * @param {any} val
               */
              formatter(val) {
                return val + "%";
              }
            },
            total: {
              show: false,
              label: "Total",
              fontSize: "16px",
              fontWeight: 600,
              fontFamily: void 0,
              color: void 0,
              /**
               * @param {import('../../types/internal').ChartStateW} w
               */
              formatter(w) {
                return (
                  /**
                   * @param {number} a
                   * @param {number} b
                   */
                  w.globals.seriesTotals.reduce((a, b) => a + b, 0) / w.seriesData.series.length + "%"
                );
              }
            }
          },
          barLabels: {
            enabled: false,
            offsetX: 0,
            offsetY: 0,
            useSeriesColors: true,
            fontFamily: void 0,
            fontWeight: 600,
            fontSize: "16px",
            /**
             * @param {any} val
             */
            formatter(val) {
              return val;
            },
            onClick: void 0
          }
        },
        pie: {
          customScale: 1,
          offsetX: 0,
          offsetY: 0,
          startAngle: 0,
          endAngle: 360,
          expandOnClick: true,
          dataLabels: {
            // These are the percentage values which are displayed on slice
            offset: 0,
            // offset by which labels will move outside
            minAngleToShowLabel: 10
          },
          donut: {
            size: "65%",
            background: "transparent",
            labels: {
              // These are the inner labels appearing inside donut
              show: false,
              name: {
                show: true,
                fontSize: "16px",
                fontFamily: void 0,
                fontWeight: 600,
                color: void 0,
                offsetY: -10,
                /**
                 * @param {any} val
                 */
                formatter(val) {
                  return val;
                }
              },
              value: {
                show: true,
                fontSize: "20px",
                fontFamily: void 0,
                fontWeight: 400,
                color: void 0,
                offsetY: 10,
                /**
                 * @param {any} val
                 */
                formatter(val) {
                  return val;
                }
              },
              total: {
                show: false,
                showAlways: false,
                label: "Total",
                fontSize: "16px",
                fontWeight: 400,
                fontFamily: void 0,
                color: void 0,
                /**
                 * @param {import('../../types/internal').ChartStateW} w
                 */
                formatter(w) {
                  return w.globals.seriesTotals.reduce((a, b) => a + b, 0);
                }
              }
            }
          }
        },
        polarArea: {
          rings: {
            strokeWidth: 1,
            strokeColor: "#e8e8e8"
          },
          spokes: {
            strokeWidth: 1,
            connectorColors: "#e8e8e8"
          }
        },
        radar: {
          size: void 0,
          offsetX: 0,
          offsetY: 0,
          polygons: {
            // strokeColor: '#e8e8e8', // should be deprecated in the minor version i.e 3.2
            strokeWidth: 1,
            strokeColors: "#e8e8e8",
            connectorColors: "#e8e8e8",
            fill: {
              colors: void 0
            }
          }
        }
      },
      colors: void 0,
      dataLabels: {
        enabled: true,
        enabledOnSeries: void 0,
        /**
         * @param {any} val
         */
        formatter(val) {
          return val !== null ? val : "";
        },
        textAnchor: "middle",
        distributed: false,
        offsetX: 0,
        offsetY: 0,
        style: {
          fontSize: "12px",
          fontFamily: void 0,
          fontWeight: 600,
          colors: void 0
        },
        background: {
          enabled: true,
          foreColor: "#fff",
          backgroundColor: void 0,
          borderRadius: 2,
          padding: 4,
          opacity: 0.9,
          borderWidth: 1,
          borderColor: "#fff",
          dropShadow: {
            enabled: false,
            top: 1,
            left: 1,
            blur: 1,
            color: "#000",
            opacity: 0.8
          }
        },
        dropShadow: {
          enabled: false,
          top: 1,
          left: 1,
          blur: 1,
          color: "#000",
          opacity: 0.8
        }
      },
      fill: {
        type: "solid",
        colors: void 0,
        // array of colors
        opacity: 0.85,
        gradient: {
          shade: "dark",
          type: "horizontal",
          shadeIntensity: 0.5,
          gradientToColors: void 0,
          inverseColors: true,
          opacityFrom: 1,
          opacityTo: 1,
          stops: [0, 50, 100],
          colorStops: []
        },
        image: {
          src: [],
          width: void 0,
          // optional
          height: void 0
          // optional
        },
        pattern: {
          style: "squares",
          // String | Array of Strings
          width: 6,
          height: 6,
          strokeWidth: 2
        }
      },
      forecastDataPoints: {
        count: 0,
        fillOpacity: 0.5,
        strokeWidth: void 0,
        dashArray: 4
      },
      grid: {
        show: true,
        borderColor: "#e0e0e0",
        strokeDashArray: 0,
        position: "back",
        xaxis: {
          lines: {
            show: false
          }
        },
        yaxis: {
          lines: {
            show: true
          }
        },
        row: {
          colors: void 0,
          // takes as array which will be repeated on rows
          opacity: 0.5
        },
        column: {
          colors: void 0,
          // takes an array which will be repeated on columns
          opacity: 0.5
        },
        padding: {
          top: 0,
          right: 10,
          bottom: 0,
          left: 12
        }
      },
      labels: [],
      legend: {
        show: true,
        showForSingleSeries: false,
        showForNullSeries: true,
        showForZeroSeries: true,
        floating: false,
        position: "bottom",
        // whether to position legends in 1 of 4
        // direction - top, bottom, left, right
        horizontalAlign: "center",
        // when position top/bottom, you can specify whether to align legends left, right or center
        inverseOrder: false,
        fontSize: "12px",
        fontFamily: void 0,
        fontWeight: 400,
        width: void 0,
        height: void 0,
        formatter: void 0,
        tooltipHoverFormatter: void 0,
        offsetX: -20,
        offsetY: 4,
        customLegendItems: [],
        clusterGroupedSeries: true,
        clusterGroupedSeriesOrientation: "vertical",
        labels: {
          colors: void 0,
          useSeriesColors: false
        },
        markers: {
          size: 7,
          fillColors: void 0,
          strokeWidth: 1,
          shape: void 0,
          offsetX: 0,
          offsetY: 0,
          customHTML: void 0,
          onClick: void 0
        },
        itemMargin: {
          horizontal: 5,
          vertical: 4
        },
        onItemClick: {
          toggleDataSeries: true
        },
        onItemHover: {
          highlightDataSeries: true
        }
      },
      markers: {
        discrete: [],
        size: 0,
        colors: void 0,
        strokeColors: "#fff",
        strokeWidth: 2,
        strokeOpacity: 0.9,
        strokeDashArray: 0,
        fillOpacity: 1,
        shape: "circle",
        offsetX: 0,
        offsetY: 0,
        showNullDataPoints: true,
        onClick: void 0,
        onDblClick: void 0,
        hover: {
          size: void 0,
          sizeOffset: 3
        }
      },
      noData: {
        text: void 0,
        align: "center",
        offsetX: 0,
        offsetY: 0,
        style: {
          color: void 0,
          fontSize: "14px",
          fontFamily: void 0
        }
      },
      responsive: [],
      // breakpoints should follow ascending order 400, then 700, then 1000
      series: void 0,
      states: {
        hover: {
          filter: {
            type: "lighten"
          }
        },
        active: {
          allowMultipleDataPointsSelection: false,
          filter: {
            type: "darken"
          }
        }
      },
      title: {
        text: void 0,
        align: "left",
        margin: 5,
        offsetX: 0,
        offsetY: 0,
        floating: false,
        style: {
          fontSize: "14px",
          fontWeight: 900,
          fontFamily: void 0,
          color: void 0
        }
      },
      subtitle: {
        text: void 0,
        align: "left",
        margin: 5,
        offsetX: 0,
        offsetY: 30,
        floating: false,
        style: {
          fontSize: "12px",
          fontWeight: 400,
          fontFamily: void 0,
          color: void 0
        }
      },
      stroke: {
        show: true,
        curve: "smooth",
        // "smooth" / "straight" / "monotoneCubic" / "stepline" / "linestep"
        lineCap: "butt",
        // round, butt , square
        width: 2,
        colors: void 0,
        // array of colors
        dashArray: 0,
        // single value or array of values
        fill: {
          type: "solid",
          colors: void 0,
          // array of colors
          opacity: 0.85,
          gradient: {
            shade: "dark",
            type: "horizontal",
            shadeIntensity: 0.5,
            gradientToColors: void 0,
            inverseColors: true,
            opacityFrom: 1,
            opacityTo: 1,
            stops: [0, 50, 100],
            colorStops: []
          }
        }
      },
      tooltip: {
        enabled: true,
        enabledOnSeries: void 0,
        shared: true,
        hideEmptySeries: false,
        followCursor: false,
        // when disabled, the tooltip will show on top of the series instead of mouse position
        intersect: false,
        // when enabled, tooltip will only show when user directly hovers over point
        inverseOrder: false,
        custom: void 0,
        fillSeriesColor: false,
        theme: "light",
        cssClass: "",
        style: {
          fontSize: "12px",
          fontFamily: void 0
        },
        onDatasetHover: {
          highlightDataSeries: false
        },
        x: {
          // x value
          show: true,
          format: "dd MMM",
          // dd/MM, dd MMM yy, dd MMM yyyy
          formatter: void 0
          // a custom user supplied formatter function
        },
        y: {
          formatter: void 0,
          title: {
            /**
             * @param {string} seriesName
             */
            formatter(seriesName) {
              return seriesName ? seriesName + ": " : "";
            }
          }
        },
        z: {
          formatter: void 0,
          title: "Size: "
        },
        marker: {
          show: true,
          fillColors: void 0
        },
        items: {
          display: "flex"
        },
        fixed: {
          enabled: false,
          position: "topRight",
          // topRight, topLeft, bottomRight, bottomLeft
          offsetX: 0,
          offsetY: 0
        }
      },
      xaxis: {
        type: "category",
        categories: [],
        convertedCatToNumeric: false,
        // internal property which should not be altered outside
        offsetX: 0,
        offsetY: 0,
        overwriteCategories: void 0,
        labels: {
          show: true,
          rotate: -45,
          rotateAlways: false,
          hideOverlappingLabels: true,
          trim: false,
          minHeight: void 0,
          maxHeight: 120,
          showDuplicates: true,
          style: {
            colors: [],
            fontSize: "12px",
            fontWeight: 400,
            fontFamily: void 0,
            cssClass: ""
          },
          offsetX: 0,
          offsetY: 0,
          format: void 0,
          formatter: void 0,
          // custom formatter function which will override format
          datetimeUTC: true,
          datetimeFormatter: {
            year: "yyyy",
            month: "MMM 'yy",
            day: "dd MMM",
            hour: "HH:mm",
            minute: "HH:mm:ss",
            second: "HH:mm:ss"
          }
        },
        group: {
          groups: [],
          style: {
            colors: [],
            fontSize: "12px",
            fontWeight: 400,
            fontFamily: void 0,
            cssClass: ""
          }
        },
        axisBorder: {
          show: true,
          color: "#e0e0e0",
          width: "100%",
          height: 1,
          offsetX: 0,
          offsetY: 0
        },
        axisTicks: {
          show: true,
          color: "#e0e0e0",
          height: 6,
          offsetX: 0,
          offsetY: 0
        },
        stepSize: void 0,
        tickAmount: void 0,
        tickPlacement: "on",
        min: void 0,
        max: void 0,
        range: void 0,
        floating: false,
        decimalsInFloat: void 0,
        position: "bottom",
        title: {
          text: void 0,
          offsetX: 0,
          offsetY: 0,
          style: {
            color: void 0,
            fontSize: "12px",
            fontWeight: 900,
            fontFamily: void 0,
            cssClass: ""
          }
        },
        crosshairs: {
          show: true,
          width: 1,
          // tickWidth/barWidth or an integer
          position: "back",
          opacity: 0.9,
          stroke: {
            color: "#b6b6b6",
            width: 1,
            dashArray: 3
          },
          fill: {
            type: "solid",
            // solid, gradient
            color: "#B1B9C4",
            gradient: {
              colorFrom: "#D8E3F0",
              colorTo: "#BED1E6",
              stops: [0, 100],
              opacityFrom: 0.4,
              opacityTo: 0.5
            }
          },
          dropShadow: {
            enabled: false,
            left: 0,
            top: 0,
            blur: 1,
            opacity: 0.8
          }
        },
        tooltip: {
          enabled: true,
          offsetY: 0,
          formatter: void 0,
          style: {
            fontSize: "12px",
            fontFamily: void 0
          }
        }
      },
      yaxis: this.yAxis,
      theme: {
        mode: "",
        palette: "palette1",
        // If defined, it will overwrite globals.colors variable
        monochrome: {
          // monochrome allows you to select just 1 color and fill out the rest with light/dark shade (intensity can be selected)
          enabled: false,
          color: "#008FFB",
          shadeTo: "light",
          shadeIntensity: 0.65
        },
        accessibility: {
          colorBlindMode: ""
          // '' | 'deuteranopia' | 'protanopia' | 'tritanopia' | 'highContrast'
        }
      }
    };
  }
}
class Config {
  /**
   * @param {Record<string, any>} opts
   */
  constructor(opts) {
    this.opts = opts;
  }
  /** @param {{responsiveOverride: any}} opts */
  init({ responsiveOverride }) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
    let opts = this.opts;
    const options2 = new Options();
    const defaults = new Defaults(opts);
    this.chartType = opts.chart.type;
    opts = this.extendYAxis(opts);
    opts = this.extendAnnotations(opts);
    let config = options2.init();
    let newDefaults = {};
    if (opts && typeof opts === "object") {
      let chartDefaults = {};
      const chartTypes = [
        "line",
        "area",
        "bar",
        "candlestick",
        "boxPlot",
        "rangeBar",
        "rangeArea",
        "bubble",
        "scatter",
        "heatmap",
        "treemap",
        "pie",
        "polarArea",
        "donut",
        "radar",
        "radialBar"
      ];
      if (chartTypes.indexOf(opts.chart.type) !== -1) {
        chartDefaults = /** @type {any} */
        defaults[opts.chart.type]();
      } else {
        chartDefaults = defaults.line();
      }
      if ((_b = (_a = opts.plotOptions) == null ? void 0 : _a.bar) == null ? void 0 : _b.isFunnel) {
        chartDefaults = defaults.funnel();
      }
      if (opts.chart.stacked && opts.chart.type === "bar") {
        chartDefaults = defaults.stackedBars();
      }
      if ((_c = opts.chart.brush) == null ? void 0 : _c.enabled) {
        chartDefaults = defaults.brush(chartDefaults);
      }
      if ((_e = (_d = opts.plotOptions) == null ? void 0 : _d.line) == null ? void 0 : _e.isSlopeChart) {
        chartDefaults = defaults.slope();
      }
      if (opts.chart.stacked && opts.chart.stackType === "100%") {
        opts = defaults.stacked100(opts);
      }
      if ((_g = (_f = opts.plotOptions) == null ? void 0 : _f.bar) == null ? void 0 : _g.isDumbbell) {
        opts = defaults.dumbbell(opts);
      }
      this.checkForDarkTheme(Environment.getApex());
      this.checkForDarkTheme(opts);
      opts.xaxis = opts.xaxis || Environment.getApex().xaxis || {};
      if (!responsiveOverride) {
        opts.xaxis.convertedCatToNumeric = false;
      }
      opts = this.checkForCatToNumericXAxis(this.chartType, chartDefaults, opts);
      if (((_h = opts.chart.sparkline) == null ? void 0 : _h.enabled) || ((_j = (_i = Environment.getApex().chart) == null ? void 0 : _i.sparkline) == null ? void 0 : _j.enabled)) {
        chartDefaults = defaults.sparkline(chartDefaults);
      }
      newDefaults = Utils$1.extend(config, chartDefaults);
    }
    const mergedWithDefaultConfig = Utils$1.extend(
      newDefaults,
      Environment.getApex()
    );
    config = Utils$1.extend(mergedWithDefaultConfig, opts);
    config = this.handleUserInputErrors(config);
    return config;
  }
  /**
   * @param {string} chartType
   * @param {Record<string, any>} chartDefaults
   * @param {Record<string, any>} opts
   */
  checkForCatToNumericXAxis(chartType, chartDefaults, opts) {
    var _a, _b;
    const defaults = new Defaults(opts);
    const isBarHorizontal = (chartType === "bar" || chartType === "boxPlot") && ((_b = (_a = opts.plotOptions) == null ? void 0 : _a.bar) == null ? void 0 : _b.horizontal);
    const unsupportedZoom = chartType === "pie" || chartType === "polarArea" || chartType === "donut" || chartType === "radar" || chartType === "radialBar" || chartType === "heatmap";
    const notNumericXAxis = opts.xaxis.type !== "datetime" && opts.xaxis.type !== "numeric";
    const tickPlacement = opts.xaxis.tickPlacement ? opts.xaxis.tickPlacement : chartDefaults.xaxis && chartDefaults.xaxis.tickPlacement;
    if (!isBarHorizontal && !unsupportedZoom && notNumericXAxis && tickPlacement !== "between") {
      opts = defaults.convertCatToNumeric(opts);
    }
    return opts;
  }
  /**
   * @param {Record<string, any>} opts
   * @param {import('../../types/internal').ChartStateW} [w]
   */
  extendYAxis(opts, w) {
    const options2 = new Options();
    if (typeof opts.yaxis === "undefined" || !opts.yaxis || Array.isArray(opts.yaxis) && opts.yaxis.length === 0) {
      opts.yaxis = {};
    }
    const globalApex = Environment.getApex();
    if (opts.yaxis.constructor !== Array && globalApex.yaxis && globalApex.yaxis.constructor !== Array) {
      opts.yaxis = Utils$1.extend(opts.yaxis, globalApex.yaxis);
    }
    if (opts.yaxis.constructor !== Array) {
      opts.yaxis = [Utils$1.extend(options2.yAxis, opts.yaxis)];
    } else {
      opts.yaxis = Utils$1.extendArray(opts.yaxis, options2.yAxis);
    }
    let isLogY = false;
    opts.yaxis.forEach((y) => {
      if (y.logarithmic) {
        isLogY = true;
      }
    });
    let series = opts.series;
    if (w && !series) {
      series = w.config.series;
    }
    if (isLogY && series.length !== opts.yaxis.length && series.length) {
      opts.yaxis = series.map((s, i) => {
        if (!s.name) {
          series[i].name = `series-${i + 1}`;
        }
        if (opts.yaxis[i]) {
          opts.yaxis[i].seriesName = series[i].name;
          return opts.yaxis[i];
        } else {
          const newYaxis = Utils$1.extend(options2.yAxis, opts.yaxis[0]);
          newYaxis.show = false;
          return newYaxis;
        }
      });
    }
    if (isLogY && series.length > 1 && series.length !== opts.yaxis.length) {
      console.warn(
        "A multi-series logarithmic chart should have equal number of series and y-axes"
      );
    }
    return opts;
  }
  // annotations also accepts array, so we need to extend them manually
  /**
   * @param {Record<string, any>} opts
   */
  extendAnnotations(opts) {
    if (typeof opts.annotations === "undefined") {
      opts.annotations = {};
      opts.annotations.yaxis = [];
      opts.annotations.xaxis = [];
      opts.annotations.points = [];
    }
    opts = this.extendYAxisAnnotations(opts);
    opts = this.extendXAxisAnnotations(opts);
    opts = this.extendPointAnnotations(opts);
    return opts;
  }
  /**
   * @param {Record<string, any>} opts
   */
  extendYAxisAnnotations(opts) {
    const options2 = new Options();
    opts.annotations.yaxis = Utils$1.extendArray(
      typeof opts.annotations.yaxis !== "undefined" ? opts.annotations.yaxis : [],
      options2.yAxisAnnotation
    );
    return opts;
  }
  /**
   * @param {Record<string, any>} opts
   */
  extendXAxisAnnotations(opts) {
    const options2 = new Options();
    opts.annotations.xaxis = Utils$1.extendArray(
      typeof opts.annotations.xaxis !== "undefined" ? opts.annotations.xaxis : [],
      options2.xAxisAnnotation
    );
    return opts;
  }
  /**
   * @param {Record<string, any>} opts
   */
  extendPointAnnotations(opts) {
    const options2 = new Options();
    opts.annotations.points = Utils$1.extendArray(
      typeof opts.annotations.points !== "undefined" ? opts.annotations.points : [],
      options2.pointAnnotation
    );
    return opts;
  }
  /**
   * @param {Record<string, any>} opts
   */
  checkForDarkTheme(opts) {
    if (opts.theme && opts.theme.mode === "dark") {
      if (!opts.tooltip) {
        opts.tooltip = {};
      }
      if (opts.tooltip.theme !== "light") {
        opts.tooltip.theme = "dark";
      }
      if (!opts.chart.foreColor) {
        opts.chart.foreColor = "#f6f7f8";
      }
      if (!opts.theme.palette) {
        opts.theme.palette = "palette4";
      }
    }
  }
  /**
   * @param {any} opts
   */
  handleUserInputErrors(opts) {
    const config = opts;
    if (config.tooltip.shared && config.tooltip.intersect) {
      throw new Error(
        "tooltip.shared cannot be enabled when tooltip.intersect is true. Turn off any other option by setting it to false."
      );
    }
    if (config.chart.type === "bar" && config.plotOptions.bar.horizontal) {
      if (config.yaxis.length > 1) {
        throw new Error(
          "Multiple Y Axis for bars are not supported. Switch to column chart by setting plotOptions.bar.horizontal=false"
        );
      }
      if (config.yaxis[0].reversed) {
        config.yaxis[0].opposite = true;
      }
      config.xaxis.tooltip.enabled = false;
      config.yaxis[0].tooltip.enabled = false;
      config.chart.zoom.enabled = false;
    }
    if (config.chart.type === "bar" || config.chart.type === "rangeBar") {
      if (config.tooltip.shared) {
        if (config.xaxis.crosshairs.width === "barWidth" && config.series.length > 1) {
          config.xaxis.crosshairs.width = "tickWidth";
        }
      }
    }
    if (config.chart.type === "candlestick" || config.chart.type === "boxPlot") {
      if (config.yaxis[0].reversed) {
        console.warn(
          `Reversed y-axis in ${config.chart.type} chart is not supported.`
        );
        config.yaxis[0].reversed = false;
      }
    }
    return config;
  }
}
const LINE_HEIGHT_RATIO = 1.618;
const NICE_SCALE_ALLOWED_MAG_MSD = [
  [1, 1, 2, 5, 5, 5, 10, 10, 10, 10, 10],
  [1, 1, 2, 5, 5, 5, 10, 10, 10, 10, 10]
];
const NICE_SCALE_DEFAULT_TICKS = [
  1,
  2,
  4,
  4,
  6,
  6,
  6,
  6,
  6,
  6,
  6,
  6,
  6,
  6,
  6,
  6,
  6,
  6,
  12,
  12,
  12,
  12,
  12,
  12,
  12,
  12,
  12,
  24
];
class Globals {
  /**
   * @param {any} gl
   */
  initGlobalVars(gl) {
    gl.series = [];
    gl.seriesCandleO = [];
    gl.seriesCandleH = [];
    gl.seriesCandleM = [];
    gl.seriesCandleL = [];
    gl.seriesCandleC = [];
    gl.seriesRangeStart = [];
    gl.seriesRangeEnd = [];
    gl.seriesRange = [];
    gl.seriesPercent = [];
    gl.seriesGoals = [];
    gl.seriesX = [];
    gl.seriesZ = [];
    gl.seriesNames = [];
    gl.seriesTotals = [];
    gl.seriesLog = [];
    gl.seriesColors = [];
    gl.stackedSeriesTotals = [];
    gl.seriesXvalues = [];
    gl.seriesYvalues = [];
    gl.dataWasParsed = false;
    gl.originalSeries = null;
    gl.maxValsInArrayIndex = 0;
    gl.yValueDecimal = 0;
    gl.allSeriesHasEqualX = true;
    gl.labels = [];
    gl.hasXaxisGroups = false;
    gl.groups = [];
    gl.barGroups = [];
    gl.lineGroups = [];
    gl.areaGroups = [];
    gl.hasSeriesGroups = false;
    gl.seriesGroups = [];
    gl.categoryLabels = [];
    gl.timescaleLabels = [];
    gl.noLabelsProvided = false;
    gl.isXNumeric = false;
    gl.skipLastTimelinelabel = false;
    gl.skipFirstTimelinelabel = false;
    gl.isDataXYZ = false;
    gl.isMultiLineX = false;
    gl.isMultipleYAxis = false;
    gl.maxY = -Number.MAX_VALUE;
    gl.minY = Number.MIN_VALUE;
    gl.minYArr = [];
    gl.maxYArr = [];
    gl.maxX = -Number.MAX_VALUE;
    gl.minX = Number.MAX_VALUE;
    gl.initialMaxX = -Number.MAX_VALUE;
    gl.initialMinX = Number.MAX_VALUE;
    gl.maxDate = 0;
    gl.minDate = Number.MAX_VALUE;
    gl.minZ = Number.MAX_VALUE;
    gl.maxZ = -Number.MAX_VALUE;
    gl.minXDiff = Number.MAX_VALUE;
    gl.yAxisScale = [];
    gl.xAxisScale = null;
    gl.xAxisTicksPositions = [];
    gl.xRange = 0;
    gl.yRange = [];
    gl.zRange = 0;
    gl.dataPoints = 0;
    gl.xTickAmount = 0;
    gl.multiAxisTickAmount = 0;
    gl.disableZoomIn = false;
    gl.disableZoomOut = false;
    gl.yLabelsCoords = [];
    gl.yTitleCoords = [];
    gl.barPadForNumericAxis = 0;
    gl.padHorizontal = 0;
    gl.rotateXLabels = false;
    gl.overlappingXLabels = false;
    gl.radialSize = 0;
    gl.barHeight = 0;
    gl.barWidth = 0;
    gl.animationEnded = false;
    gl.resizeTimer = null;
    gl.selectionResizeTimer = null;
    gl.lastWheelExecution = 0;
    gl.delayedElements = [];
    gl.pointsArray = [];
    gl.dataLabelsRects = [];
    gl.lastDrawnDataLabelsIndexes = [];
    gl.textRectsCache = /* @__PURE__ */ new Map();
    gl.domCache = /* @__PURE__ */ new Map();
    gl.dimensionCache = {};
    gl.cachedSelectors = {};
    if (!gl.seriesNS) {
      this._attachNamespaces(gl);
    }
  }
  /**
   * Attach domain-grouped namespace sub-objects onto gl.
   * Each sub-object is a plain object whose properties are defined as
   * getters/setters that read/write the canonical flat properties on gl.
   * This means there is exactly ONE storage location per value — no copies,
   * no sync needed.
   *
   * Namespaces:
   *   gl.series  — parsed series data and chart-type-specific arrays
   *   gl.axes    — axis bounds, scales, ranges, tick state
   *   gl.layout  — SVG/grid dimensions, translations, label sizes
   *   gl.cache   — DOM caches, timers, observers, drawing scratch space
   *
   * Note: interact state lives on w.interact (not gl) — see Base.js.
   * @param {any} gl
   */
  _attachNamespaces(gl) {
    const proxy = (ns, key, nsKey = key) => {
      Object.defineProperty(ns, nsKey, {
        get() {
          return gl[key];
        },
        set(v) {
          gl[key] = v;
        },
        enumerable: true,
        configurable: true
      });
    };
    const seriesNS = {};
    proxy(seriesNS, "series", "data");
    for (const key of [
      "seriesNames",
      "seriesX",
      "seriesZ",
      "seriesXvalues",
      "seriesYvalues",
      "seriesGoals",
      "seriesLog",
      "seriesColors",
      "seriesPercent",
      "seriesTotals",
      "stackedSeriesTotals",
      "seriesCandleO",
      "seriesCandleH",
      "seriesCandleM",
      "seriesCandleL",
      "seriesCandleC",
      "seriesRangeStart",
      "seriesRangeEnd",
      "seriesRange",
      "seriesYAxisMap",
      "seriesYAxisReverseMap",
      "seriesGroups",
      "barGroups",
      "lineGroups",
      "areaGroups",
      "originalSeries",
      "collapsedSeries",
      "collapsedSeriesIndices",
      "ancillaryCollapsedSeries",
      "ancillaryCollapsedSeriesIndices",
      "allSeriesCollapsed",
      "risingSeries",
      "previousPaths",
      "ignoreYAxisIndexes",
      "labels",
      "categoryLabels",
      "timescaleLabels",
      "groups"
    ]) {
      proxy(seriesNS, key);
    }
    Object.defineProperty(gl, "seriesNS", {
      value: seriesNS,
      writable: false,
      enumerable: false,
      configurable: true
    });
    const axesNS = {};
    for (const key of [
      "minX",
      "maxX",
      "initialMinX",
      "initialMaxX",
      "minY",
      "maxY",
      "minYArr",
      "maxYArr",
      "minZ",
      "maxZ",
      "minDate",
      "maxDate",
      "minXDiff",
      "xRange",
      "yRange",
      "zRange",
      "xAxisScale",
      "yAxisScale",
      "xAxisTicksPositions",
      "xTickAmount",
      "multiAxisTickAmount",
      "dataPoints",
      "maxValsInArrayIndex",
      "isXNumeric",
      "isMultipleYAxis",
      "isMultiLineX",
      "isDataXYZ",
      "dataFormatXNumeric",
      "allSeriesHasEqualX",
      "hasNullValues",
      "dataWasParsed",
      "hasXaxisGroups",
      "hasSeriesGroups",
      "skipFirstTimelinelabel",
      "skipLastTimelinelabel",
      "yValueDecimal",
      "invalidLogScale",
      "noLabelsProvided"
    ]) {
      proxy(axesNS, key);
    }
    Object.defineProperty(gl, "axes", {
      value: axesNS,
      writable: false,
      enumerable: false,
      configurable: true
    });
    const layoutNS = {};
    for (const key of [
      "svgWidth",
      "svgHeight",
      "gridWidth",
      "gridHeight",
      "translateX",
      "translateY",
      "translateXAxisX",
      "translateXAxisY",
      "translateYAxisX",
      "xAxisLabelsHeight",
      "xAxisGroupLabelsHeight",
      "xAxisLabelsWidth",
      "yAxisLabelsWidth",
      "yAxisWidths",
      "yLabelsCoords",
      "yTitleCoords",
      "padHorizontal",
      "barPadForNumericAxis",
      "rotateXLabels",
      "scaleX",
      "scaleY",
      "radialSize",
      "defaultLabels",
      "overlappingXLabels"
    ]) {
      proxy(layoutNS, key);
    }
    Object.defineProperty(gl, "layout", {
      value: layoutNS,
      writable: false,
      enumerable: false,
      configurable: true
    });
    const cacheNS = {};
    for (const key of [
      "domCache",
      "dimensionCache",
      "cachedSelectors",
      "textRectsCache",
      "pointsArray",
      "dataLabelsRects",
      "lastDrawnDataLabelsIndexes",
      "delayedElements",
      "resizeTimer",
      "selectionResizeTimer",
      "resizeObserver"
    ]) {
      proxy(cacheNS, key);
    }
    Object.defineProperty(gl, "cache", {
      value: cacheNS,
      writable: false,
      enumerable: false,
      configurable: true
    });
  }
  /**
   * Persistent chart state — set ONCE at chart construction and intentionally NOT
   * reset by initGlobalVars.  These values must survive updateSeries / re-render.
   *
   * Rule: if a value is recalculated fresh on every render it belongs in
   * initGlobalVars instead, not here.
   * @returns {import('../../types/internal').ChartGlobals}
   * @param {Record<string, any>} config
   */
  globalVars(config) {
    const globals = {
      // ── Identity (set once, never changes) ───────────────────────────────────
      chartID: null,
      // full chart ID: "apexcharts-<cuid>"
      cuid: null,
      // random suffix only
      // ── Event registry (accumulates listeners, never reset) ───────────────────
      events: {
        beforeMount: [],
        mounted: [],
        updated: [],
        clicked: [],
        selection: [],
        dataPointSelection: [],
        zoomed: [],
        scrolled: []
      },
      // ── Theme colors (set by Theme module after config merge) ─────────────────
      colors: [],
      fill: { colors: [] },
      stroke: { colors: [] },
      dataLabels: { style: { colors: [] } },
      radarPolygons: { fill: { colors: [] } },
      markers: {
        colors: [],
        size: config.markers.size,
        largestSize: 0
      },
      // ── Device / environment detected once at startup ─────────────────────────
      // Note: isTouchDevice lives on w.interact — see Base.js. Shim installed there.
      LINE_HEIGHT_RATIO,
      // ── Chart-type flags (derived from config, set during Core.mount) ─────────
      axisCharts: true,
      // false for pie/radial/treemap etc.
      isSlopeChart: config.plotOptions.line.isSlopeChart,
      comboCharts: false,
      // true when mixing line + column series
      // ── Config snapshots (backups for zoom-reset / updateOptions) ────────────
      initialConfig: null,
      // deep clone of the original user config
      initialSeries: [],
      lastXAxis: [],
      lastYAxis: [],
      // ── User interaction state (must survive re-renders) ──────────────────────
      // Note: zoomEnabled, panEnabled, selectionEnabled, zoomed, selection,
      //       visibleXRange, selectedDataPoints, mousedown, clientX, clientY,
      //       lastClientPosition, lastWheelExecution, capturedSeriesIndex,
      //       capturedDataPointIndex, disableZoomIn, disableZoomOut, isTouchDevice
      //       live on w.interact — see Base.js. Backward-compat shims installed there.
      // Series collapse state (user-driven, must persist across re-renders)
      allSeriesCollapsed: false,
      collapsedSeries: [],
      collapsedSeriesIndices: [],
      ancillaryCollapsedSeries: [],
      ancillaryCollapsedSeriesIndices: [],
      risingSeries: [],
      // series being re-shown after collapse
      ignoreYAxisIndexes: [],
      // y-axis indices excluded during series collapse
      // ── Lifecycle / update flags ──────────────────────────────────────────────
      isDirty: false,
      // true when user called an update method manually
      isExecCalled: false,
      // true when update came via exec()
      dataChanged: false,
      // true when series data was changed dynamically
      resized: false,
      // true after a container resize
      // ── Data format flags (derived from config/series, stable between renders) ─
      // Note: dataFormatXNumeric lives on w.axisFlags — see Base.js. Shim installed there.
      invalidLogScale: false,
      // true when log scale requested but data is invalid
      hasNullValues: false,
      // true when any series contains null values
      // Persistent data tracking
      columnSeries: null,
      // tracks which series are rendered as bars/columns
      yaxis: null,
      // resolved yaxis config array
      total: 0,
      // running total (used by pie/radial)
      // ── Animation control ─────────────────────────────────────────────────────
      shouldAnimate: true,
      previousPaths: [],
      // paths from previous render — source for enter animation
      // ── SVG viewport (set by Dimensions, but persistent as layout anchor) ─────
      svgWidth: 0,
      svgHeight: 0,
      // Note: gridWidth, gridHeight, translateX, translateY, translateXAxisX,
      // translateXAxisY, xAxisLabelsHeight, xAxisGroupLabelsHeight, xAxisLabelsWidth,
      // rotateXLabels, xAxisHeight, yLabelsCoords, yTitleCoords live on w.layout —
      // see Base.js. Backward-compat shims installed there.
      defaultLabels: false,
      // Note: formatter properties (xLabelFormatter, yLabelFormatters, etc.) live on
      // w.formatters — see Base.js. Backward-compat shims installed there.
      yAxisLabelsWidth: 0,
      scaleX: 1,
      scaleY: 1,
      translateYAxisX: [],
      yAxisWidths: [],
      // ── Instances (created once, replaced only on full re-init) ──────────────
      tooltip: null,
      resizeObserver: null,
      // ── Locale (loaded once; changes only via setLocale()) ───────────────────
      locale: {},
      // ── Method queue (deferred calls during async operations) ────────────────
      memory: {
        methodsToExec: []
      },
      // ── Scale configuration constants — imported from utils/Constants.js ──────
      niceScaleAllowedMagMsd: NICE_SCALE_ALLOWED_MAG_MSD,
      niceScaleDefaultTicks: NICE_SCALE_DEFAULT_TICKS,
      // ── Multi-axis series mapping ─────────────────────────────────────────────
      seriesYAxisMap: [],
      // yAxis index → series indices[]
      seriesYAxisReverseMap: [],
      // series index → yAxis index
      noData: false
      // true when there is nothing to render
    };
    return (
      /** @type {import('../../types/internal').ChartGlobals} */
      /** @type {unknown} */
      globals
    );
  }
  /**
   * @param {Record<string, any>} config
   */
  init(config) {
    const globals = this.globalVars(config);
    this.initGlobalVars(globals);
    globals.initialConfig = Utils$1.extend({}, config);
    globals.initialSeries = Utils$1.clone(config.series);
    globals.lastXAxis = Utils$1.clone(
      /** @type {NonNullable<typeof globals.initialConfig>} */
      globals.initialConfig.xaxis
    );
    globals.lastYAxis = Utils$1.clone(
      /** @type {NonNullable<typeof globals.initialConfig>} */
      globals.initialConfig.yaxis
    );
    return globals;
  }
}
class Base {
  /**
   * @param {object} opts
   */
  constructor(opts) {
    this.opts = opts;
  }
  /**
   * Build and return the full chart state object `w`.
   * @returns {import('../types/internal').ChartStateW}
   */
  init() {
    const config = new Config(this.opts).init({ responsiveOverride: false });
    const globals = new Globals().init(config);
    const w = {
      config,
      globals,
      dom: {},
      // DOM node cache — lives here, not inside globals
      interact: {
        // Tool mode (derived from toolbar config at construction, updated by Toolbar)
        zoomEnabled: config.chart.toolbar.autoSelected === "zoom" && config.chart.toolbar.tools.zoom && config.chart.zoom.enabled,
        panEnabled: config.chart.toolbar.autoSelected === "pan" && config.chart.toolbar.tools.pan,
        selectionEnabled: config.chart.toolbar.autoSelected === "selection" && config.chart.toolbar.tools.selection,
        // Zoom / pan state (user-driven, must persist across re-renders)
        zoomed: false,
        selection: void 0,
        visibleXRange: void 0,
        selectedDataPoints: [],
        // Mouse / pointer state
        mousedown: false,
        clientX: null,
        clientY: null,
        lastClientPosition: {},
        lastWheelExecution: 0,
        // Tooltip capture state
        capturedSeriesIndex: -1,
        capturedDataPointIndex: -1,
        // Timescale zoom bounds (reset per render by TimeScale)
        disableZoomIn: false,
        disableZoomOut: false,
        // Device detection (set once at construction)
        isTouchDevice: Environment.isBrowser() ? "ontouchstart" in window || navigator.maxTouchPoints > 0 : false
      },
      formatters: {
        // Populated by Formatters.setLabelFormatters() each render
        xLabelFormatter: void 0,
        yLabelFormatters: [],
        xaxisTooltipFormatter: void 0,
        ttKeyFormatter: void 0,
        ttVal: void 0,
        ttZFormatter: void 0,
        legendFormatter: void 0
      },
      // Candlestick / boxplot OHLC arrays — written by Data.handleCandleStickBoxData()
      // each render; empty for all other chart types.
      candleData: {
        seriesCandleO: [],
        seriesCandleH: [],
        seriesCandleM: [],
        seriesCandleL: [],
        seriesCandleC: []
      },
      // Range chart arrays — written by Data.handleRangeData() each render;
      // empty for all other chart types.
      rangeData: {
        seriesRangeStart: [],
        seriesRangeEnd: [],
        seriesRange: []
      },
      // Label / category data — written by Data.parseData() and TimeScale each render.
      labelData: {
        labels: [],
        categoryLabels: [],
        timescaleLabels: [],
        // written by TimeScale.calculateTimeScaleMinMax()
        hasXaxisGroups: false,
        groups: [],
        seriesGroups: []
      },
      // Axis / parsing behaviour flags — written by Data.parseData() each render.
      axisFlags: {
        isXNumeric: false,
        dataFormatXNumeric: false,
        isDataXYZ: false,
        isRangeData: false,
        isRangeBar: false,
        isMultiLineX: false,
        noLabelsProvided: false,
        dataWasParsed: false
      },
      // Parsed series data — written by Data.parseData() each render.
      // Note: initialSeries and originalSeries are intentionally excluded —
      // they are persistent (survive re-renders) and remain on w.globals.
      seriesData: {
        series: [],
        // main y-values array
        seriesNames: [],
        seriesX: [],
        seriesZ: [],
        seriesColors: [],
        seriesGoals: [],
        stackedSeriesTotals: [],
        stackedSeriesTotalsByGroups: []
      },
      // Grid / axis layout computed by Dimensions.plotCoords() each render.
      // gridWidth/gridHeight/translateX/translateY are also used as starting
      // points by Dimensions on the next render (accumulated values), so the
      // shim must be bidirectional — reads and writes both route correctly.
      layout: {
        gridHeight: 0,
        gridWidth: 0,
        translateX: 0,
        translateY: 0,
        translateXAxisX: 0,
        translateXAxisY: 0,
        rotateXLabels: false,
        xAxisHeight: 0,
        xAxisLabelsHeight: 0,
        xAxisGroupLabelsHeight: 0,
        xAxisLabelsWidth: 0,
        yLabelsCoords: [],
        yTitleCoords: []
      }
    };
    Object.defineProperty(globals, "dom", {
      get() {
        return w.dom;
      },
      set(v) {
        w.dom = v;
      },
      enumerable: false,
      configurable: true
    });
    for (const key of [
      "xLabelFormatter",
      "yLabelFormatters",
      "xaxisTooltipFormatter",
      "ttKeyFormatter",
      "ttVal",
      "ttZFormatter",
      "legendFormatter"
    ]) {
      Object.defineProperty(globals, key, {
        get() {
          return (
            /** @type {Record<string,any>} */
            w.formatters[key]
          );
        },
        set(v) {
          w.formatters[key] = v;
        },
        enumerable: false,
        configurable: true
      });
    }
    for (const key of [
      "zoomEnabled",
      "panEnabled",
      "selectionEnabled",
      "zoomed",
      "selection",
      "visibleXRange",
      "selectedDataPoints",
      "mousedown",
      "clientX",
      "clientY",
      "lastClientPosition",
      "lastWheelExecution",
      "capturedSeriesIndex",
      "capturedDataPointIndex",
      "disableZoomIn",
      "disableZoomOut",
      "isTouchDevice"
    ]) {
      Object.defineProperty(globals, key, {
        get() {
          return (
            /** @type {Record<string,any>} */
            w.interact[key]
          );
        },
        set(v) {
          w.interact[key] = v;
        },
        enumerable: false,
        configurable: true
      });
    }
    for (const key of [
      "gridHeight",
      "gridWidth",
      "translateX",
      "translateY",
      "translateXAxisX",
      "translateXAxisY",
      "rotateXLabels",
      "xAxisHeight",
      "xAxisLabelsHeight",
      "xAxisGroupLabelsHeight",
      "xAxisLabelsWidth",
      "yLabelsCoords",
      "yTitleCoords"
    ]) {
      Object.defineProperty(globals, key, {
        get() {
          return (
            /** @type {Record<string,any>} */
            w.layout[key]
          );
        },
        set(v) {
          w.layout[key] = v;
        },
        enumerable: false,
        configurable: true
      });
    }
    for (const key of [
      "series",
      "seriesNames",
      "seriesX",
      "seriesZ",
      "seriesColors",
      "seriesGoals",
      "stackedSeriesTotals",
      "stackedSeriesTotalsByGroups"
    ]) {
      Object.defineProperty(globals, key, {
        get() {
          return (
            /** @type {Record<string,any>} */
            w.seriesData[key]
          );
        },
        set(v) {
          w.seriesData[key] = v;
        },
        enumerable: false,
        configurable: true
      });
    }
    for (const key of [
      "isXNumeric",
      "dataFormatXNumeric",
      "isDataXYZ",
      "isRangeData",
      "isRangeBar",
      "isMultiLineX",
      "noLabelsProvided",
      "dataWasParsed"
    ]) {
      Object.defineProperty(globals, key, {
        get() {
          return (
            /** @type {Record<string,any>} */
            w.axisFlags[key]
          );
        },
        set(v) {
          w.axisFlags[key] = v;
        },
        enumerable: false,
        configurable: true
      });
    }
    for (const key of [
      "labels",
      "categoryLabels",
      "timescaleLabels",
      "hasXaxisGroups",
      "groups",
      "seriesGroups"
    ]) {
      Object.defineProperty(globals, key, {
        get() {
          return (
            /** @type {Record<string,any>} */
            w.labelData[key]
          );
        },
        set(v) {
          w.labelData[key] = v;
        },
        enumerable: false,
        configurable: true
      });
    }
    for (const key of ["seriesRangeStart", "seriesRangeEnd", "seriesRange"]) {
      Object.defineProperty(globals, key, {
        get() {
          return (
            /** @type {Record<string,any>} */
            w.rangeData[key]
          );
        },
        set(v) {
          w.rangeData[key] = v;
        },
        enumerable: false,
        configurable: true
      });
    }
    for (const key of [
      "seriesCandleO",
      "seriesCandleH",
      "seriesCandleM",
      "seriesCandleL",
      "seriesCandleC"
    ]) {
      Object.defineProperty(globals, key, {
        get() {
          return (
            /** @type {Record<string,any>} */
            w.candleData[key]
          );
        },
        set(v) {
          w.candleData[key] = v;
        },
        enumerable: false,
        configurable: true
      });
    }
    return (
      /** @type {import('../types/internal').ChartStateW} */
      /** @type {unknown} */
      w
    );
  }
}
class CoreUtils {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
  }
  /**
   * @param {any[]} series
   * @param {string} chartType
   */
  static checkComboSeries(series, chartType) {
    let comboCharts = false;
    let comboBarCount = 0;
    let comboCount = 0;
    if (chartType === void 0) {
      chartType = "line";
    }
    if (series.length && typeof series[0].type !== "undefined") {
      series.forEach((s) => {
        if (s.type === "bar" || s.type === "column" || s.type === "candlestick" || s.type === "boxPlot") {
          comboBarCount++;
        }
        if (typeof s.type !== "undefined" && s.type !== chartType) {
          comboCount++;
        }
      });
    }
    if (comboCount > 0) {
      comboCharts = true;
    }
    return {
      comboBarCount,
      comboCharts
    };
  }
  /**
   * @memberof CoreUtils
   * returns the sum of all individual values in a multiple stacked series
   * Eg. w.seriesData.series = [[32,33,43,12], [2,3,5,1]]
   *  @return [34,36,48,13]
   * @param {number[]} excludedSeriesIndices
   **/
  getStackedSeriesTotals(excludedSeriesIndices = []) {
    const w = this.w;
    const total = [];
    if (w.seriesData.series.length === 0) return total;
    for (let i = 0; i < w.seriesData.series[w.globals.maxValsInArrayIndex].length; i++) {
      let t = 0;
      for (let j = 0; j < w.seriesData.series.length; j++) {
        if (typeof w.seriesData.series[j][i] !== "undefined" && excludedSeriesIndices.indexOf(j) === -1) {
          t += w.seriesData.series[j][i];
        }
      }
      total.push(t);
    }
    return total;
  }
  // get total of the all values inside all series
  /**
   * @param {number | null} [index]
   */
  getSeriesTotalByIndex(index = null) {
    if (index === null) {
      return (
        /** @type {any[]} */
        this.w.config.series.reduce(
          (acc, cur) => acc + cur,
          0
        )
      );
    } else {
      return this.w.seriesData.series[index].reduce(
        (acc, cur) => acc + cur,
        0
      );
    }
  }
  /**
   * @memberof CoreUtils
   * returns the sum of values in a multiple stacked grouped charts
   * Eg. w.seriesData.series = [[32,33,43,12], [2,3,5,1], [43, 23, 34, 22]]
   * series 1 and 2 are in a group, while series 3 is in another group
   *  @return [[34, 36, 48, 12], [43, 23, 34, 22]]
   **/
  getStackedSeriesTotalsByGroups() {
    const w = this.w;
    const total = [];
    w.labelData.seriesGroups.forEach((sg) => {
      const includedIndexes = [];
      w.config.series.forEach((s, si) => {
        if (sg.indexOf(w.seriesData.seriesNames[si]) > -1) {
          includedIndexes.push(si);
        }
      });
      const excludedIndices = w.seriesData.series.map((_, fi) => includedIndexes.indexOf(fi) === -1 ? fi : -1).filter((f) => f !== -1);
      total.push(this.getStackedSeriesTotals(excludedIndices));
    });
    return total;
  }
  setSeriesYAxisMappings() {
    const gl = this.w.globals;
    const cnf = this.w.config;
    let axisSeriesMap = [];
    const seriesYAxisReverseMap = [];
    const unassignedSeriesIndices = [];
    const seriesNameArrayStyle = this.w.seriesData.series.length > cnf.yaxis.length || /**
     * @param {ApexYAxis} a
     */
    cnf.yaxis.some((a) => Array.isArray(a.seriesName));
    cnf.series.forEach((_s, i) => {
      unassignedSeriesIndices.push(i);
      seriesYAxisReverseMap.push(null);
    });
    cnf.yaxis.forEach(
      (_yaxe, yi) => {
        axisSeriesMap[yi] = [];
      }
    );
    const unassignedYAxisIndices = [];
    cnf.yaxis.forEach((yaxe, yi) => {
      let assigned = false;
      if (yaxe.seriesName) {
        let seriesNames = [];
        if (Array.isArray(yaxe.seriesName)) {
          seriesNames = yaxe.seriesName;
        } else {
          seriesNames.push(yaxe.seriesName);
        }
        seriesNames.forEach((name2) => {
          cnf.series.forEach((s, si) => {
            if (
              /** @type {any} */
              s.name === name2
            ) {
              let remove = si;
              if (yi === si || seriesNameArrayStyle) {
                if (!seriesNameArrayStyle || unassignedSeriesIndices.indexOf(si) > -1) {
                  axisSeriesMap[yi].push([yi, si]);
                } else {
                  console.warn(
                    "Series '" + /** @type {any} */
                    s.name + "' referenced more than once in what looks like the new style. That is, when using either seriesName: [], or when there are more series than yaxes."
                  );
                }
              } else {
                axisSeriesMap[si].push([si, yi]);
                remove = yi;
              }
              assigned = true;
              remove = unassignedSeriesIndices.indexOf(remove);
              if (remove !== -1) {
                unassignedSeriesIndices.splice(remove, 1);
              }
            }
          });
        });
      }
      if (!assigned) {
        unassignedYAxisIndices.push(yi);
      }
    });
    axisSeriesMap = axisSeriesMap.map((yaxe) => {
      const ra = [];
      yaxe.forEach((sa) => {
        seriesYAxisReverseMap[sa[1]] = sa[0];
        ra.push(sa[1]);
      });
      return ra;
    });
    let lastUnassignedYAxis = cnf.yaxis.length - 1;
    for (let i = 0; i < unassignedYAxisIndices.length; i++) {
      lastUnassignedYAxis = unassignedYAxisIndices[i];
      axisSeriesMap[lastUnassignedYAxis] = [];
      if (unassignedSeriesIndices) {
        const si = unassignedSeriesIndices[0];
        unassignedSeriesIndices.shift();
        axisSeriesMap[lastUnassignedYAxis].push(si);
        seriesYAxisReverseMap[si] = lastUnassignedYAxis;
      } else {
        break;
      }
    }
    unassignedSeriesIndices.forEach((i) => {
      axisSeriesMap[lastUnassignedYAxis].push(i);
      seriesYAxisReverseMap[i] = lastUnassignedYAxis;
    });
    gl.seriesYAxisMap = axisSeriesMap.map((x) => x);
    gl.seriesYAxisReverseMap = seriesYAxisReverseMap.map((x) => x);
    gl.seriesYAxisMap.forEach((axisSeries, ai) => {
      axisSeries.forEach((si) => {
        if (
          /** @type {any} */
          cnf.series[si] && /** @type {any} */
          cnf.series[si].group === void 0
        ) {
          const _series = (
            /** @type {any} */
            cnf.series[si]
          );
          _series.group = "apexcharts-axis-".concat(ai.toString());
        }
      });
    });
  }
  /**
   * @param {number | null} [index]
   */
  isSeriesNull(index = null) {
    let r = [];
    if (index === null) {
      r = /** @type {any[]} */
      this.w.config.series.filter(
        (d) => d !== null
      );
    } else {
      r = /** @type {Record<string,any>} */
      this.w.config.series[index].data.filter((d) => d !== null);
    }
    return r.length === 0;
  }
  /**
   * @param {number} index
   */
  seriesHaveSameValues(index) {
    return this.w.seriesData.series[index].every(
      (val, i, arr) => val === arr[0]
    );
  }
  /**
   * @param {any[]} labels
   */
  getCategoryLabels(labels) {
    const w = this.w;
    let catLabels = labels.slice();
    if (w.config.xaxis.convertedCatToNumeric) {
      catLabels = labels.map((i) => {
        return w.config.xaxis.labels.formatter(i - w.globals.minX + 1);
      });
    }
    return catLabels;
  }
  // maxValsInArrayIndex is the index of series[] which has the largest number of items
  getLargestSeries() {
    const w = this.w;
    w.globals.maxValsInArrayIndex = w.seriesData.series.map((a) => a.length).indexOf(
      Math.max.apply(
        Math,
        /**
         * @param {number[]} a
         */
        w.seriesData.series.map((a) => a.length)
      )
    );
  }
  getLargestMarkerSize() {
    const w = this.w;
    let size = 0;
    w.globals.markers.size.forEach((m) => {
      size = Math.max(size, m);
    });
    if (w.config.markers.discrete && w.config.markers.discrete.length) {
      w.config.markers.discrete.forEach((m) => {
        size = Math.max(size, m.size);
      });
    }
    if (size > 0) {
      if (w.config.markers.hover.size > 0) {
        size = w.config.markers.hover.size;
      } else {
        size += w.config.markers.hover.sizeOffset;
      }
    }
    w.globals.markers.largestSize = size;
    return size;
  }
  /**
   * @memberof Core
   * returns the sum of all values in a series
   * Eg. w.seriesData.series = [[32,33,43,12], [2,3,5,1]]
   *  @return [120, 11]
   **/
  getSeriesTotals() {
    const w = this.w;
    w.globals.seriesTotals = w.seriesData.series.map((ser) => {
      let total = 0;
      if (Array.isArray(ser)) {
        for (let j = 0; j < ser.length; j++) {
          total += ser[j];
        }
      } else {
        total += ser;
      }
      return total;
    });
  }
  /**
   * @param {number} minX
   * @param {number} maxX
   */
  getSeriesTotalsXRange(minX, maxX) {
    const w = this.w;
    const seriesTotalsXRange = w.seriesData.series.map((ser, index) => {
      let total = 0;
      for (let j = 0; j < ser.length; j++) {
        if (w.seriesData.seriesX[index][j] > minX && w.seriesData.seriesX[index][j] < maxX) {
          total += ser[j];
        }
      }
      return total;
    });
    return seriesTotalsXRange;
  }
  /**
   * @memberof CoreUtils
   * returns the percentage value of all individual values which can be used in a 100% stacked series
   * Eg. w.seriesData.series = [[32, 33, 43, 12], [2, 3, 5, 1]]
   *  @return [[94.11, 91.66, 89.58, 92.30], [5.88, 8.33, 10.41, 7.7]]
   **/
  getPercentSeries() {
    const w = this.w;
    w.globals.seriesPercent = w.seriesData.series.map((ser) => {
      const seriesPercent = [];
      if (Array.isArray(ser)) {
        for (let j = 0; j < ser.length; j++) {
          const total = w.seriesData.stackedSeriesTotals[j];
          let percent = 0;
          if (total) {
            percent = 100 * ser[j] / total;
          }
          seriesPercent.push(percent);
        }
      } else {
        const total = w.globals.seriesTotals.reduce((acc, val) => acc + val, 0);
        const percent = 100 * ser / total;
        seriesPercent.push(percent);
      }
      return seriesPercent;
    });
  }
  getCalculatedRatios() {
    const w = this.w;
    const gl = w.globals;
    const yRatio = [];
    let invertedYRatio = 0;
    let xRatio = 0;
    let invertedXRatio = 0;
    let zRatio = 0;
    let baseLineY = [];
    let baseLineInvertedY = 0.1;
    let baseLineX = 0;
    gl.yRange = [];
    if (gl.isMultipleYAxis) {
      for (let i = 0; i < gl.minYArr.length; i++) {
        gl.yRange.push(Math.abs(gl.minYArr[i] - gl.maxYArr[i]));
        baseLineY.push(0);
      }
    } else {
      gl.yRange.push(Math.abs(gl.minY - gl.maxY));
    }
    gl.xRange = Math.abs(gl.maxX - gl.minX);
    gl.zRange = Math.abs(gl.maxZ - gl.minZ);
    for (let i = 0; i < gl.yRange.length; i++) {
      yRatio.push(gl.yRange[i] / this.w.layout.gridHeight);
    }
    xRatio = gl.xRange / this.w.layout.gridWidth;
    invertedYRatio = /** @type {any} */
    gl.yRange / this.w.layout.gridWidth;
    invertedXRatio = gl.xRange / this.w.layout.gridHeight;
    zRatio = gl.zRange / this.w.layout.gridHeight * 16;
    if (!zRatio) {
      zRatio = 1;
    }
    if (gl.minY !== Number.MIN_VALUE && Math.abs(gl.minY) !== 0) {
      const _hasNegsGl = (
        /** @type {any} */
        gl
      );
      _hasNegsGl.hasNegs = true;
    }
    if (w.globals.seriesYAxisReverseMap.length > 0) {
      const scaleBaseLineYScale = (y, i) => {
        const yAxis = w.config.yaxis[w.globals.seriesYAxisReverseMap[i]];
        const sign = y < 0 ? -1 : 1;
        y = Math.abs(y);
        if (yAxis.logarithmic) {
          y = this.getBaseLog(yAxis.logBase, y);
        }
        return -sign * y / yRatio[i];
      };
      if (gl.isMultipleYAxis) {
        baseLineY = [];
        for (let i = 0; i < yRatio.length; i++) {
          baseLineY.push(scaleBaseLineYScale(gl.minYArr[i], i));
        }
      } else {
        baseLineY = [];
        baseLineY.push(scaleBaseLineYScale(gl.minY, 0));
        if (gl.minY !== Number.MIN_VALUE && Math.abs(gl.minY) !== 0) {
          baseLineInvertedY = -gl.minY / invertedYRatio;
          baseLineX = gl.minX / xRatio;
        }
      }
    } else {
      baseLineY = [];
      baseLineY.push(0);
      baseLineInvertedY = 0;
      baseLineX = 0;
    }
    return {
      yRatio,
      invertedYRatio,
      zRatio,
      xRatio,
      invertedXRatio,
      baseLineInvertedY,
      baseLineY,
      baseLineX
    };
  }
  /**
   * @param {any[]} series
   */
  getLogSeries(series) {
    const w = this.w;
    w.globals.seriesLog = series.map((s, i) => {
      const yAxisIndex = w.globals.seriesYAxisReverseMap[i];
      if (w.config.yaxis[yAxisIndex] && w.config.yaxis[yAxisIndex].logarithmic) {
        return s.map((d) => {
          if (d === null) return null;
          return this.getLogVal(w.config.yaxis[yAxisIndex].logBase, d, i);
        });
      } else {
        return s;
      }
    });
    return w.globals.invalidLogScale ? series : w.globals.seriesLog;
  }
  /**
   * @param {number} val
   * @param {number} seriesIndex
   * @returns {number}
   */
  getLogValAtSeriesIndex(val, seriesIndex) {
    if (val === null) return (
      /** @type {any} */
      null
    );
    const w = this.w;
    const yAxisIndex = w.globals.seriesYAxisReverseMap[seriesIndex];
    if (w.config.yaxis[yAxisIndex] && w.config.yaxis[yAxisIndex].logarithmic) {
      return this.getLogVal(
        w.config.yaxis[yAxisIndex].logBase,
        val,
        seriesIndex
      );
    }
    return val;
  }
  /**
   * @param {number} base
   * @param {number} value
   */
  getBaseLog(base, value) {
    return Math.log(value) / Math.log(base);
  }
  /**
   * @param {number} b
   * @param {number} d
   * @param {number} seriesIndex
   */
  getLogVal(b, d, seriesIndex) {
    if (d <= 0) {
      return 0;
    }
    const w = this.w;
    const min_log_val = w.globals.minYArr[seriesIndex] === 0 ? -1 : this.getBaseLog(b, w.globals.minYArr[seriesIndex]);
    const max_log_val = w.globals.maxYArr[seriesIndex] === 0 ? 0 : this.getBaseLog(b, w.globals.maxYArr[seriesIndex]);
    const number_of_height_levels = max_log_val - min_log_val;
    if (d < 1) return d / number_of_height_levels;
    const log_height_value = this.getBaseLog(b, d) - min_log_val;
    return log_height_value / number_of_height_levels;
  }
  /**
   * @param {number[]} yRatio
   */
  getLogYRatios(yRatio) {
    const w = this.w;
    const gl = this.w.globals;
    const _gl = (
      /** @type {any} */
      gl
    );
    _gl.yLogRatio = yRatio.slice();
    _gl.logYRange = /** @type {any[]} */
    gl.yRange.map(
      (_, i) => {
        const yAxisIndex = w.globals.seriesYAxisReverseMap[i];
        if (w.config.yaxis[yAxisIndex] && this.w.config.yaxis[yAxisIndex].logarithmic) {
          let maxY = -Number.MAX_VALUE;
          let minY = Number.MIN_VALUE;
          let range = 1;
          gl.seriesLog.forEach(
            (s, si) => {
              s.forEach((v) => {
                if (w.config.yaxis[si] && w.config.yaxis[si].logarithmic) {
                  maxY = Math.max(v, maxY);
                  minY = Math.min(v, minY);
                }
              });
            }
          );
          range = Math.pow(gl.yRange[i], Math.abs(minY - maxY) / gl.yRange[i]);
          _gl.yLogRatio[i] = range / this.w.layout.gridHeight;
          return range;
        }
      }
    );
    return _gl.invalidLogScale ? yRatio.slice() : _gl.yLogRatio;
  }
  // Some config objects can be array - and we need to extend them correctly
  /**
   * @param {any} configInstance
   * @param {Record<string, any>} options
   * @param {import('../types/internal').ChartStateW} w
   */
  static extendArrayProps(configInstance, options2, w) {
    var _a, _b;
    if (options2 == null ? void 0 : options2.yaxis) {
      options2 = configInstance.extendYAxis(options2, w);
    }
    if (options2 == null ? void 0 : options2.annotations) {
      if (options2.annotations.yaxis) {
        options2 = configInstance.extendYAxisAnnotations(options2);
      }
      if ((_a = options2 == null ? void 0 : options2.annotations) == null ? void 0 : _a.xaxis) {
        options2 = configInstance.extendXAxisAnnotations(options2);
      }
      if ((_b = options2 == null ? void 0 : options2.annotations) == null ? void 0 : _b.points) {
        options2 = configInstance.extendPointAnnotations(options2);
      }
    }
    return options2;
  }
  // Series of the same group and type can be stacked together distinct from
  // other series of the same type on the same axis.
  /**
   * @param {Record<string, any>} typeSeries
   * @param {string[]} typeGroups
   * @param {string} type
   * @param {string} chartClass
   */
  drawSeriesByGroup(typeSeries, typeGroups, type, chartClass) {
    const w = this.w;
    const graph = [];
    if (typeSeries.series.length > 0) {
      typeGroups.forEach((gn) => {
        const gs = [];
        const gi = [];
        typeSeries.i.forEach((i, ii) => {
          if (
            /** @type {Record<string,any>} */
            w.config.series[i].group === gn
          ) {
            gs.push(typeSeries.series[ii]);
            gi.push(i);
          }
        });
        gs.length > 0 && graph.push(
          /** @type {any} */
          chartClass.draw(gs, type, gi)
        );
      });
    }
    return graph;
  }
}
class Animations {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} [ctx]
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
  }
  /**
   * @param {any} el
   * @param {Record<string, any>} from
   * @param {Record<string, any>} to
   * @param {object} speed
   */
  animateLine(el, from, to, speed) {
    el.attr(from).animate(speed).attr(to);
  }
  /*
   ** Animate radius of a circle element
   * @param {any} el
   * @param {number} speed
   * @param {string} easing
   * @param {Function} cb
   */
  /** @param {any} el @param {any} speed @param {any} easing @param {any} cb */
  animateMarker(el, speed, easing, cb) {
    el.attr({
      opacity: 0
    }).animate(speed).attr({
      opacity: 1
    }).after(() => {
      cb();
    });
  }
  /*
   ** Animate rect properties
   * @param {any} el
   * @param {any} from
   * @param {any} to
   * @param {number} speed
   * @param {Function} fn
   */
  /** @param {any} el @param {any} from @param {any} to @param {any} speed @param {any} fn */
  animateRect(el, from, to, speed, fn) {
    el.attr(from).animate(speed).attr(to).after(() => fn());
  }
  /**
   * @param {Record<string, any>} params
   */
  animatePathsGradually(params) {
    const { el, realIndex, j, fill, pathFrom, pathTo, speed, delay } = params;
    const me = this;
    const w = this.w;
    let delayFactor = 0;
    if (w.config.chart.animations.animateGradually.enabled) {
      delayFactor = w.config.chart.animations.animateGradually.delay;
    }
    if (w.config.chart.animations.dynamicAnimation.enabled && w.globals.dataChanged && w.config.chart.type !== "bar") {
      delayFactor = 0;
    }
    me.morphSVG(
      el,
      realIndex,
      j,
      w.config.chart.type === "line" && !w.globals.comboCharts ? "stroke" : fill,
      pathFrom,
      pathTo,
      speed,
      delay * delayFactor
    );
  }
  showDelayedElements() {
    this.w.globals.delayedElements.forEach((d) => {
      const ele = d.el;
      ele.classList.remove("apexcharts-element-hidden");
      ele.classList.add("apexcharts-hidden-element-shown");
    });
  }
  /**
   * @param {any} el
   */
  animationCompleted(el) {
    const w = this.w;
    if (w.globals.animationEnded) return;
    w.globals.animationEnded = true;
    this.showDelayedElements();
    if (typeof w.config.chart.events.animationEnd === "function") {
      w.config.chart.events.animationEnd(this.ctx, { el, w });
    }
  }
  // SVG.js animation for morphing one path to another
  /**
   * @param {any} el
   * @param {number} realIndex
   * @param {number} j
   * @param {string} fill
   * @param {string} pathFrom
   * @param {string} pathTo
   * @param {number} speed
   * @param {number} delay
   */
  morphSVG(el, realIndex, j, fill, pathFrom, pathTo, speed, delay) {
    const w = this.w;
    if (!pathFrom) {
      pathFrom = el.attr("pathFrom");
    }
    if (!pathTo) {
      pathTo = el.attr("pathTo");
    }
    const disableAnimationForCorrupPath = () => {
      if (w.config.chart.type === "radar") {
        speed = 1;
      }
      return `M 0 ${w.layout.gridHeight}`;
    };
    if (!pathFrom || pathFrom.indexOf("undefined") > -1 || pathFrom.indexOf("NaN") > -1) {
      pathFrom = disableAnimationForCorrupPath();
    }
    if (!pathTo.trim() || pathTo.indexOf("undefined") > -1 || pathTo.indexOf("NaN") > -1) {
      pathTo = disableAnimationForCorrupPath();
    }
    if (!w.globals.shouldAnimate) {
      speed = 1;
    }
    el.plot(pathFrom).animate(1, delay).plot(pathFrom).animate(speed, delay).plot(pathTo).after(() => {
      if (Utils$1.isNumber(j)) {
        if (j === w.seriesData.series[w.globals.maxValsInArrayIndex].length - 2 && w.globals.shouldAnimate) {
          this.animationCompleted(el);
        }
      } else if (fill !== "none" && w.globals.shouldAnimate) {
        if (!w.globals.comboCharts && realIndex === w.seriesData.series.length - 1 || w.globals.comboCharts) {
          this.animationCompleted(el);
        }
      }
      this.showDelayedElements();
    });
  }
}
class Filters {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
  }
  // create a re-usable filter which can be appended other filter effects and applied to multiple elements
  /**
   * @param {any} el
   * @param {number} i
   */
  getDefaultFilter(el, i) {
    const w = this.w;
    if (el.unfilter) {
      el.unfilter(true);
    }
    if (w.config.chart.dropShadow.enabled) {
      this.dropShadow(el, w.config.chart.dropShadow, i);
    }
  }
  /**
   * @param {any} el
   * @param {number} i
   * @param {string} filterType
   */
  applyFilter(el, i, filterType) {
    var _a, _b, _c;
    const w = this.w;
    if (el.unfilter) {
      el.unfilter(true);
    }
    if (filterType === "none") {
      this.getDefaultFilter(el, i);
      return;
    }
    const shadowAttr = w.config.chart.dropShadow;
    const brightnessFactor = filterType === "lighten" ? 2 : 0.3;
    if (el.filterWith) {
      el.filterWith((add) => {
        add.colorMatrix({
          type: "matrix",
          values: `
            ${brightnessFactor} 0 0 0 0
            0 ${brightnessFactor} 0 0 0
            0 0 ${brightnessFactor} 0 0
            0 0 0 1 0
          `,
          in: "SourceGraphic",
          result: "brightness"
        });
        if (shadowAttr.enabled) {
          this.addShadow(add, i, shadowAttr, "brightness");
        }
      });
      if (!shadowAttr.noUserSpaceOnUse) {
        (_b = (_a = el.filterer()) == null ? void 0 : _a.node) == null ? void 0 : _b.setAttribute("filterUnits", "userSpaceOnUse");
      }
      this._scaleFilterSize((_c = el.filterer()) == null ? void 0 : _c.node);
    }
  }
  // appends dropShadow to the filter object which can be chained with other filter effects
  /**
   * @param {any} add
   * @param {number} i
   * @param {Record<string, any>} attrs
   * @param {string} source
   */
  addShadow(add, i, attrs, source) {
    var _a;
    const w = this.w;
    let { blur, top, left, color, opacity } = attrs;
    color = Array.isArray(color) ? color[i] : color;
    if (((_a = w.config.chart.dropShadow.enabledOnSeries) == null ? void 0 : _a.length) > 0) {
      if (w.config.chart.dropShadow.enabledOnSeries.indexOf(i) === -1) {
        return add;
      }
    }
    add.offset({
      in: source,
      dx: left,
      dy: top,
      result: "offset"
    });
    add.gaussianBlur({
      in: "offset",
      stdDeviation: blur,
      result: "blur"
    });
    add.flood({
      "flood-color": color,
      "flood-opacity": opacity,
      result: "flood"
    });
    add.composite({
      in: "flood",
      in2: "blur",
      operator: "in",
      result: "shadow"
    });
    add.merge(["shadow", source]);
  }
  // directly adds dropShadow to the element and returns the same element.
  /**
   * @param {any} el
   * @param {Record<string, any>} attrs
   */
  dropShadow(el, attrs, i = 0) {
    var _a, _b, _c, _d, _e;
    const w = this.w;
    if (el.unfilter) {
      el.unfilter(true);
    }
    if (Utils$1.isMsEdge() && w.config.chart.type === "radialBar") {
      return el;
    }
    if (((_a = w.config.chart.dropShadow.enabledOnSeries) == null ? void 0 : _a.length) > 0) {
      if (((_b = w.config.chart.dropShadow.enabledOnSeries) == null ? void 0 : _b.indexOf(i)) === -1) {
        return el;
      }
    }
    if (el.filterWith) {
      el.filterWith((add) => {
        this.addShadow(add, i, attrs, "SourceGraphic");
      });
      if (!attrs.noUserSpaceOnUse) {
        (_d = (_c = el.filterer()) == null ? void 0 : _c.node) == null ? void 0 : _d.setAttribute("filterUnits", "userSpaceOnUse");
      }
      this._scaleFilterSize((_e = el.filterer()) == null ? void 0 : _e.node);
    }
    return el;
  }
  /**
   * @param {any} el
   * @param {number} realIndex
   * @param {number} dataPointIndex
   */
  setSelectionFilter(el, realIndex, dataPointIndex) {
    const w = this.w;
    if (typeof w.interact.selectedDataPoints[realIndex] !== "undefined") {
      if (w.interact.selectedDataPoints[realIndex].indexOf(dataPointIndex) > -1) {
        el.node.setAttribute("selected", true);
        const activeFilter = w.config.states.active.filter;
        if (activeFilter !== "none") {
          this.applyFilter(el, realIndex, activeFilter.type);
        }
      }
    }
  }
  /**
   * @param {any} el
   */
  _scaleFilterSize(el) {
    if (!el) return;
    const setAttributes = (attrs) => {
      for (const key in attrs) {
        if (Object.prototype.hasOwnProperty.call(attrs, key)) {
          el.setAttribute(key, attrs[key]);
        }
      }
    };
    setAttributes({
      width: "200%",
      height: "200%",
      x: "-50%",
      y: "-50%"
    });
  }
}
class Graphics {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext | null} ctx
   */
  constructor(w, ctx = null) {
    this.w = w;
    this.ctx = ctx;
  }
  /*****************************************************************************
   *                                                                            *
   *  SVG Path Rounding Function                                                *
   *  Copyright (C) 2014 Yona Appletree                                         *
   *                                                                            *
   *  Licensed under the Apache License, Version 2.0 (the "License");           *
   *  you may not use this file except in compliance with the License.          *
   *  You may obtain a copy of the License at                                   *
   *                                                                            *
   *      http://www.apache.org/licenses/LICENSE-2.0                            *
   *                                                                            *
   *  Unless required by applicable law or agreed to in writing, software       *
   *  distributed under the License is distributed on an "AS IS" BASIS,         *
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
   *  See the License for the specific language governing permissions and       *
   *  limitations under the License.                                            *
   *                                                                            *
   *****************************************************************************/
  /**
   * SVG Path rounding function. Takes an input path string and outputs a path
   * string where all line-line corners have been rounded. Only supports absolute
   * commands at the moment.
   *
   * @param pathString The SVG input path
   * @param radius The amount to round the corners, either a value in the SVG
   *               coordinate space, or, if useFractionalRadius is true, a value
   *               from 0 to 1.
   * @returns A new SVG path string with the rounding
   * @param {string} pathString
   * @param {number} radius
   */
  roundPathCorners(pathString, radius) {
    if (pathString.indexOf("NaN") > -1) pathString = "";
    function moveTowardsLength(movingPoint, targetPoint, amount) {
      var width = targetPoint.x - movingPoint.x;
      var height = targetPoint.y - movingPoint.y;
      var distance = Math.sqrt(width * width + height * height);
      return moveTowardsFractional(
        movingPoint,
        targetPoint,
        Math.min(1, amount / distance)
      );
    }
    function moveTowardsFractional(movingPoint, targetPoint, fraction) {
      return {
        x: movingPoint.x + (targetPoint.x - movingPoint.x) * fraction,
        y: movingPoint.y + (targetPoint.y - movingPoint.y) * fraction
      };
    }
    function adjustCommand(cmd, newPoint) {
      if (cmd.length > 2) {
        cmd[cmd.length - 2] = newPoint.x;
        cmd[cmd.length - 1] = newPoint.y;
      }
    }
    function pointForCommand(cmd) {
      return {
        x: parseFloat(cmd[cmd.length - 2]),
        y: parseFloat(cmd[cmd.length - 1])
      };
    }
    var pathParts = pathString.split(/[,\s]/).reduce(function(parts, part) {
      var match = part.match(/^([a-zA-Z])(.+)/);
      if (match) {
        parts.push(match[1]);
        parts.push(match[2]);
      } else {
        parts.push(part);
      }
      return parts;
    }, []);
    var commands = pathParts.reduce(function(commands2, part) {
      if (parseFloat(part) == part && commands2.length) {
        commands2[commands2.length - 1].push(part);
      } else {
        commands2.push([part]);
      }
      return commands2;
    }, []);
    var resultCommands = [];
    if (commands.length > 1) {
      var startPoint = pointForCommand(commands[0]);
      var virtualCloseLine = null;
      if (commands[commands.length - 1][0] == "Z" && commands[0].length > 2) {
        virtualCloseLine = ["L", startPoint.x, startPoint.y];
        commands[commands.length - 1] = virtualCloseLine;
      }
      resultCommands.push(commands[0]);
      for (var cmdIndex = 1; cmdIndex < commands.length; cmdIndex++) {
        var prevCmd = resultCommands[resultCommands.length - 1];
        var curCmd = commands[cmdIndex];
        var nextCmd = curCmd == virtualCloseLine ? commands[1] : commands[cmdIndex + 1];
        if (nextCmd && prevCmd && prevCmd.length > 2 && curCmd[0] == "L" && nextCmd.length > 2 && nextCmd[0] == "L") {
          var prevPoint = pointForCommand(prevCmd);
          var curPoint = pointForCommand(curCmd);
          var nextPoint = pointForCommand(nextCmd);
          var curveStart, curveEnd;
          curveStart = moveTowardsLength(curPoint, prevPoint, radius);
          curveEnd = moveTowardsLength(curPoint, nextPoint, radius);
          adjustCommand(curCmd, curveStart);
          curCmd.origPoint = curPoint;
          resultCommands.push(curCmd);
          var startControl = moveTowardsFractional(curveStart, curPoint, 0.5);
          var endControl = moveTowardsFractional(curPoint, curveEnd, 0.5);
          var curveCmd = [
            "C",
            startControl.x,
            startControl.y,
            endControl.x,
            endControl.y,
            curveEnd.x,
            curveEnd.y
          ];
          curveCmd.origPoint = curPoint;
          resultCommands.push(curveCmd);
        } else {
          resultCommands.push(curCmd);
        }
      }
      if (virtualCloseLine) {
        var newStartPoint = pointForCommand(
          resultCommands[resultCommands.length - 1]
        );
        resultCommands.push(["Z"]);
        adjustCommand(resultCommands[0], newStartPoint);
      }
    } else {
      resultCommands = commands;
    }
    return resultCommands.reduce(function(str, c) {
      return str + c.join(" ") + " ";
    }, "");
  }
  /**
   * @param {number} x1
   * @param {number} y1
   * @param {number} x2
   * @param {number} y2
   * @param {number | null} [strokeWidth]
   */
  drawLine(x1, y1, x2, y2, lineColor = "#a8a8a8", dashArray = 0, strokeWidth = null, strokeLineCap = "butt") {
    const w = this.w;
    const line = w.dom.Paper.line().attr({
      x1,
      y1,
      x2,
      y2,
      stroke: lineColor,
      "stroke-dasharray": dashArray,
      "stroke-width": strokeWidth,
      "stroke-linecap": strokeLineCap
    });
    return line;
  }
  /**
   * @param {number | null} [strokeWidth]
   * @param {string | null} [strokeColor]
   */
  drawRect(x1 = 0, y1 = 0, x2 = 0, y2 = 0, radius = 0, color = "#fefefe", opacity = 1, strokeWidth = null, strokeColor = null, strokeDashArray = 0) {
    const w = this.w;
    const rect = w.dom.Paper.rect();
    rect.attr({
      x: x1,
      y: y1,
      width: x2 > 0 ? x2 : 0,
      height: y2 > 0 ? y2 : 0,
      rx: radius,
      ry: radius,
      opacity,
      "stroke-width": strokeWidth !== null ? strokeWidth : 0,
      stroke: strokeColor !== null ? strokeColor : "none",
      "stroke-dasharray": strokeDashArray
    });
    rect.node.setAttribute("fill", color);
    return rect;
  }
  /**
   * @param {string} polygonString
   */
  drawPolygon(polygonString, stroke = "#e1e1e1", strokeWidth = 1, fill = "none") {
    const w = this.w;
    const polygon = w.dom.Paper.polygon(polygonString).attr({
      fill,
      stroke,
      "stroke-width": strokeWidth
    });
    return polygon;
  }
  /**
   * @param {number} radius
   * @param {Record<string, any> | null} attrs
   */
  drawCircle(radius, attrs = null) {
    const w = this.w;
    if (radius < 0) radius = 0;
    const c = w.dom.Paper.circle(radius * 2);
    if (attrs !== null) {
      c.attr(attrs);
    }
    return c;
  }
  /** @param {{ d?: string, stroke?: string, strokeWidth?: number, fill: any, fillOpacity?: number, strokeOpacity?: number, classes?: any, strokeLinecap?: any, strokeDashArray?: number }} opts */
  drawPath({
    d = "",
    stroke = "#a8a8a8",
    strokeWidth = 1,
    fill,
    fillOpacity = 1,
    strokeOpacity = 1,
    classes,
    strokeLinecap = null,
    strokeDashArray = 0
  }) {
    const w = this.w;
    if (strokeLinecap === null) {
      strokeLinecap = w.config.stroke.lineCap;
    }
    if (d.indexOf("undefined") > -1 || d.indexOf("NaN") > -1) {
      d = `M 0 ${w.layout.gridHeight}`;
    }
    const p = w.dom.Paper.path(d).attr({
      fill,
      "fill-opacity": fillOpacity,
      stroke,
      "stroke-opacity": strokeOpacity,
      "stroke-linecap": strokeLinecap,
      "stroke-width": strokeWidth,
      "stroke-dasharray": strokeDashArray,
      class: classes
    });
    return p;
  }
  /**
   * @param {Record<string, any> | null} attrs
   */
  group(attrs = null) {
    const w = this.w;
    const g = w.dom.Paper.group();
    if (attrs !== null) {
      g.attr(attrs);
    }
    return g;
  }
  /**
   * @param {number} x
   * @param {number} y
   */
  move(x, y) {
    const move = ["M", x, y].join(" ");
    return move;
  }
  /**
   * @param {number | null} x
   * @param {number | null} y
   * @param {string | null} hORv
   * @returns {string}
   */
  line(x, y, hORv = null) {
    if (hORv === "H") return [" H", x].join(" ");
    if (hORv === "V") return [" V", y].join(" ");
    return [" L", x, y].join(" ");
  }
  /**
   * @param {number} x1
   * @param {number} y1
   * @param {number} x2
   * @param {number} y2
   * @param {number} x
   * @param {number} y
   */
  curve(x1, y1, x2, y2, x, y) {
    const curve = ["C", x1, y1, x2, y2, x, y].join(" ");
    return curve;
  }
  /**
   * @param {number} x1
   * @param {number} y1
   * @param {number} x
   * @param {number} y
   */
  quadraticCurve(x1, y1, x, y) {
    const curve = ["Q", x1, y1, x, y].join(" ");
    return curve;
  }
  /**
   * @param {number} rx
   * @param {number} ry
   * @param {number} axisRotation
   * @param {number} largeArcFlag
   * @param {number} sweepFlag
   * @param {number} x
   * @param {number} y
   */
  arc(rx, ry, axisRotation, largeArcFlag, sweepFlag, x, y, relative = false) {
    let coord = "A";
    if (relative) coord = "a";
    const arc = [
      coord,
      rx,
      ry,
      axisRotation,
      largeArcFlag,
      sweepFlag,
      x,
      y
    ].join(" ");
    return arc;
  }
  /**
   * @memberof Graphics
   * @param {Record<string, any>} opts
   *  i = series's index
   *  realIndex = realIndex is series's actual index when it was drawn time. After several redraws, the iterating "i" may change in loops, but realIndex doesn't
   *  pathFrom = existing pathFrom to animateTo
   *  pathTo = new Path to which d attr will be animated from pathFrom to pathTo
   *  stroke = line Color
   *  strokeWidth = width of path Line
   *  fill = it can be gradient, single color, pattern or image
   *  animationDelay = how much to delay when starting animation (in milliseconds)
   *  dataChangeSpeed = for dynamic animations, when data changes
   *  className = class attribute to add
   * @return {any} svg.js path object
   **/
  renderPaths({
    j,
    realIndex,
    pathFrom,
    pathTo,
    stroke,
    strokeWidth,
    strokeLinecap,
    fill,
    animationDelay,
    initialSpeed,
    dataChangeSpeed,
    className,
    chartType,
    shouldClipToGrid = true,
    bindEventsOnPaths = true,
    drawShadow = true
  }) {
    const w = this.w;
    const filters = new Filters(this.w);
    const anim = new Animations(
      this.w,
      /** @type {any} */
      void 0
    );
    const initialAnim = this.w.config.chart.animations.enabled;
    const dynamicAnim = initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled;
    if (pathFrom && pathFrom.startsWith("M 0 0") && pathTo) {
      const moveCommand = pathTo.match(/^M\s+[\d.-]+\s+[\d.-]+/);
      if (moveCommand) {
        pathFrom = pathFrom.replace(/^M\s+0\s+0/, moveCommand[0]);
      }
    }
    let d;
    const shouldAnimate = !!(initialAnim && !w.globals.resized || dynamicAnim && w.globals.dataChanged && w.globals.shouldAnimate);
    if (shouldAnimate) {
      d = pathFrom;
    } else {
      d = pathTo;
      w.globals.animationEnded = true;
    }
    const strokeDashArrayOpt = w.config.stroke.dashArray;
    let strokeDashArray = 0;
    if (Array.isArray(strokeDashArrayOpt)) {
      strokeDashArray = strokeDashArrayOpt[realIndex];
    } else {
      strokeDashArray = w.config.stroke.dashArray;
    }
    const el = this.drawPath({
      d,
      stroke,
      strokeWidth,
      fill,
      fillOpacity: 1,
      classes: className,
      strokeLinecap,
      strokeDashArray
    });
    el.attr("index", realIndex);
    if (shouldClipToGrid) {
      if (chartType === "bar" && !w.globals.isBarHorizontal || w.globals.comboCharts) {
        el.attr({
          "clip-path": `url(#gridRectBarMask${w.globals.cuid})`
        });
      } else {
        el.attr({
          "clip-path": `url(#gridRectMask${w.globals.cuid})`
        });
      }
    }
    if (w.config.chart.dropShadow.enabled && drawShadow) {
      filters.dropShadow(el, w.config.chart.dropShadow, realIndex);
    }
    if (bindEventsOnPaths) {
      el.node.addEventListener("mouseenter", this.pathMouseEnter.bind(this, el));
      el.node.addEventListener("mouseleave", this.pathMouseLeave.bind(this, el));
      el.node.addEventListener("mousedown", this.pathMouseDown.bind(this, el));
    }
    el.attr({
      pathTo,
      pathFrom
    });
    const defaultAnimateOpts = {
      el,
      j,
      realIndex,
      pathFrom,
      pathTo,
      fill,
      strokeWidth,
      delay: animationDelay
    };
    if (initialAnim && !w.globals.resized && !w.globals.dataChanged) {
      anim.animatePathsGradually(__spreadProps(__spreadValues({}, defaultAnimateOpts), {
        speed: initialSpeed
      }));
    } else {
      if (w.globals.resized || !w.globals.dataChanged) {
        anim.showDelayedElements();
      }
    }
    if (w.globals.dataChanged && dynamicAnim && shouldAnimate) {
      anim.animatePathsGradually(__spreadProps(__spreadValues({}, defaultAnimateOpts), {
        speed: dataChangeSpeed
      }));
    }
    return el;
  }
  /**
   * @param {string} style
   * @param {number} width
   * @param {number} height
   */
  drawPattern(style, width, height, stroke = "#a8a8a8", strokeWidth = 0) {
    const w = this.w;
    const p = w.dom.Paper.pattern(width, height, (add) => {
      if (style === "horizontalLines") {
        add.line(0, 0, height, 0).stroke({ color: stroke, width: strokeWidth + 1 });
      } else if (style === "verticalLines") {
        add.line(0, 0, 0, width).stroke({ color: stroke, width: strokeWidth + 1 });
      } else if (style === "slantedLines") {
        add.line(0, 0, width, height).stroke({ color: stroke, width: strokeWidth });
      } else if (style === "squares") {
        add.rect(width, height).fill("none").stroke({ color: stroke, width: strokeWidth });
      } else if (style === "circles") {
        add.circle(width).fill("none").stroke({ color: stroke, width: strokeWidth });
      }
    });
    return p;
  }
  /**
   * @param {string} style
   * @param {string} gfrom
   * @param {string} gto
   * @param {number} opacityFrom
   * @param {number} opacityTo
   * @param {number | null} [size]
   * @param {number[] | null} stops
   * @param {any[]} colorStops
   */
  drawGradient(style, gfrom, gto, opacityFrom, opacityTo, size = null, stops = null, colorStops = [], i = 0) {
    const w = this.w;
    let g;
    if (gfrom.length < 9 && gfrom.indexOf("#") === 0) {
      gfrom = Utils$1.hexToRgba(gfrom, opacityFrom);
    }
    if (gto.length < 9 && gto.indexOf("#") === 0) {
      gto = Utils$1.hexToRgba(gto, opacityTo);
    }
    let stop1 = 0;
    let stop2 = 1;
    let stop3 = 1;
    let stop4 = null;
    if (stops !== null) {
      stop1 = typeof stops[0] !== "undefined" ? stops[0] / 100 : 0;
      stop2 = typeof stops[1] !== "undefined" ? stops[1] / 100 : 1;
      stop3 = typeof stops[2] !== "undefined" ? stops[2] / 100 : 1;
      stop4 = typeof stops[3] !== "undefined" ? stops[3] / 100 : null;
    }
    const radial = !!(w.config.chart.type === "donut" || w.config.chart.type === "pie" || w.config.chart.type === "polarArea" || w.config.chart.type === "bubble");
    if (!colorStops || colorStops.length === 0) {
      g = w.dom.Paper.gradient(
        radial ? "radial" : "linear",
        (add) => {
          add.stop(stop1, gfrom, opacityFrom);
          add.stop(stop2, gto, opacityTo);
          add.stop(stop3, gto, opacityTo);
          if (stop4 !== null) {
            add.stop(stop4, gfrom, opacityFrom);
          }
        }
      );
    } else {
      g = w.dom.Paper.gradient(
        radial ? "radial" : "linear",
        (add) => {
          const gradientStops = Array.isArray(colorStops[i]) ? colorStops[i] : colorStops;
          gradientStops.forEach((s) => {
            add.stop(s.offset / 100, s.color, s.opacity);
          });
        }
      );
    }
    if (!radial) {
      if (style === "vertical") {
        g.from(0, 0).to(0, 1);
      } else if (style === "diagonal") {
        g.from(0, 0).to(1, 1);
      } else if (style === "horizontal") {
        g.from(0, 1).to(1, 1);
      } else if (style === "diagonal2") {
        g.from(1, 0).to(0, 1);
      }
    } else {
      const offx = w.layout.gridWidth / 2;
      const offy = w.layout.gridHeight / 2;
      if (w.config.chart.type !== "bubble") {
        g.attr({
          gradientUnits: "userSpaceOnUse",
          cx: offx,
          cy: offy,
          r: size
        });
      } else {
        g.attr({
          cx: 0.5,
          cy: 0.5,
          r: 0.8,
          fx: 0.2,
          fy: 0.2
        });
      }
    }
    return g;
  }
  /** @param {{ text: any, maxWidth: any, fontSize: any, fontFamily?: any }} opts */
  getTextBasedOnMaxWidth({ text, maxWidth, fontSize, fontFamily }) {
    const tRects = this.getTextRects(text, fontSize, fontFamily, "");
    const wordWidth = tRects.width / text.length;
    const wordsBasedOnWidth = Math.floor(maxWidth / wordWidth);
    if (maxWidth < tRects.width) {
      return text.slice(0, wordsBasedOnWidth - 3) + "...";
    }
    return text;
  }
  /**
   * @param {{ x: any, y: any, text: any, textAnchor?: any, fontSize?: any, fontFamily?: any, fontWeight?: any, foreColor?: any, opacity?: any, maxWidth?: any, cssClass?: string, isPlainText?: boolean, dominantBaseline?: string }} opts
   */
  drawText({
    x,
    y,
    text,
    textAnchor,
    fontSize,
    fontFamily,
    fontWeight,
    foreColor,
    opacity,
    maxWidth,
    cssClass = "",
    isPlainText = true,
    dominantBaseline = "auto"
  }) {
    const w = this.w;
    if (typeof text === "undefined") text = "";
    let truncatedText = text;
    if (!textAnchor) {
      textAnchor = "start";
    }
    if (!foreColor || !foreColor.length) {
      foreColor = w.config.chart.foreColor;
    }
    fontFamily = fontFamily || w.config.chart.fontFamily;
    fontSize = fontSize || "11px";
    fontWeight = fontWeight || "regular";
    const commonProps = {
      maxWidth,
      fontSize,
      fontFamily
    };
    let elText;
    if (Array.isArray(text)) {
      elText = w.dom.Paper.text((add) => {
        for (let i = 0; i < text.length; i++) {
          truncatedText = text[i];
          if (maxWidth) {
            truncatedText = this.getTextBasedOnMaxWidth(__spreadValues({
              text: text[i]
            }, commonProps));
          }
          i === 0 ? add.tspan(truncatedText) : add.tspan(truncatedText).newLine();
        }
      });
    } else {
      if (maxWidth) {
        truncatedText = this.getTextBasedOnMaxWidth(__spreadValues({
          text
        }, commonProps));
      }
      elText = isPlainText ? w.dom.Paper.plain(text) : (
        /**
         * @param {any} add
         */
        w.dom.Paper.text((add) => add.tspan(truncatedText))
      );
    }
    elText.attr({
      x,
      y,
      "text-anchor": textAnchor,
      "dominant-baseline": dominantBaseline,
      "font-size": fontSize,
      "font-family": fontFamily,
      "font-weight": fontWeight,
      fill: foreColor,
      class: "apexcharts-text " + cssClass
    });
    elText.node.style.fontFamily = fontFamily;
    elText.node.style.opacity = opacity;
    return elText;
  }
  /**
   * @param {number} x
   * @param {number} y
   * @param {string} type
   * @param {number} size
   */
  getMarkerPath(x, y, type, size) {
    let d = "";
    switch (type) {
      case "cross":
        size = size / 1.4;
        d = `M ${x - size} ${y - size} L ${x + size} ${y + size}  M ${x - size} ${y + size} L ${x + size} ${y - size}`;
        break;
      case "plus":
        size = size / 1.12;
        d = `M ${x - size} ${y} L ${x + size} ${y}  M ${x} ${y - size} L ${x} ${y + size}`;
        break;
      case "star":
      case "sparkle": {
        let points = 5;
        size = size * 1.15;
        if (type === "sparkle") {
          size = size / 1.1;
          points = 4;
        }
        const step = Math.PI / points;
        for (let i = 0; i <= 2 * points; i++) {
          const angle = i * step;
          const radius = i % 2 === 0 ? size : size / 2;
          const xPos = x + radius * Math.sin(angle);
          const yPos = y - radius * Math.cos(angle);
          d += (i === 0 ? "M" : "L") + xPos + "," + yPos;
        }
        d += "Z";
        break;
      }
      case "triangle":
        d = `M ${x} ${y - size} 
             L ${x + size} ${y + size} 
             L ${x - size} ${y + size} 
             Z`;
        break;
      case "square":
      case "rect":
        size = size / 1.125;
        d = `M ${x - size} ${y - size} 
           L ${x + size} ${y - size} 
           L ${x + size} ${y + size} 
           L ${x - size} ${y + size} 
           Z`;
        break;
      case "diamond":
        size = size * 1.05;
        d = `M ${x} ${y - size} 
             L ${x + size} ${y} 
             L ${x} ${y + size} 
             L ${x - size} ${y} 
            Z`;
        break;
      case "line":
        size = size / 1.1;
        d = `M ${x - size} ${y} 
           L ${x + size} ${y}`;
        break;
      case "circle":
      default:
        size = size * 2;
        d = `M ${x}, ${y} 
           m -${size / 2}, 0 
           a ${size / 2},${size / 2} 0 1,0 ${size},0 
           a ${size / 2},${size / 2} 0 1,0 -${size},0`;
        break;
    }
    return d;
  }
  /**
   * @param {number} x - The x-coordinate of the marker
   * @param {number} y - The y-coordinate of the marker
   * @param {string} type - Marker shape type
   * @param {number} size - The size of the marker
   * @param {Record<string, any>} opts - The options for the marker
   * @returns {any} The created marker.
   */
  drawMarkerShape(x, y, type, size, opts) {
    const path = this.drawPath({
      d: this.getMarkerPath(x, y, type, size),
      stroke: opts.pointStrokeColor,
      strokeDashArray: opts.pointStrokeDashArray,
      strokeWidth: opts.pointStrokeWidth,
      fill: opts.pointFillColor,
      fillOpacity: opts.pointFillOpacity,
      strokeOpacity: opts.pointStrokeOpacity
    });
    path.attr({
      cx: x,
      cy: y,
      shape: opts.shape,
      class: opts.class ? opts.class : ""
    });
    return path;
  }
  /**
   * @param {number} x
   * @param {number} y
   * @param {Record<string, any>} opts
   */
  drawMarker(x, y, opts) {
    x = x || 0;
    let size = opts.pSize || 0;
    if (!Utils$1.isNumber(y)) {
      size = 0;
      y = 0;
    }
    return this.drawMarkerShape(x, y, opts == null ? void 0 : opts.shape, size, __spreadValues(__spreadValues({}, opts), opts.shape === "line" || opts.shape === "plus" || opts.shape === "cross" ? {
      pointStrokeColor: opts.pointFillColor,
      pointStrokeOpacity: opts.pointFillOpacity
    } : {}));
  }
  /**
   * @param {any} path
   * @param {Event | null} [e]
   */
  pathMouseEnter(path, e) {
    var _a, _b;
    const w = this.w;
    const filters = new Filters(this.w);
    const i = parseInt((_a = path.node.getAttribute("index")) != null ? _a : "", 10);
    const j = parseInt((_b = path.node.getAttribute("j")) != null ? _b : "", 10);
    if (isNaN(i) || isNaN(j)) return;
    if (typeof w.config.chart.events.dataPointMouseEnter === "function") {
      w.config.chart.events.dataPointMouseEnter(e, this.ctx, {
        seriesIndex: i,
        dataPointIndex: j,
        w
      });
    }
    Graphics._fireEvent(w, "dataPointMouseEnter", [
      e,
      this.ctx,
      { seriesIndex: i, dataPointIndex: j, w }
    ]);
    if (w.config.states.active.filter.type !== "none") {
      if (path.node.getAttribute("selected") === "true") {
        return;
      }
    }
    if (w.config.states.hover.filter.type !== "none") {
      if (!w.interact.isTouchDevice) {
        const hoverFilter = w.config.states.hover.filter;
        filters.applyFilter(path, i, hoverFilter.type);
      }
    }
  }
  /**
   * @param {any} path
   * @param {Event | null} [e]
   */
  pathMouseLeave(path, e) {
    var _a, _b;
    const w = this.w;
    const filters = new Filters(this.w);
    const i = parseInt((_a = path.node.getAttribute("index")) != null ? _a : "", 10);
    const j = parseInt((_b = path.node.getAttribute("j")) != null ? _b : "", 10);
    if (isNaN(i) || isNaN(j)) return;
    if (typeof w.config.chart.events.dataPointMouseLeave === "function") {
      w.config.chart.events.dataPointMouseLeave(e, this.ctx, {
        seriesIndex: i,
        dataPointIndex: j,
        w
      });
    }
    Graphics._fireEvent(w, "dataPointMouseLeave", [
      e,
      this.ctx,
      { seriesIndex: i, dataPointIndex: j, w }
    ]);
    if (w.config.states.active.filter.type !== "none") {
      if (path.node.getAttribute("selected") === "true") {
        return;
      }
    }
    if (w.config.states.hover.filter.type !== "none") {
      filters.getDefaultFilter(path, i);
    }
  }
  /**
   * @param {any} path
   * @param {Event | null} e
   */
  pathMouseDown(path, e) {
    var _a, _b;
    const w = this.w;
    const filters = new Filters(this.w);
    const i = parseInt((_a = path.node.getAttribute("index")) != null ? _a : "", 10);
    const j = parseInt((_b = path.node.getAttribute("j")) != null ? _b : "", 10);
    if (isNaN(i) || isNaN(j)) return;
    let selected = "false";
    if (path.node.getAttribute("selected") === "true") {
      path.node.setAttribute("selected", "false");
      const index = w.interact.selectedDataPoints[i].indexOf(j);
      if (index > -1) {
        w.interact.selectedDataPoints[i].splice(index, 1);
      }
    } else {
      if (!w.config.states.active.allowMultipleDataPointsSelection && w.interact.selectedDataPoints.length > 0) {
        w.interact.selectedDataPoints = [];
        const elPaths = w.dom.Paper.find(
          ".apexcharts-series path:not(.apexcharts-decoration-element)"
        );
        const elCircles = w.dom.Paper.find(
          ".apexcharts-series circle:not(.apexcharts-decoration-element), .apexcharts-series rect:not(.apexcharts-decoration-element)"
        );
        const deSelect = (els) => {
          Array.prototype.forEach.call(els, (el) => {
            el.node.setAttribute("selected", "false");
            filters.getDefaultFilter(el, i);
          });
        };
        deSelect(elPaths);
        deSelect(elCircles);
      }
      path.node.setAttribute("selected", "true");
      selected = "true";
      if (typeof w.interact.selectedDataPoints[i] === "undefined") {
        w.interact.selectedDataPoints[i] = [];
      }
      w.interact.selectedDataPoints[i].push(j);
    }
    if (selected === "true") {
      const activeFilter = w.config.states.active.filter;
      if (activeFilter !== "none") {
        filters.applyFilter(path, i, activeFilter.type);
      } else {
        if (w.config.states.hover.filter !== "none") {
          if (!w.interact.isTouchDevice) {
            const hoverFilter = w.config.states.hover.filter;
            filters.applyFilter(path, i, hoverFilter.type);
          }
        }
      }
    } else {
      if (w.config.states.active.filter.type !== "none") {
        if (w.config.states.hover.filter.type !== "none" && !w.interact.isTouchDevice) {
          const hoverFilter = w.config.states.hover.filter;
          filters.applyFilter(path, i, hoverFilter.type);
        } else {
          filters.getDefaultFilter(path, i);
        }
      }
    }
    if (typeof w.config.chart.events.dataPointSelection === "function") {
      w.config.chart.events.dataPointSelection(e, this.ctx, {
        selectedDataPoints: w.interact.selectedDataPoints,
        seriesIndex: i,
        dataPointIndex: j,
        w
      });
    }
    if (e) {
      Graphics._fireEvent(w, "dataPointSelection", [
        e,
        this.ctx,
        {
          selectedDataPoints: w.interact.selectedDataPoints,
          seriesIndex: i,
          dataPointIndex: j,
          w
        }
      ]);
    }
  }
  /**
   * @param {any} el
   * @returns {{ x: number, y: number }}
   */
  rotateAroundCenter(el) {
    let coord = (
      /** @type {any} */
      {}
    );
    if (el && typeof el.getBBox === "function") {
      coord = el.getBBox();
    }
    const x = coord.x + coord.width / 2;
    const y = coord.y + coord.height / 2;
    return {
      x,
      y
    };
  }
  /**
   * Sets up event delegation on a parent group element.
   * Uses mouseover/mouseout (which bubble) to simulate mouseenter/mouseleave
   * on matching child elements, reducing per-element listener overhead.
   * @param {any} parentGroup
   * @param {string} targetSelector
   */
  setupEventDelegation(parentGroup, targetSelector) {
    let currentHovered = null;
    parentGroup.node.addEventListener("mouseover", (e) => {
      const targetNode = Graphics._findDelegateTarget(
        e.target,
        parentGroup.node,
        targetSelector
      );
      if (!targetNode || targetNode === currentHovered) return;
      if (currentHovered && /** @type {any} */
      currentHovered.instance) {
        this.pathMouseLeave(
          /** @type {any} */
          currentHovered.instance,
          e
        );
      }
      currentHovered = targetNode;
      if (targetNode.instance) {
        this.pathMouseEnter(targetNode.instance, e);
      }
    });
    parentGroup.node.addEventListener("mouseout", (e) => {
      if (!currentHovered) return;
      const relatedNode = e.relatedTarget ? Graphics._findDelegateTarget(
        e.relatedTarget,
        parentGroup.node,
        targetSelector
      ) : null;
      if (relatedNode !== currentHovered) {
        if (currentHovered && /** @type {any} */
        currentHovered.instance) {
          this.pathMouseLeave(
            /** @type {any} */
            currentHovered.instance,
            e
          );
        }
        currentHovered = null;
      }
    });
    parentGroup.node.addEventListener("mousedown", (e) => {
      const targetNode = Graphics._findDelegateTarget(
        e.target,
        parentGroup.node,
        targetSelector
      );
      if (targetNode && targetNode.instance) {
        this.pathMouseDown(targetNode.instance, e);
      }
    });
  }
  // Fire a named event from w.globals.events without requiring a ctx reference.
  // Mirrors Events.fireEvent() but reads the registry directly from w so that
  // pathMouseEnter/Leave/Down work even when this.ctx is null (Graphics instances
  // created without a ctx arg for drawing-only use cases).
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {string} name
   * @param {any[]} args
   */
  static _fireEvent(w, name2, args) {
    const evs = w.globals.events;
    if (!evs || !Object.prototype.hasOwnProperty.call(evs, name2)) return;
    const handlers = (
      /** @type {Record<string,any>} */
      evs[name2]
    );
    for (let i = 0; i < handlers.length; i++) {
      handlers[i].apply(null, args);
    }
  }
  /**
   * @param {any} node
   * @param {Record<string, any>} boundary
   * @param {string} selector
   */
  static _findDelegateTarget(node, boundary, selector) {
    while (node && node !== boundary && node !== document) {
      if (node.matches && node.matches(selector)) return node;
      node = node.parentNode;
    }
    return null;
  }
  /**
   * @param {any} el
   * @param {Record<string, any>} attrs
   */
  static setAttrs(el, attrs) {
    for (const key in attrs) {
      if (Object.prototype.hasOwnProperty.call(attrs, key)) {
        el.setAttribute(key, attrs[key]);
      }
    }
  }
  /**
   * @param {string} text
   * @param {string} fontSize
   * @param {string | null | undefined} [fontFamily]
   * @param {string} [transform]
   * @returns {{ width: number, height: number }}
   */
  getTextRects(text, fontSize, fontFamily, transform, useBBox = true) {
    const w = this.w;
    const cacheKey = [text, fontSize, fontFamily, transform, useBBox].join("\0");
    const cache = w.globals.textRectsCache;
    if (cache && cache.has(cacheKey)) {
      return (
        /** @type {{ width: number, height: number }} */
        cache.get(cacheKey)
      );
    }
    const virtualText = this.drawText({
      x: -200,
      y: -200,
      text,
      textAnchor: "start",
      fontSize,
      fontFamily,
      foreColor: "#fff",
      opacity: 0
    });
    if (transform) {
      virtualText.attr("transform", transform);
    }
    w.dom.Paper.add(virtualText);
    let rect = virtualText.bbox();
    if (!useBBox) {
      rect = virtualText.node.getBoundingClientRect();
    }
    virtualText.remove();
    const result = {
      width: rect.width,
      height: rect.height
    };
    if (cache) {
      cache.set(cacheKey, result);
    }
    return result;
  }
  /**
   * append ... to long text
   * http://stackoverflow.com/questions/9241315/trimming-text-to-a-given-pixel-width-in-svg
   * @memberof Graphics
   * @param {Record<string, any>} textObj
   * @param {string} textString
   * @param {number} width
   **/
  placeTextWithEllipsis(textObj, textString, width) {
    if (typeof textObj.getComputedTextLength !== "function") return;
    textObj.textContent = textString;
    if (textString.length > 0) {
      if (textObj.getComputedTextLength() >= width / 1.1) {
        for (let x = textString.length - 3; x > 0; x -= 3) {
          if (textObj.getSubStringLength(0, x) <= width / 1.1) {
            textObj.textContent = textString.substring(0, x) + "...";
            return;
          }
        }
        textObj.textContent = ".";
      }
    }
  }
}
const SVGNS = "http://www.w3.org/2000/svg";
class Point {
  /**
   * @param {number|{x:number,y:number}} x
   * @param {number} [y]
   */
  constructor(x, y) {
    if (typeof x === "object") {
      this.x = x.x;
      this.y = x.y;
    } else {
      this.x = x || 0;
      this.y = y || 0;
    }
  }
  /**
   * @param {Matrix} matrix
   */
  transform(matrix) {
    return matrix.apply(this);
  }
  clone() {
    return new Point(this.x, this.y);
  }
}
class Matrix {
  /**
   * @param {number} a
   * @param {number} b
   * @param {number} c
   * @param {number} d
   * @param {number} e
   * @param {number} f
   */
  constructor(a, b, c, d, e, f) {
    this.a = a != null ? a : 1;
    this.b = b != null ? b : 0;
    this.c = c != null ? c : 0;
    this.d = d != null ? d : 1;
    this.e = e != null ? e : 0;
    this.f = f != null ? f : 0;
  }
  /**
   * @param {number} deg
   */
  rotate(deg) {
    const rad = deg * Math.PI / 180;
    const cos = Math.cos(rad);
    const sin = Math.sin(rad);
    return this.multiply(new Matrix(cos, sin, -sin, cos, 0, 0));
  }
  /**
   * @param {number} sx
   * @param {number} sy
   */
  scale(sx, sy) {
    return this.multiply(new Matrix(sx, 0, 0, sy != null ? sy : sx, 0, 0));
  }
  /**
   * @param {Matrix} m
   */
  multiply(m) {
    return new Matrix(
      this.a * m.a + this.c * m.b,
      this.b * m.a + this.d * m.b,
      this.a * m.c + this.c * m.d,
      this.b * m.c + this.d * m.d,
      this.a * m.e + this.c * m.f + this.e,
      this.b * m.e + this.d * m.f + this.f
    );
  }
  /**
   * @param {Point} point
   */
  apply(point) {
    return new Point(
      this.a * point.x + this.c * point.y + this.e,
      this.b * point.x + this.d * point.y + this.f
    );
  }
}
class Box {
  /**
   * @param {number} x
   * @param {number} y
   * @param {number} w
   * @param {number} h
   */
  constructor(x, y, w, h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.width = w;
    this.height = h;
    this.x2 = x + w;
    this.y2 = y + h;
  }
}
class Fill {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
    this.opts = null;
    this.seriesIndex = 0;
    this.patternIDs = [];
  }
  /**
   * @param {Record<string, any>} params
   */
  clippedImgArea(params) {
    const w = this.w;
    const cnf = w.config;
    const svgW = parseInt(String(w.layout.gridWidth), 10);
    const svgH = parseInt(String(w.layout.gridHeight), 10);
    const size = svgW > svgH ? svgW : svgH;
    const fillImg = params.image;
    let imgWidth = 0;
    let imgHeight = 0;
    if (typeof params.width === "undefined" && typeof params.height === "undefined") {
      if (cnf.fill.image.width !== void 0 && cnf.fill.image.height !== void 0) {
        imgWidth = cnf.fill.image.width + 1;
        imgHeight = cnf.fill.image.height;
      } else {
        imgWidth = size + 1;
        imgHeight = size;
      }
    } else {
      imgWidth = params.width;
      imgHeight = params.height;
    }
    const elPattern = BrowserAPIs.createElementNS(SVGNS, "pattern");
    Graphics.setAttrs(elPattern, {
      id: params.patternID,
      patternUnits: params.patternUnits ? params.patternUnits : "userSpaceOnUse",
      width: imgWidth + "px",
      height: imgHeight + "px"
    });
    const elImage = BrowserAPIs.createElementNS(SVGNS, "image");
    elPattern.appendChild(elImage);
    const SVGLib = Environment.isBrowser() ? (
      /** @type {any} */
      window.SVG
    ) : (
      /** @type {any} */
      global.SVG
    );
    elImage.setAttributeNS(SVGLib.xlink, "href", fillImg);
    Graphics.setAttrs(elImage, {
      x: 0,
      y: 0,
      preserveAspectRatio: "none",
      width: imgWidth + "px",
      height: imgHeight + "px"
    });
    elImage.style.opacity = params.opacity;
    w.dom.elDefs.node.appendChild(elPattern);
  }
  /**
   * @param {Record<string, any>} opts
   */
  getSeriesIndex(opts) {
    const w = this.w;
    const cType = w.config.chart.type;
    if ((cType === "bar" || cType === "rangeBar") && w.config.plotOptions.bar.distributed || cType === "heatmap" || cType === "treemap") {
      this.seriesIndex = opts.seriesNumber;
    } else {
      this.seriesIndex = opts.seriesNumber % w.seriesData.series.length;
    }
    return this.seriesIndex;
  }
  /**
   * @param {number[]} data
   * @param {Record<string, any>} multiColorConfig
   */
  computeColorStops(data, multiColorConfig) {
    const w = this.w;
    let maxPositive = null;
    let minNegative = null;
    for (const value of data) {
      if (value >= multiColorConfig.threshold) {
        if (maxPositive === null || value > maxPositive) {
          maxPositive = value;
        }
      } else {
        if (minNegative === null || value < minNegative) {
          minNegative = value;
        }
      }
    }
    if (maxPositive === null) {
      maxPositive = multiColorConfig.threshold;
    }
    if (minNegative === null) {
      minNegative = multiColorConfig.threshold;
    }
    let totalRange = maxPositive - multiColorConfig.threshold + (multiColorConfig.threshold - minNegative);
    if (totalRange === 0) {
      totalRange = 1;
    }
    const negativePercentage = (multiColorConfig.threshold - minNegative) / totalRange * 100;
    let offset = 100 - negativePercentage;
    offset = Math.max(0, Math.min(offset, 100));
    return [
      {
        offset,
        color: multiColorConfig.colorAboveThreshold,
        opacity: w.config.fill.opacity
      },
      {
        offset: 0,
        color: multiColorConfig.colorBelowThreshold,
        opacity: w.config.fill.opacity
      }
    ];
  }
  /**
   * @param {Record<string, any>} opts
   */
  fillPath(opts) {
    var _a, _b, _c, _d;
    const w = this.w;
    this.opts = opts;
    const cnf = this.w.config;
    let pathFill;
    let patternFill, gradientFill;
    this.seriesIndex = this.getSeriesIndex(opts);
    const drawMultiColorLine = cnf.plotOptions.line.colors.colorAboveThreshold && cnf.plotOptions.line.colors.colorBelowThreshold;
    const fillColors = this.getFillColors();
    let fillColor = fillColors[this.seriesIndex];
    if (w.seriesData.seriesColors[this.seriesIndex] !== void 0) {
      fillColor = w.seriesData.seriesColors[this.seriesIndex];
    }
    if (typeof fillColor === "function") {
      fillColor = fillColor({
        seriesIndex: this.seriesIndex,
        dataPointIndex: opts.dataPointIndex,
        value: opts.value,
        w
      });
    }
    const fillType = opts.fillType ? opts.fillType : this.getFillType(this.seriesIndex);
    let fillOpacity = Array.isArray(cnf.fill.opacity) ? cnf.fill.opacity[this.seriesIndex] : cnf.fill.opacity;
    const useGradient = fillType === "gradient" || drawMultiColorLine;
    if (opts.color) {
      fillColor = opts.color;
    }
    const seriesItem = (
      /** @type {Record<string,any>} */
      w.config.series[this.seriesIndex]
    );
    if ((_b = (_a = seriesItem == null ? void 0 : seriesItem.data) == null ? void 0 : _a[opts.dataPointIndex]) == null ? void 0 : _b.fillColor) {
      fillColor = (_d = (_c = seriesItem == null ? void 0 : seriesItem.data) == null ? void 0 : _c[opts.dataPointIndex]) == null ? void 0 : _d.fillColor;
    }
    if (!fillColor) {
      fillColor = "#fff";
      console.warn("undefined color - ApexCharts");
    }
    if (opts.opacity !== void 0 && opts.opacity !== null) fillOpacity = opts.opacity;
    let defaultColor = fillColor;
    if (Utils$1.isCSSVariable(fillColor)) {
      defaultColor = Utils$1.applyOpacityToColor(fillColor, fillOpacity);
    } else if (fillColor.indexOf("rgb") === -1) {
      if (fillColor.indexOf("#") === -1) {
        defaultColor = fillColor;
      } else if (fillColor.length < 9) {
        defaultColor = Utils$1.hexToRgba(fillColor, fillOpacity);
      }
    } else {
      if (fillColor.indexOf("rgba") > -1) {
        fillOpacity = Utils$1.getOpacityFromRGBA(fillColor);
      } else {
        defaultColor = Utils$1.hexToRgba(Utils$1.rgb2hex(fillColor), fillOpacity);
      }
    }
    const resolvedFillColor = Utils$1.isCSSVariable(fillColor) ? Utils$1.getThemeColor(fillColor) : fillColor;
    if (fillType === "pattern") {
      patternFill = this.handlePatternFill({
        fillConfig: opts.fillConfig,
        patternFill,
        fillColor: resolvedFillColor,
        defaultColor
      });
    }
    if (useGradient) {
      const colorStops = cnf.fill.gradient.colorStops ? [...cnf.fill.gradient.colorStops] : [];
      let type = cnf.fill.gradient.type;
      if (drawMultiColorLine) {
        colorStops[this.seriesIndex] = this.computeColorStops(
          w.seriesData.series[this.seriesIndex],
          cnf.plotOptions.line.colors
        );
        type = "vertical";
      }
      gradientFill = this.handleGradientFill({
        type,
        fillConfig: opts.fillConfig,
        fillColor: resolvedFillColor,
        fillOpacity,
        colorStops,
        i: this.seriesIndex
      });
    }
    if (fillType === "image") {
      const imgSrc = cnf.fill.image.src;
      const patternID = opts.patternID ? opts.patternID : "";
      const patternKey = `pattern${w.globals.cuid}${opts.seriesNumber + 1}${patternID}`;
      if (this.patternIDs.indexOf(patternKey) === -1) {
        this.clippedImgArea({
          opacity: fillOpacity,
          image: Array.isArray(imgSrc) ? opts.seriesNumber < imgSrc.length ? imgSrc[opts.seriesNumber] : imgSrc[0] : imgSrc,
          width: opts.width ? opts.width : void 0,
          height: opts.height ? opts.height : void 0,
          patternUnits: opts.patternUnits,
          patternID: patternKey
        });
        this.patternIDs.push(patternKey);
      }
      pathFill = `url(#${patternKey})`;
    } else if (useGradient) {
      pathFill = gradientFill;
    } else if (fillType === "pattern") {
      pathFill = patternFill;
    } else {
      pathFill = defaultColor;
    }
    if (opts.solid) {
      pathFill = defaultColor;
    }
    return pathFill;
  }
  /**
   * @param {number} seriesIndex
   */
  getFillType(seriesIndex) {
    const w = this.w;
    if (Array.isArray(w.config.fill.type)) {
      return w.config.fill.type[seriesIndex];
    } else {
      return w.config.fill.type;
    }
  }
  getFillColors() {
    const w = this.w;
    const cnf = w.config;
    const opts = this.opts;
    let fillColors = [];
    if (w.globals.comboCharts) {
      if (
        /** @type {Record<string,any>} */
        w.config.series[this.seriesIndex].type === "line"
      ) {
        if (Array.isArray(w.globals.stroke.colors)) {
          fillColors = w.globals.stroke.colors;
        } else {
          fillColors.push(w.globals.stroke.colors);
        }
      } else {
        if (Array.isArray(w.globals.fill.colors)) {
          fillColors = w.globals.fill.colors;
        } else {
          fillColors.push(w.globals.fill.colors);
        }
      }
    } else {
      if (cnf.chart.type === "line") {
        if (Array.isArray(w.globals.stroke.colors)) {
          fillColors = w.globals.stroke.colors;
        } else {
          fillColors.push(w.globals.stroke.colors);
        }
      } else {
        if (Array.isArray(w.globals.fill.colors)) {
          fillColors = w.globals.fill.colors;
        } else {
          fillColors.push(w.globals.fill.colors);
        }
      }
    }
    if (typeof opts.fillColors !== "undefined") {
      fillColors = [];
      if (Array.isArray(opts.fillColors)) {
        fillColors = opts.fillColors.slice();
      } else {
        fillColors.push(opts.fillColors);
      }
    }
    return fillColors;
  }
  /** @param {{fillConfig: any, patternFill: any, fillColor: any, defaultColor: any}} opts */
  handlePatternFill({ fillConfig, patternFill, fillColor, defaultColor }) {
    let fillCnf = this.w.config.fill;
    if (fillConfig) {
      fillCnf = fillConfig;
    }
    const opts = this.opts;
    const graphics = new Graphics(this.w);
    const patternStrokeWidth = Array.isArray(fillCnf.pattern.strokeWidth) ? fillCnf.pattern.strokeWidth[this.seriesIndex] : fillCnf.pattern.strokeWidth;
    const patternLineColor = fillColor;
    if (Array.isArray(fillCnf.pattern.style)) {
      if (typeof fillCnf.pattern.style[opts.seriesNumber] !== "undefined") {
        const pf = graphics.drawPattern(
          fillCnf.pattern.style[opts.seriesNumber],
          fillCnf.pattern.width,
          fillCnf.pattern.height,
          patternLineColor,
          patternStrokeWidth
        );
        patternFill = pf;
      } else {
        patternFill = defaultColor;
      }
    } else {
      patternFill = graphics.drawPattern(
        fillCnf.pattern.style,
        fillCnf.pattern.width,
        fillCnf.pattern.height,
        patternLineColor,
        patternStrokeWidth
      );
    }
    return patternFill;
  }
  handleGradientFill({
    type,
    fillColor,
    fillOpacity,
    fillConfig,
    colorStops,
    i
  }) {
    let fillCnf = this.w.config.fill;
    if (fillConfig) {
      fillCnf = __spreadValues(__spreadValues({}, fillCnf), fillConfig);
    }
    const opts = this.opts;
    const graphics = new Graphics(this.w);
    const utils = new Utils$1();
    type = type || fillCnf.gradient.type;
    let gradientFrom = fillColor;
    let gradientTo;
    let opacityFrom = fillCnf.gradient.opacityFrom === void 0 ? fillOpacity : Array.isArray(fillCnf.gradient.opacityFrom) ? fillCnf.gradient.opacityFrom[i] : fillCnf.gradient.opacityFrom;
    if (gradientFrom.indexOf("rgba") > -1) {
      opacityFrom = Utils$1.getOpacityFromRGBA(gradientFrom);
    }
    let opacityTo = fillCnf.gradient.opacityTo === void 0 ? fillOpacity : Array.isArray(fillCnf.gradient.opacityTo) ? fillCnf.gradient.opacityTo[i] : fillCnf.gradient.opacityTo;
    if (fillCnf.gradient.gradientToColors === void 0 || fillCnf.gradient.gradientToColors.length === 0) {
      if (fillCnf.gradient.shade === "dark") {
        gradientTo = utils.shadeColor(
          parseFloat(fillCnf.gradient.shadeIntensity) * -1,
          fillColor.indexOf("rgb") > -1 ? Utils$1.rgb2hex(fillColor) : fillColor
        );
      } else {
        gradientTo = utils.shadeColor(
          parseFloat(fillCnf.gradient.shadeIntensity),
          fillColor.indexOf("rgb") > -1 ? Utils$1.rgb2hex(fillColor) : fillColor
        );
      }
    } else {
      if (fillCnf.gradient.gradientToColors[opts.seriesNumber]) {
        const gToColor = fillCnf.gradient.gradientToColors[opts.seriesNumber];
        gradientTo = gToColor;
        if (gToColor.indexOf("rgba") > -1) {
          opacityTo = Utils$1.getOpacityFromRGBA(gToColor);
        }
      } else {
        gradientTo = fillColor;
      }
    }
    if (fillCnf.gradient.gradientFrom) {
      gradientFrom = fillCnf.gradient.gradientFrom;
    }
    if (fillCnf.gradient.gradientTo) {
      gradientTo = fillCnf.gradient.gradientTo;
    }
    if (fillCnf.gradient.inverseColors) {
      const t = gradientFrom;
      gradientFrom = gradientTo;
      gradientTo = t;
    }
    if (gradientFrom.indexOf("rgb") > -1) {
      gradientFrom = Utils$1.rgb2hex(gradientFrom);
    }
    if (gradientTo.indexOf("rgb") > -1) {
      gradientTo = Utils$1.rgb2hex(gradientTo);
    }
    return graphics.drawGradient(
      type,
      gradientFrom,
      gradientTo,
      opacityFrom,
      opacityTo,
      opts.size,
      fillCnf.gradient.stops,
      colorStops,
      i
    );
  }
}
class Markers {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
    this._filters = new Filters(this.w);
    this._graphics = new Graphics(this.w, this.ctx);
  }
  setGlobalMarkerSize() {
    const w = this.w;
    w.globals.markers.size = Array.isArray(w.config.markers.size) ? w.config.markers.size : [w.config.markers.size];
    if (w.globals.markers.size.length > 0) {
      if (w.globals.markers.size.length < w.seriesData.series.length + 1) {
        for (let i = 0; i <= w.seriesData.series.length; i++) {
          if (typeof w.globals.markers.size[i] === "undefined") {
            w.globals.markers.size.push(w.globals.markers.size[0]);
          }
        }
      }
    } else {
      w.globals.markers.size = w.config.series.map(
        () => (
          /** @type {number} */
          w.config.markers.size
        )
      );
    }
  }
  /** @param {{ pointsPos?: any, seriesIndex?: any, j?: any, pSize?: any, alwaysDrawMarker?: boolean, isVirtualPoint?: boolean }} opts */
  plotChartMarkers({
    pointsPos,
    seriesIndex,
    j,
    pSize,
    alwaysDrawMarker = false,
    isVirtualPoint = false
  }) {
    const w = this.w;
    const i = seriesIndex;
    const p = pointsPos;
    let elMarkersWrap = null;
    const graphics = new Graphics(this.w);
    const hasDiscreteMarkers = w.config.markers.discrete && w.config.markers.discrete.length;
    if (Array.isArray(p.x)) {
      for (let q = 0; q < p.x.length; q++) {
        let markerElement;
        let dataPointIndex = j;
        let invalidMarker = !Utils$1.isNumber(p.y[q]);
        if (w.globals.markers.largestSize === 0 && w.globals.hasNullValues && w.seriesData.series[i][j + 1] !== null && !isVirtualPoint) {
          invalidMarker = true;
        }
        if (j === 1 && q === 0) dataPointIndex = 0;
        if (j === 1 && q === 1) dataPointIndex = 1;
        let markerClasses = "apexcharts-marker";
        if ((w.config.chart.type === "line" || w.config.chart.type === "area") && !w.globals.comboCharts && !w.config.tooltip.intersect) {
          markerClasses += " no-pointer-events";
        }
        const shouldMarkerDraw = Array.isArray(w.config.markers.size) ? w.globals.markers.size[seriesIndex] > 0 : w.config.markers.size > 0;
        if (shouldMarkerDraw || alwaysDrawMarker || hasDiscreteMarkers) {
          if (!invalidMarker) {
            markerClasses += ` w${Utils$1.randomId()}`;
          }
          const opts = this.getMarkerConfig({
            cssClass: markerClasses,
            seriesIndex,
            dataPointIndex
          });
          const _si = (
            /** @type {Record<string,any>} */
            w.config.series[i]
          );
          if (_si.data[dataPointIndex]) {
            if (_si.data[dataPointIndex].fillColor) {
              opts.pointFillColor = _si.data[dataPointIndex].fillColor;
            }
            if (_si.data[dataPointIndex].strokeColor) {
              opts.pointStrokeColor = _si.data[dataPointIndex].strokeColor;
            }
          }
          if (typeof pSize !== "undefined") {
            opts.pSize = pSize;
          }
          if (p.x[q] < -w.globals.markers.largestSize || p.x[q] > w.layout.gridWidth + w.globals.markers.largestSize || p.y[q] < -w.globals.markers.largestSize || p.y[q] > w.layout.gridHeight + w.globals.markers.largestSize) {
            opts.pSize = 0;
          }
          if (!invalidMarker) {
            const shouldCreateMarkerWrap = w.globals.markers.size[seriesIndex] > 0 || alwaysDrawMarker || hasDiscreteMarkers;
            if (shouldCreateMarkerWrap && !elMarkersWrap) {
              elMarkersWrap = graphics.group({
                class: alwaysDrawMarker || hasDiscreteMarkers ? "" : "apexcharts-series-markers"
              });
              elMarkersWrap.attr(
                "clip-path",
                `url(#gridRectMarkerMask${w.globals.cuid})`
              );
              this.setupMarkerDelegation(elMarkersWrap);
            }
            markerElement = graphics.drawMarker(p.x[q], p.y[q], opts);
            markerElement.attr("rel", dataPointIndex);
            markerElement.attr("j", dataPointIndex);
            markerElement.attr("index", seriesIndex);
            markerElement.node.setAttribute("default-marker-size", opts.pSize);
            this._filters.setSelectionFilter(
              markerElement,
              seriesIndex,
              dataPointIndex
            );
            if (elMarkersWrap) {
              elMarkersWrap.add(markerElement);
            }
          }
        } else {
          if (typeof w.globals.pointsArray[seriesIndex] === "undefined")
            w.globals.pointsArray[seriesIndex] = [];
          w.globals.pointsArray[seriesIndex].push([p.x[q], p.y[q]]);
        }
      }
    }
    return elMarkersWrap;
  }
  /** @param {{cssClass: any, seriesIndex: any, dataPointIndex?: any, radius?: any, size?: any, strokeWidth?: any}} opts */
  getMarkerConfig({
    cssClass,
    seriesIndex,
    dataPointIndex = null,
    radius = null,
    size = null,
    strokeWidth = null
  }) {
    const w = this.w;
    const pStyle = this.getMarkerStyle(seriesIndex);
    let pSize = size === null ? w.globals.markers.size[seriesIndex] : size;
    const m = w.config.markers;
    if (dataPointIndex !== null && m.discrete.length) {
      m.discrete.map((marker) => {
        if (marker.seriesIndex === seriesIndex && marker.dataPointIndex === dataPointIndex) {
          pStyle.pointStrokeColor = marker.strokeColor;
          pStyle.pointFillColor = marker.fillColor;
          pSize = marker.size;
          pStyle.pointShape = marker.shape;
        }
      });
    }
    return {
      pSize: radius === null ? pSize : radius,
      pRadius: radius !== null ? radius : m.radius,
      pointStrokeWidth: strokeWidth !== null ? strokeWidth : Array.isArray(m.strokeWidth) ? m.strokeWidth[seriesIndex] : m.strokeWidth,
      pointStrokeColor: pStyle.pointStrokeColor,
      pointFillColor: pStyle.pointFillColor,
      shape: pStyle.pointShape || (Array.isArray(m.shape) ? m.shape[seriesIndex] : m.shape),
      class: cssClass,
      pointStrokeOpacity: Array.isArray(m.strokeOpacity) ? m.strokeOpacity[seriesIndex] : m.strokeOpacity,
      pointStrokeDashArray: Array.isArray(m.strokeDashArray) ? m.strokeDashArray[seriesIndex] : m.strokeDashArray,
      pointFillOpacity: Array.isArray(m.fillOpacity) ? m.fillOpacity[seriesIndex] : m.fillOpacity,
      seriesIndex
    };
  }
  /**
   * @param {any} parentGroup
   */
  setupMarkerDelegation(parentGroup) {
    const w = this.w;
    const selector = ".apexcharts-marker";
    this._graphics.setupEventDelegation(parentGroup, selector);
    parentGroup.node.addEventListener("click", (e) => {
      if (w.config.markers.onClick) {
        const targetNode = Graphics._findDelegateTarget(
          e.target,
          parentGroup.node,
          selector
        );
        if (targetNode) w.config.markers.onClick(e);
      }
    });
    parentGroup.node.addEventListener("dblclick", (e) => {
      if (w.config.markers.onDblClick) {
        const targetNode = Graphics._findDelegateTarget(
          e.target,
          parentGroup.node,
          selector
        );
        if (targetNode) w.config.markers.onDblClick(e);
      }
    });
    parentGroup.node.addEventListener(
      "touchstart",
      (e) => {
        const targetNode = Graphics._findDelegateTarget(
          e.target,
          parentGroup.node,
          selector
        );
        if (targetNode && targetNode.instance) {
          this._graphics.pathMouseDown(targetNode.instance, e);
        }
      },
      { passive: true }
    );
  }
  /**
   * @param {any} marker
   */
  addEvents(marker) {
    const w = this.w;
    marker.node.addEventListener(
      "mouseenter",
      this._graphics.pathMouseEnter.bind(this.ctx, marker)
    );
    marker.node.addEventListener(
      "mouseleave",
      this._graphics.pathMouseLeave.bind(this.ctx, marker)
    );
    marker.node.addEventListener(
      "mousedown",
      this._graphics.pathMouseDown.bind(this.ctx, marker)
    );
    marker.node.addEventListener("click", w.config.markers.onClick);
    marker.node.addEventListener("dblclick", w.config.markers.onDblClick);
    marker.node.addEventListener(
      "touchstart",
      this._graphics.pathMouseDown.bind(this.ctx, marker),
      { passive: true }
    );
  }
  /**
   * @returns {any}
   * @param {number} seriesIndex
   */
  getMarkerStyle(seriesIndex) {
    const w = this.w;
    const colors = w.globals.markers.colors;
    const strokeColors = w.config.markers.strokeColor || w.config.markers.strokeColors;
    const pointStrokeColor = Array.isArray(strokeColors) ? strokeColors[seriesIndex] : strokeColors;
    const pointFillColor = Array.isArray(colors) ? colors[seriesIndex] : colors;
    return {
      pointStrokeColor,
      pointFillColor
    };
  }
}
class Scatter {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.ctx = ctx;
    this.w = w;
    this.initialAnim = this.w.config.chart.animations.enabled;
    this.anim = new Animations(this.w);
    this.filters = new Filters(this.w);
    this.fill = new Fill(this.w);
    this.markers = new Markers(this.w, this.ctx);
    this.graphics = new Graphics(this.w);
  }
  /**
   * @param {Element} elSeries
   * @param {number} j
   * @param {Record<string, any>} opts
   */
  draw(elSeries, j, opts) {
    const w = this.w;
    const graphics = this.graphics;
    const realIndex = opts.realIndex;
    const pointsPos = opts.pointsPos;
    const zRatio = opts.zRatio;
    const elPointsMain = opts.elParent;
    const elPointsWrap = graphics.group({
      class: `apexcharts-series-markers apexcharts-series-${w.config.chart.type}`
    });
    elPointsWrap.attr("clip-path", `url(#gridRectMarkerMask${w.globals.cuid})`);
    this.markers.setupMarkerDelegation(elPointsWrap);
    if (Array.isArray(pointsPos.x)) {
      for (let q = 0; q < pointsPos.x.length; q++) {
        let dataPointIndex = j + 1;
        let shouldDraw = true;
        if (j === 0 && q === 0) dataPointIndex = 0;
        if (j === 0 && q === 1) dataPointIndex = 1;
        let radius = w.globals.markers.size[realIndex];
        if (zRatio !== Infinity) {
          const bubble = w.config.plotOptions.bubble;
          radius = w.seriesData.seriesZ[realIndex][dataPointIndex];
          if (bubble.zScaling) {
            radius /= zRatio;
          }
          if (bubble.minBubbleRadius && radius < bubble.minBubbleRadius) {
            radius = bubble.minBubbleRadius;
          }
          if (bubble.maxBubbleRadius && radius > bubble.maxBubbleRadius) {
            radius = bubble.maxBubbleRadius;
          }
        }
        const x = pointsPos.x[q];
        const y = pointsPos.y[q];
        radius = radius || 0;
        if (y === null || typeof w.seriesData.series[realIndex][dataPointIndex] === "undefined") {
          shouldDraw = false;
        }
        if (shouldDraw) {
          const point = this.drawPoint(
            x,
            y,
            radius,
            realIndex,
            dataPointIndex,
            j
          );
          elPointsWrap.add(point);
        }
        elPointsMain.add(elPointsWrap);
      }
    }
  }
  /**
   * @param {number} x
   * @param {number} y
   * @param {number} radius
   * @param {number} realIndex
   * @param {number} dataPointIndex
   * @param {number} j
   */
  drawPoint(x, y, radius, realIndex, dataPointIndex, j) {
    const w = this.w;
    const i = realIndex;
    const anim = this.anim;
    const filters = this.filters;
    const fill = this.fill;
    const markers = this.markers;
    const graphics = this.graphics;
    const markerConfig = markers.getMarkerConfig({
      cssClass: "apexcharts-marker",
      seriesIndex: i,
      dataPointIndex,
      radius: w.config.chart.type === "bubble" || w.globals.comboCharts && w.config.series[realIndex] && /** @type {Record<string,any>} */
      w.config.series[realIndex].type === "bubble" ? radius : null
    });
    let pathFillCircle = fill.fillPath({
      seriesNumber: realIndex,
      dataPointIndex,
      color: markerConfig.pointFillColor,
      patternUnits: "objectBoundingBox",
      value: w.seriesData.series[realIndex][j]
    });
    const el = graphics.drawMarker(x, y, markerConfig);
    const _si = (
      /** @type {Record<string,any>} */
      w.config.series[i]
    );
    if (_si.data[dataPointIndex]) {
      if (_si.data[dataPointIndex].fillColor) {
        pathFillCircle = _si.data[dataPointIndex].fillColor;
      }
    }
    el.attr({
      fill: pathFillCircle
    });
    if (w.config.chart.dropShadow.enabled) {
      const dropShadow = w.config.chart.dropShadow;
      filters.dropShadow(el, dropShadow, realIndex);
    }
    if (this.initialAnim && !w.globals.dataChanged && !w.globals.resized) {
      const speed = w.config.chart.animations.speed;
      anim.animateMarker(
        el,
        speed,
        /** @type {any} */
        w.globals.easing,
        () => {
          window.setTimeout(() => {
            anim.animationCompleted(el);
          }, 100);
        }
      );
    } else {
      w.globals.animationEnded = true;
    }
    el.attr({
      rel: dataPointIndex,
      j: dataPointIndex,
      index: realIndex,
      "default-marker-size": markerConfig.pSize
    });
    filters.setSelectionFilter(el, realIndex, dataPointIndex);
    el.node.classList.add("apexcharts-marker");
    return el;
  }
  /**
   * @param {number} y
   */
  centerTextInBubble(y) {
    const w = this.w;
    y = y + parseInt(w.config.dataLabels.style.fontSize, 10) / 4;
    return {
      y
    };
  }
}
class DataLabels {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext | null} ctx
   */
  constructor(w, ctx = null) {
    this.w = w;
    this.ctx = ctx;
  }
  // When there are many datalabels to be printed, and some of them overlaps each other in the same series, this method will take care of that
  // Also, when datalabels exceeds the drawable area and get clipped off, we need to adjust and move some pixels to make them visible again
  /**
   * @param {number} x
   * @param {number} y
   * @param {any} val
   * @param {number} i
   * @param {number} dataPointIndex
   * @param {boolean} alwaysDrawDataLabel
   * @param {string} fontSize
   */
  dataLabelsCorrection(x, y, val, i, dataPointIndex, alwaysDrawDataLabel, fontSize) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    let drawnextLabel = false;
    const textRects = (
      /** @type {any} */
      graphics.getTextRects(val, fontSize)
    );
    const width = textRects.width;
    const height = textRects.height;
    if (y < 0) y = 0;
    if (y > w.layout.gridHeight + height) y = w.layout.gridHeight + height / 2;
    if (typeof /** @type {any} */
    w.globals.dataLabelsRects[i] === "undefined") {
      w.globals.dataLabelsRects[i] = [];
    }
    w.globals.dataLabelsRects[i].push({
      x,
      y,
      width,
      height
    });
    const len = (
      /** @type {any} */
      w.globals.dataLabelsRects[i].length - 2
    );
    const lastDrawnIndex = typeof w.globals.lastDrawnDataLabelsIndexes[i] !== "undefined" ? w.globals.lastDrawnDataLabelsIndexes[i][w.globals.lastDrawnDataLabelsIndexes[i].length - 1] : 0;
    if (typeof /** @type {any} */
    w.globals.dataLabelsRects[i][len] !== "undefined") {
      const lastDataLabelRect = (
        /** @type {any} */
        w.globals.dataLabelsRects[i][lastDrawnIndex]
      );
      if (
        // next label forward and x not intersecting
        x > lastDataLabelRect.x + lastDataLabelRect.width || y > lastDataLabelRect.y + lastDataLabelRect.height || y + height < lastDataLabelRect.y || x + width < lastDataLabelRect.x
      ) {
        drawnextLabel = true;
      }
    }
    if (dataPointIndex === 0 || alwaysDrawDataLabel) {
      drawnextLabel = true;
    }
    return {
      x,
      y,
      textRects,
      drawnextLabel
    };
  }
  /** @param {{type: any, pos: any, i: any, j: any, isRangeStart: any, strokeWidth?: any}} opts */
  drawDataLabel({ type, pos, i, j, isRangeStart, strokeWidth = 2 }) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const dataLabelsConfig = w.config.dataLabels;
    let x = 0;
    let y = 0;
    let dataPointIndex = j;
    let elDataLabelsWrap = null;
    const seriesCollapsed = w.globals.collapsedSeriesIndices.indexOf(i) !== -1;
    if (seriesCollapsed || !dataLabelsConfig.enabled || !Array.isArray(pos.x)) {
      return elDataLabelsWrap;
    }
    elDataLabelsWrap = graphics.group({
      class: "apexcharts-data-labels"
    });
    for (let q = 0; q < pos.x.length; q++) {
      x = pos.x[q] + dataLabelsConfig.offsetX;
      y = pos.y[q] + dataLabelsConfig.offsetY + strokeWidth;
      if (!isNaN(x)) {
        if (j === 1 && q === 0) dataPointIndex = 0;
        if (j === 1 && q === 1) dataPointIndex = 1;
        let val = w.seriesData.series[i][dataPointIndex];
        if (type === "rangeArea") {
          if (isRangeStart) {
            val = w.rangeData.seriesRangeStart[i][dataPointIndex];
          } else {
            val = w.rangeData.seriesRangeEnd[i][dataPointIndex];
          }
        }
        let text = "";
        const getText = (v) => {
          return w.config.dataLabels.formatter(v, {
            seriesIndex: i,
            dataPointIndex,
            w
          });
        };
        if (w.config.chart.type === "bubble") {
          val = w.seriesData.seriesZ[i][dataPointIndex];
          text = getText(val);
          y = pos.y[q];
          const scatter = new Scatter(
            this.w,
            /** @type {import('../types/internal').ChartContext} */
            this.ctx
          );
          const centerTextInBubbleCoords = scatter.centerTextInBubble(y);
          y = centerTextInBubbleCoords.y;
        } else {
          if (typeof val !== "undefined") {
            text = getText(val);
          }
        }
        let textAnchor = w.config.dataLabels.textAnchor;
        if (w.globals.isSlopeChart) {
          if (dataPointIndex === 0) {
            textAnchor = "end";
          } else if (dataPointIndex === /** @type {Record<string,any>} */
          w.config.series[i].data.length - 1) {
            textAnchor = "start";
          } else {
            textAnchor = "middle";
          }
        }
        this.plotDataLabelsText({
          x,
          y,
          text,
          i,
          j: dataPointIndex,
          parent: elDataLabelsWrap,
          offsetCorrection: true,
          dataLabelsConfig: w.config.dataLabels,
          textAnchor
        });
      }
    }
    return elDataLabelsWrap;
  }
  /**
   * @param {Record<string, any>} opts
   */
  plotDataLabelsText(opts) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    let {
      x,
      y,
      i,
      j,
      text,
      textAnchor,
      fontSize,
      parent,
      dataLabelsConfig,
      color,
      alwaysDrawDataLabel,
      offsetCorrection,
      className
    } = opts;
    let dataLabelText = null;
    if (Array.isArray(w.config.dataLabels.enabledOnSeries)) {
      if (w.config.dataLabels.enabledOnSeries.indexOf(i) < 0) {
        return dataLabelText;
      }
    }
    let correctedLabels = {
      x,
      y,
      drawnextLabel: true,
      textRects: null
    };
    if (offsetCorrection) {
      correctedLabels = this.dataLabelsCorrection(
        x,
        y,
        text,
        i,
        j,
        alwaysDrawDataLabel,
        parseInt(
          /** @type {any} */
          dataLabelsConfig.style.fontSize,
          10
        ).toString()
      );
    }
    if (!w.interact.zoomed) {
      x = correctedLabels.x;
      y = correctedLabels.y;
    }
    if (correctedLabels.textRects) {
      const barPad = w.globals.barPadForNumericAxis || 0;
      if (x < -(barPad + 20) - /** @type {any} */
      correctedLabels.textRects.width || x > w.layout.gridWidth + /** @type {any} */
      correctedLabels.textRects.width + barPad + 30) {
        text = "";
      }
    }
    let dataLabelColor = w.globals.dataLabels.style.colors[i];
    if ((w.config.chart.type === "bar" || w.config.chart.type === "rangeBar") && w.config.plotOptions.bar.distributed || w.config.dataLabels.distributed) {
      dataLabelColor = w.globals.dataLabels.style.colors[j];
    }
    if (typeof dataLabelColor === "function") {
      dataLabelColor = /** @type {any} */
      dataLabelColor({
        series: w.seriesData.series,
        seriesIndex: i,
        dataPointIndex: j,
        w
      });
    }
    if (color) {
      dataLabelColor = color;
    }
    let offX = dataLabelsConfig.offsetX;
    let offY = dataLabelsConfig.offsetY;
    if (w.config.chart.type === "bar" || w.config.chart.type === "rangeBar") {
      offX = 0;
      offY = 0;
    }
    if (w.globals.isSlopeChart) {
      if (j !== 0) {
        offX = dataLabelsConfig.offsetX * -2 + 5;
      }
      if (j !== 0 && j !== /** @type {Record<string,any>} */
      w.config.series[i].data.length - 1) {
        offX = 0;
      }
    }
    if (correctedLabels.drawnextLabel) {
      if (textAnchor === "middle") {
        if (x === w.layout.gridWidth) {
          textAnchor = "end";
        }
      }
      dataLabelText = graphics.drawText({
        x: x + offX,
        y: y + offY,
        foreColor: dataLabelColor,
        textAnchor: textAnchor || dataLabelsConfig.textAnchor,
        text,
        fontSize: fontSize || dataLabelsConfig.style.fontSize,
        fontFamily: dataLabelsConfig.style.fontFamily,
        fontWeight: dataLabelsConfig.style.fontWeight || "normal"
      });
      dataLabelText.attr({
        class: className || "apexcharts-datalabel",
        cx: x,
        cy: y
      });
      if (dataLabelsConfig.dropShadow.enabled) {
        const textShadow = dataLabelsConfig.dropShadow;
        const filters = new Filters(this.w);
        filters.dropShadow(dataLabelText, textShadow);
      }
      parent.add(dataLabelText);
      if (typeof w.globals.lastDrawnDataLabelsIndexes[i] === "undefined") {
        w.globals.lastDrawnDataLabelsIndexes[i] = [];
      }
      w.globals.lastDrawnDataLabelsIndexes[i].push(j);
    }
    return dataLabelText;
  }
  /**
   * @param {Element} el
   * @param {{x: number, y: number, width: number, height: number}} coords
   */
  addBackgroundToDataLabel(el, coords) {
    const w = this.w;
    const bCnf = w.config.dataLabels.background;
    const paddingH = bCnf.padding;
    const paddingV = bCnf.padding / 2;
    const width = coords.width;
    const height = coords.height;
    const graphics = new Graphics(this.w);
    const elRect = graphics.drawRect(
      coords.x - paddingH,
      coords.y - paddingV / 2,
      width + paddingH * 2,
      height + paddingV,
      bCnf.borderRadius,
      w.config.chart.background === "transparent" || !w.config.chart.background ? "#fff" : w.config.chart.background,
      bCnf.opacity,
      bCnf.borderWidth,
      bCnf.borderColor
    );
    if (bCnf.dropShadow.enabled) {
      const filters = new Filters(this.w);
      filters.dropShadow(elRect, bCnf.dropShadow);
    }
    return elRect;
  }
  dataLabelsBackground() {
    var _a;
    const w = this.w;
    if (w.config.chart.type === "bubble") return;
    const elDataLabels = w.dom.baseEl.querySelectorAll(
      ".apexcharts-datalabels text"
    );
    for (let i = 0; i < elDataLabels.length; i++) {
      const el = elDataLabels[i];
      const coords = (
        /** @type {SVGGraphicsElement} */
        el.getBBox()
      );
      let elRect = null;
      if (coords.width && coords.height) {
        elRect = this.addBackgroundToDataLabel(el, coords);
      }
      if (elRect) {
        (_a = el.parentNode) == null ? void 0 : _a.insertBefore(elRect.node, el);
        const background = w.config.dataLabels.background.backgroundColor || el.getAttribute("fill");
        const shouldAnim = w.config.chart.animations.enabled && !w.globals.resized && !w.globals.dataChanged;
        if (shouldAnim) {
          elRect.animate().attr({ fill: background });
        } else {
          elRect.attr({ fill: background });
        }
        el.setAttribute("fill", w.config.dataLabels.background.foreColor);
      }
    }
  }
  bringForward() {
    const w = this.w;
    const elDataLabelsNodes = w.dom.baseEl.querySelectorAll(
      ".apexcharts-datalabels"
    );
    const elSeries = w.dom.baseEl.querySelector(
      ".apexcharts-plot-series:last-child"
    );
    for (let i = 0; i < elDataLabelsNodes.length; i++) {
      if (elSeries) {
        elSeries.insertBefore(elDataLabelsNodes[i], elSeries.nextSibling);
      }
    }
  }
}
class PerformanceCache {
  /**
   * Invalidate all caches
   * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
   */
  static invalidateAll(w) {
    if (!w || !w.globals) return;
    if (w.globals.cachedSelectors) {
      w.globals.cachedSelectors = {};
    }
    if (w.globals.domCache) {
      w.globals.domCache.clear();
    }
    w.globals.dimensionCache = {};
  }
  /**
   * Invalidate dimension cache only
   * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
   */
  static invalidateDimensions(w) {
    if (!w || !w.globals) return;
    w.globals.dimensionCache = {};
  }
  /**
   * Invalidate selector cache only
   * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
   */
  static invalidateSelectors(w) {
    if (!w || !w.globals) return;
    if (w.globals.cachedSelectors) {
      w.globals.cachedSelectors = {};
    }
  }
  /**
   * Get cached selector result or compute and cache it
   * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
   * @param {string} key - Cache key
   * @param {Function} queryFn - Function to execute if not cached
   * @returns {*} Cached or newly computed result
   */
  static getCachedSelector(w, key, queryFn) {
    if (!w || !w.globals) return queryFn();
    if (!w.globals.cachedSelectors) {
      w.globals.cachedSelectors = {};
    }
    if (!w.globals.cachedSelectors[key]) {
      w.globals.cachedSelectors[key] = queryFn();
    }
    return w.globals.cachedSelectors[key];
  }
  /**
   * Get cached dimension or compute and cache it
   * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
   * @param {string} key - Cache key
   * @param {Function} computeFn - Function to compute dimensions
   * @param {number} maxAge - Maximum cache age in milliseconds (default: 1000ms)
   * @returns {*} Cached or newly computed dimensions
   */
  static getCachedDimension(w, key, computeFn, maxAge = 1e3) {
    if (!w || !w.globals) return computeFn();
    if (!w.globals.dimensionCache) {
      w.globals.dimensionCache = {};
    }
    const cache = w.globals.dimensionCache[key];
    const now = Date.now();
    if (cache && cache.lastUpdate && now - cache.lastUpdate < maxAge) {
      return cache.value;
    }
    const value = computeFn();
    w.globals.dimensionCache[key] = {
      value,
      lastUpdate: now
    };
    return value;
  }
  /**
   * Cache a DOM element reference
   * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
   * @param {string} key - Cache key
   * @param {Element} element - DOM element to cache
   */
  static cacheDOMElement(w, key, element) {
    if (!w || !w.globals) return;
    if (!w.globals.domCache) {
      w.globals.domCache = /* @__PURE__ */ new Map();
    }
    w.globals.domCache.set(key, element);
  }
  /**
   * Get cached DOM element
   * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
   * @param {string} key - Cache key
   * @returns {Element|null} Cached element or null
   */
  static getCachedDOMElement(w, key) {
    if (!w || !w.globals || !w.globals.domCache) return null;
    return w.globals.domCache.get(key) || null;
  }
}
class AxesUtils {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   */
  constructor(w, { theme = null, timeScale = null } = {}) {
    this.w = w;
    this.theme = theme;
    this.timeScale = timeScale;
  }
  // Based on the formatter function, get the label text and position
  /**
   * @param {any[]} labels
   * @param {Array<Record<string, any>>} timescaleLabels
   * @param {number} x
   * @param {number} i
   * @param {any[]} drawnLabels
   */
  getLabel(labels, timescaleLabels, x, i, drawnLabels = [], fontSize = "12px", isLeafGroup = true) {
    const w = this.w;
    const rawLabel = typeof labels[i] === "undefined" ? "" : labels[i];
    let label = rawLabel;
    const xlbFormatter = w.formatters.xLabelFormatter;
    const customFormatter = w.config.xaxis.labels.formatter;
    let isBold = false;
    const xFormat = new Formatters(this.w);
    const timestamp = rawLabel;
    if (isLeafGroup) {
      label = /** @type {any} */
      xFormat.xLabelFormat(
        xlbFormatter,
        rawLabel,
        timestamp,
        {
          i,
          dateFormatter: new DateTime(this.w).formatDate,
          w
        }
      );
      if (customFormatter !== void 0) {
        label = customFormatter(rawLabel, labels[i], {
          i,
          dateFormatter: new DateTime(this.w).formatDate,
          w
        });
      }
    }
    const determineHighestUnit = (unit) => {
      let highestUnit = null;
      timescaleLabels.forEach((t) => {
        if (t.unit === "month") {
          highestUnit = "year";
        } else if (t.unit === "day") {
          highestUnit = "month";
        } else if (t.unit === "hour") {
          highestUnit = "day";
        } else if (t.unit === "minute") {
          highestUnit = "hour";
        }
      });
      return highestUnit === unit;
    };
    if (timescaleLabels.length > 0) {
      isBold = determineHighestUnit(timescaleLabels[i].unit);
      x = timescaleLabels[i].position;
      label = timescaleLabels[i].value;
    } else {
      if (w.config.xaxis.type === "datetime" && customFormatter === void 0) {
        label = "";
      }
    }
    if (typeof label === "undefined") label = "";
    label = Array.isArray(label) ? label : label.toString();
    const graphics = new Graphics(this.w);
    let textRect = {};
    if (w.layout.rotateXLabels && isLeafGroup) {
      textRect = graphics.getTextRects(
        label,
        parseInt(fontSize, 10).toString(),
        null,
        `rotate(${w.config.xaxis.labels.rotate} 0 0)`,
        false
      );
    } else {
      textRect = graphics.getTextRects(label, parseInt(fontSize, 10).toString());
    }
    const allowDuplicatesInTimeScale = !w.config.xaxis.labels.showDuplicates && this.timeScale;
    if (!Array.isArray(label) && (String(label) === "NaN" || drawnLabels.indexOf(label) >= 0 && allowDuplicatesInTimeScale)) {
      label = "";
    }
    return {
      x,
      text: label,
      textRect,
      isBold
    };
  }
  /**
   * @param {number} i
   * @param {any} label
   * @param {number} labelsLen
   */
  checkLabelBasedOnTickamount(i, label, labelsLen) {
    const w = this.w;
    let ticks = w.config.xaxis.tickAmount;
    if (ticks === "dataPoints") ticks = Math.round(w.layout.gridWidth / 120);
    if (ticks > labelsLen) return label;
    const tickMultiple = Math.round(labelsLen / (ticks + 1));
    if (i % tickMultiple === 0) {
      return label;
    } else {
      label.text = "";
    }
    return label;
  }
  /**
   * @param {number} i
   * @param {any} label
   * @param {number} labelsLen
   * @param {any[]} drawnLabels
   * @param {Array<Record<string, any>>} drawnLabelsRects
   */
  checkForOverflowingLabels(i, label, labelsLen, drawnLabels, drawnLabelsRects) {
    const w = this.w;
    if (i === 0) {
      if (w.globals.skipFirstTimelinelabel) {
        label.text = "";
      }
    }
    if (i === labelsLen - 1) {
      if (w.globals.skipLastTimelinelabel) {
        label.text = "";
      }
    }
    if (w.config.xaxis.labels.hideOverlappingLabels && drawnLabels.length > 0) {
      const prev = drawnLabelsRects[drawnLabelsRects.length - 1];
      if (w.config.xaxis.labels.trim && w.config.xaxis.type !== "datetime") {
        return label;
      }
      if (
        /** @type {any} */
        label.x < prev.textRect.width / (w.layout.rotateXLabels ? Math.abs(w.config.xaxis.labels.rotate) / 12 : 1.01) + prev.x
      ) {
        label.text = "";
      }
    }
    return label;
  }
  /**
   * @param {number} i
   * @param {any[]} labels
   */
  checkForReversedLabels(i, labels) {
    const w = this.w;
    if (w.config.yaxis[i] && w.config.yaxis[i].reversed) {
      labels.reverse();
    }
    return labels;
  }
  /**
   * @param {number} index
   */
  yAxisAllSeriesCollapsed(index) {
    const gl = this.w.globals;
    return !gl.seriesYAxisMap[index].some((si) => {
      return gl.collapsedSeriesIndices.indexOf(si) === -1;
    });
  }
  // Method to translate annotation.yAxisIndex values from
  // seriesName-as-a-string values to seriesName-as-an-array values (old style
  // series mapping to new style).
  /**
   * @param {number} index
   */
  translateYAxisIndex(index) {
    const w = this.w;
    const gl = w.globals;
    const yaxis = w.config.yaxis;
    const newStyle = w.seriesData.series.length > yaxis.length || /**
     * @param {Record<string, any>} a
     */
    yaxis.some((a) => Array.isArray(a.seriesName));
    if (newStyle) {
      return index;
    } else {
      return gl.seriesYAxisReverseMap[index];
    }
  }
  /**
   * @param {number} index
   */
  isYAxisHidden(index) {
    const w = this.w;
    const yaxis = w.config.yaxis[index];
    if (!yaxis.show || this.yAxisAllSeriesCollapsed(index)) {
      return true;
    }
    if (!yaxis.showForNullSeries) {
      const seriesIndices = w.globals.seriesYAxisMap[index];
      const coreUtils = new CoreUtils(this.w);
      return seriesIndices.every((si) => coreUtils.isSeriesNull(si));
    }
    return false;
  }
  // get the label color for y-axis
  // realIndex is the actual series index, while i is the tick Index
  /**
   * @param {string[]} yColors
   * @param {number} realIndex
   */
  getYAxisForeColor(yColors, realIndex) {
    var _a;
    const w = this.w;
    if (Array.isArray(yColors) && w.globals.yAxisScale[realIndex]) {
      (_a = this.theme) == null ? void 0 : _a.pushExtraColors(
        yColors,
        w.globals.yAxisScale[realIndex].result.length,
        false
      );
    }
    return yColors;
  }
  /**
   * @param {number} x
   * @param {number} tickAmount
   * @param {Record<string, any>} axisBorder
   * @param {Record<string, any>} axisTicks
   * @param {number} realIndex
   * @param {any} labelsDivider
   * @param {any} elYaxis
   */
  drawYAxisTicks(x, tickAmount, axisBorder, axisTicks, realIndex, labelsDivider, elYaxis) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    let tY = w.layout.translateY + w.config.yaxis[realIndex].labels.offsetY;
    if (w.globals.isBarHorizontal) {
      tY = 0;
    } else if (w.config.chart.type === "heatmap") {
      tY += labelsDivider / 2;
    }
    if (axisTicks.show && tickAmount > 0) {
      if (w.config.yaxis[realIndex].opposite === true) x = x + axisTicks.width;
      for (let i = tickAmount; i >= 0; i--) {
        const elTick = graphics.drawLine(
          x + axisBorder.offsetX - axisTicks.width + axisTicks.offsetX,
          tY + axisTicks.offsetY,
          x + axisBorder.offsetX + axisTicks.offsetX,
          tY + axisTicks.offsetY,
          axisTicks.color
        );
        elYaxis.add(elTick);
        tY += labelsDivider;
      }
    }
  }
}
class XAxis {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   * @param {import('../../types/internal').ChartContext} ctx
   * @param {any} [elgrid]
   */
  constructor(w, ctx, elgrid) {
    this.w = w;
    this.ctx = ctx;
    this.elgrid = elgrid;
    this.axesUtils = new AxesUtils(w, {
      theme: ctx.theme,
      timeScale: ctx.timeScale
    });
    this.xaxisLabels = w.labelData.labels.slice();
    if (w.labelData.timescaleLabels.length > 0 && !w.globals.isBarHorizontal) {
      this.xaxisLabels = w.labelData.timescaleLabels.slice();
    }
    if (w.config.xaxis.overwriteCategories) {
      this.xaxisLabels = w.config.xaxis.overwriteCategories;
    }
    this.drawnLabels = [];
    this.drawnLabelsRects = [];
    if (w.config.xaxis.position === "top") {
      this.offY = 0;
    } else {
      this.offY = w.layout.gridHeight;
    }
    this.offY = this.offY + w.config.xaxis.axisBorder.offsetY;
    this.isCategoryBarHorizontal = w.config.chart.type === "bar" && w.config.plotOptions.bar.horizontal;
    this.xaxisFontSize = w.config.xaxis.labels.style.fontSize;
    this.xaxisFontFamily = w.config.xaxis.labels.style.fontFamily;
    this.xaxisForeColors = w.config.xaxis.labels.style.colors;
    this.xaxisBorderWidth = w.config.xaxis.axisBorder.width;
    if (this.isCategoryBarHorizontal) {
      this.xaxisBorderWidth = w.config.yaxis[0].axisBorder.width.toString();
    }
    if (String(this.xaxisBorderWidth).indexOf("%") > -1) {
      this.xaxisBorderWidth = w.layout.gridWidth * parseInt(this.xaxisBorderWidth, 10) / 100;
    } else {
      this.xaxisBorderWidth = parseInt(this.xaxisBorderWidth, 10);
    }
    this.xaxisBorderHeight = w.config.xaxis.axisBorder.height;
    this.yaxis = w.config.yaxis[0];
  }
  drawXaxis() {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const elXaxis = graphics.group({
      class: "apexcharts-xaxis",
      transform: `translate(${w.config.xaxis.offsetX}, ${w.config.xaxis.offsetY})`
    });
    const elXaxisTexts = graphics.group({
      class: "apexcharts-xaxis-texts-g",
      transform: `translate(${w.layout.translateXAxisX}, ${w.layout.translateXAxisY})`
    });
    elXaxis.add(elXaxisTexts);
    let labels = [];
    for (let i = 0; i < this.xaxisLabels.length; i++) {
      labels.push(this.xaxisLabels[i]);
    }
    this.drawXAxisLabelAndGroup(
      true,
      graphics,
      elXaxisTexts,
      labels,
      w.axisFlags.isXNumeric,
      (i, colWidth) => colWidth
    );
    if (w.labelData.hasXaxisGroups) {
      const labelsGroup = w.labelData.groups;
      labels = [];
      for (let i = 0; i < labelsGroup.length; i++) {
        labels.push(labelsGroup[i].title);
      }
      const overwriteStyles = (
        /** @type {any} */
        {}
      );
      if (w.config.xaxis.group.style) {
        overwriteStyles.xaxisFontSize = w.config.xaxis.group.style.fontSize;
        overwriteStyles.xaxisFontFamily = w.config.xaxis.group.style.fontFamily;
        overwriteStyles.xaxisForeColors = w.config.xaxis.group.style.colors;
        overwriteStyles.fontWeight = w.config.xaxis.group.style.fontWeight;
        overwriteStyles.cssClass = w.config.xaxis.group.style.cssClass;
      }
      this.drawXAxisLabelAndGroup(
        false,
        graphics,
        elXaxisTexts,
        labels,
        false,
        (i, colWidth) => labelsGroup[i].cols * colWidth,
        overwriteStyles
      );
    }
    if (w.config.xaxis.title.text !== void 0) {
      const elXaxisTitle = graphics.group({
        class: "apexcharts-xaxis-title"
      });
      const elXAxisTitleText = graphics.drawText({
        x: w.layout.gridWidth / 2 + w.config.xaxis.title.offsetX,
        y: this.offY + parseFloat(this.xaxisFontSize) + (w.config.xaxis.position === "bottom" ? w.layout.xAxisLabelsHeight : -w.layout.xAxisLabelsHeight - 10) + w.config.xaxis.title.offsetY,
        text: w.config.xaxis.title.text,
        textAnchor: "middle",
        fontSize: w.config.xaxis.title.style.fontSize,
        fontFamily: w.config.xaxis.title.style.fontFamily,
        fontWeight: w.config.xaxis.title.style.fontWeight,
        foreColor: w.config.xaxis.title.style.color,
        cssClass: "apexcharts-xaxis-title-text " + w.config.xaxis.title.style.cssClass
      });
      elXaxisTitle.add(elXAxisTitleText);
      elXaxis.add(elXaxisTitle);
    }
    if (w.config.xaxis.axisBorder.show) {
      const offX = w.globals.barPadForNumericAxis;
      const elHorzLine = graphics.drawLine(
        w.globals.padHorizontal + w.config.xaxis.axisBorder.offsetX - offX,
        this.offY,
        this.xaxisBorderWidth + offX,
        this.offY,
        w.config.xaxis.axisBorder.color,
        0,
        this.xaxisBorderHeight
      );
      if (this.elgrid && this.elgrid.elGridBorders && w.config.grid.show) {
        this.elgrid.elGridBorders.add(elHorzLine);
      } else {
        elXaxis.add(elHorzLine);
      }
    }
    return elXaxis;
  }
  /**
   * @param {Record<string, any>} [overwriteStyles]
   * @param {boolean} isLeafGroup
   * @param {import('../Graphics').default} graphics
   * @param {any} elXaxisTexts
   * @param {any[]} labels
   * @param {boolean} isXNumeric
   * @param {any} colWidthCb
   */
  drawXAxisLabelAndGroup(isLeafGroup, graphics, elXaxisTexts, labels, isXNumeric, colWidthCb, overwriteStyles = {}) {
    const drawnLabels = [];
    const drawnLabelsRects = [];
    const w = this.w;
    const xaxisFontSize = overwriteStyles.xaxisFontSize || this.xaxisFontSize;
    const xaxisFontFamily = overwriteStyles.xaxisFontFamily || this.xaxisFontFamily;
    const xaxisForeColors = overwriteStyles.xaxisForeColors || this.xaxisForeColors;
    const fontWeight = overwriteStyles.fontWeight || w.config.xaxis.labels.style.fontWeight;
    const cssClass = overwriteStyles.cssClass || w.config.xaxis.labels.style.cssClass;
    let colWidth;
    let xPos = w.globals.padHorizontal;
    const labelsLen = labels.length;
    let dataPoints = w.config.xaxis.type === "category" ? w.globals.dataPoints : labelsLen;
    if (dataPoints === 0 && labelsLen > dataPoints) dataPoints = labelsLen;
    if (isXNumeric) {
      const len = Math.max(
        Number(w.config.xaxis.tickAmount) || 1,
        dataPoints > 1 ? dataPoints - 1 : dataPoints
      );
      colWidth = w.layout.gridWidth / Math.min(len, labelsLen - 1);
      xPos = xPos + colWidthCb(0, colWidth) / 2 + w.config.xaxis.labels.offsetX;
    } else {
      colWidth = w.layout.gridWidth / dataPoints;
      xPos = xPos + colWidthCb(0, colWidth) + w.config.xaxis.labels.offsetX;
    }
    for (let i = 0; i <= labelsLen - 1; i++) {
      let x = xPos - colWidthCb(i, colWidth) / 2 + w.config.xaxis.labels.offsetX;
      if (i === 0 && labelsLen === 1 && colWidth / 2 === xPos && dataPoints === 1) {
        x = w.layout.gridWidth / 2;
      }
      let label = this.axesUtils.getLabel(
        labels,
        w.labelData.timescaleLabels,
        x,
        i,
        drawnLabels,
        xaxisFontSize,
        isLeafGroup
      );
      let offsetYCorrection = 28;
      if (w.layout.rotateXLabels && isLeafGroup) {
        offsetYCorrection = 22;
      }
      if (w.config.xaxis.title.text && w.config.xaxis.position === "top") {
        offsetYCorrection += parseFloat(w.config.xaxis.title.style.fontSize) + 2;
      }
      if (!isLeafGroup) {
        offsetYCorrection = offsetYCorrection + parseFloat(xaxisFontSize) + (w.layout.xAxisLabelsHeight - w.layout.xAxisGroupLabelsHeight) + (w.layout.rotateXLabels ? 10 : 0);
      }
      const isCategoryTickAmounts = typeof w.config.xaxis.tickAmount !== "undefined" && w.config.xaxis.tickAmount !== "dataPoints" && w.config.xaxis.type !== "datetime";
      if (isCategoryTickAmounts) {
        label = this.axesUtils.checkLabelBasedOnTickamount(i, label, labelsLen);
      } else {
        label = this.axesUtils.checkForOverflowingLabels(
          i,
          label,
          labelsLen,
          drawnLabels,
          drawnLabelsRects
        );
      }
      const getCatForeColor = () => {
        return isLeafGroup && w.config.xaxis.convertedCatToNumeric ? xaxisForeColors[w.globals.minX + i - 1] : xaxisForeColors[i];
      };
      if (w.config.xaxis.labels.show) {
        const elText = graphics.drawText({
          x: label.x,
          y: this.offY + w.config.xaxis.labels.offsetY + offsetYCorrection - (w.config.xaxis.position === "top" ? w.layout.xAxisHeight + w.config.xaxis.axisTicks.height - 2 : 0),
          text: label.text,
          textAnchor: "middle",
          fontWeight: label.isBold ? 600 : fontWeight,
          fontSize: xaxisFontSize,
          fontFamily: xaxisFontFamily,
          foreColor: Array.isArray(xaxisForeColors) ? getCatForeColor() : xaxisForeColors,
          isPlainText: false,
          cssClass: (isLeafGroup ? "apexcharts-xaxis-label " : "apexcharts-xaxis-group-label ") + cssClass
        });
        elXaxisTexts.add(elText);
        elText.on("click", (e) => {
          if (typeof w.config.chart.events.xAxisLabelClick === "function") {
            const opts = Object.assign({}, w, {
              labelIndex: i
            });
            w.config.chart.events.xAxisLabelClick(e, this.ctx, opts);
          }
        });
        if (isLeafGroup) {
          const elTooltipTitle = BrowserAPIs.createElementNS(SVGNS, "title");
          elTooltipTitle.textContent = Array.isArray(label.text) ? label.text.join(" ") : label.text;
          elText.node.appendChild(elTooltipTitle);
          if (label.text !== "") {
            drawnLabels.push(label.text);
            drawnLabelsRects.push(label);
          }
        }
      }
      if (i < labelsLen - 1) {
        xPos = xPos + colWidthCb(i + 1, colWidth);
      }
    }
  }
  // this actually becomes the vertical axis (for bar charts)
  /**
   * @param {number} realIndex
   */
  drawXaxisInversed(realIndex) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const translateYAxisX = w.config.yaxis[0].opposite ? w.globals.translateYAxisX[realIndex] : 0;
    const elYaxis = graphics.group({
      class: "apexcharts-yaxis apexcharts-xaxis-inversed",
      rel: realIndex
    });
    const elYaxisTexts = graphics.group({
      class: "apexcharts-yaxis-texts-g apexcharts-xaxis-inversed-texts-g",
      transform: "translate(" + translateYAxisX + ", 0)"
    });
    elYaxis.add(elYaxisTexts);
    const labels = [];
    if (w.config.yaxis[realIndex].show) {
      for (let i = 0; i < this.xaxisLabels.length; i++) {
        labels.push(this.xaxisLabels[i]);
      }
    }
    const colHeight = w.layout.gridHeight / labels.length;
    let yPos = -(colHeight / 2.2);
    const lbFormatter = w.formatters.yLabelFormatters[0];
    const ylabels = w.config.yaxis[0].labels;
    if (ylabels.show) {
      for (let i = 0; i <= labels.length - 1; i++) {
        let label = typeof labels[i] === "undefined" ? "" : labels[i];
        label = lbFormatter(label, {
          seriesIndex: realIndex,
          dataPointIndex: i,
          w
        });
        const yColors = this.axesUtils.getYAxisForeColor(
          ylabels.style.colors,
          realIndex
        );
        const getForeColor = () => {
          return Array.isArray(yColors) ? yColors[i] : yColors;
        };
        let multiY = 0;
        if (Array.isArray(label)) {
          multiY = label.length / 2 * parseInt(ylabels.style.fontSize, 10);
        }
        let offsetX = ylabels.offsetX - 15;
        let textAnchor = "end";
        if (this.yaxis.opposite) {
          textAnchor = "start";
        }
        if (w.config.yaxis[0].labels.align === "left") {
          offsetX = ylabels.offsetX;
          textAnchor = "start";
        } else if (w.config.yaxis[0].labels.align === "center") {
          offsetX = ylabels.offsetX;
          textAnchor = "middle";
        } else if (w.config.yaxis[0].labels.align === "right") {
          textAnchor = "end";
        }
        const elLabel = graphics.drawText({
          x: offsetX,
          y: yPos + colHeight + ylabels.offsetY - multiY,
          text: label,
          textAnchor,
          foreColor: getForeColor(),
          fontSize: ylabels.style.fontSize,
          fontFamily: ylabels.style.fontFamily,
          fontWeight: ylabels.style.fontWeight,
          isPlainText: false,
          cssClass: "apexcharts-yaxis-label " + ylabels.style.cssClass,
          maxWidth: ylabels.maxWidth
        });
        elYaxisTexts.add(elLabel);
        elLabel.on("click", (e) => {
          if (typeof w.config.chart.events.xAxisLabelClick === "function") {
            const opts = Object.assign({}, w, {
              labelIndex: i
            });
            w.config.chart.events.xAxisLabelClick(e, this.ctx, opts);
          }
        });
        const elTooltipTitle = BrowserAPIs.createElementNS(SVGNS, "title");
        elTooltipTitle.textContent = Array.isArray(label) ? label.join(" ") : label;
        elLabel.node.appendChild(elTooltipTitle);
        if (w.config.yaxis[realIndex].labels.rotate !== 0) {
          const labelRotatingCenter = graphics.rotateAroundCenter(elLabel.node);
          elLabel.node.setAttribute(
            "transform",
            `rotate(${w.config.yaxis[realIndex].labels.rotate} 0 ${labelRotatingCenter.y})`
          );
        }
        yPos = yPos + colHeight;
      }
    }
    if (w.config.yaxis[0].title.text !== void 0) {
      const elXaxisTitle = graphics.group({
        class: "apexcharts-yaxis-title apexcharts-xaxis-title-inversed",
        transform: "translate(" + translateYAxisX + ", 0)"
      });
      const elXAxisTitleText = graphics.drawText({
        x: w.config.yaxis[0].title.offsetX,
        y: w.layout.gridHeight / 2 + w.config.yaxis[0].title.offsetY,
        text: w.config.yaxis[0].title.text,
        textAnchor: "middle",
        foreColor: w.config.yaxis[0].title.style.color,
        fontSize: w.config.yaxis[0].title.style.fontSize,
        fontWeight: w.config.yaxis[0].title.style.fontWeight,
        fontFamily: w.config.yaxis[0].title.style.fontFamily,
        cssClass: "apexcharts-yaxis-title-text " + w.config.yaxis[0].title.style.cssClass
      });
      elXaxisTitle.add(elXAxisTitleText);
      elYaxis.add(elXaxisTitle);
    }
    let offX = 0;
    if (this.isCategoryBarHorizontal && w.config.yaxis[0].opposite) {
      offX = w.layout.gridWidth;
    }
    const axisBorder = w.config.xaxis.axisBorder;
    if (axisBorder.show) {
      const elVerticalLine = graphics.drawLine(
        w.globals.padHorizontal + axisBorder.offsetX + offX,
        1 + axisBorder.offsetY,
        w.globals.padHorizontal + axisBorder.offsetX + offX,
        w.layout.gridHeight + axisBorder.offsetY,
        axisBorder.color,
        0
      );
      if (this.elgrid && this.elgrid.elGridBorders && w.config.grid.show) {
        this.elgrid.elGridBorders.add(elVerticalLine);
      } else {
        elYaxis.add(elVerticalLine);
      }
    }
    if (w.config.yaxis[0].axisTicks.show) {
      this.axesUtils.drawYAxisTicks(
        offX,
        labels.length,
        w.config.yaxis[0].axisBorder,
        w.config.yaxis[0].axisTicks,
        0,
        colHeight,
        elYaxis
      );
    }
    return elYaxis;
  }
  /**
   * @param {number} x1
   * @param {number} y2
   * @param {any} appendToElement
   */
  drawXaxisTicks(x1, y2, appendToElement) {
    const w = this.w;
    const x2 = x1;
    if (x1 < 0 || x1 - 2 > w.layout.gridWidth) return;
    const y1 = this.offY + w.config.xaxis.axisTicks.offsetY;
    y2 = y2 + y1 + w.config.xaxis.axisTicks.height;
    if (w.config.xaxis.position === "top") {
      y2 = y1 - w.config.xaxis.axisTicks.height;
    }
    if (w.config.xaxis.axisTicks.show) {
      const graphics = new Graphics(this.w);
      const line = graphics.drawLine(
        x1 + w.config.xaxis.axisTicks.offsetX,
        y1 + w.config.xaxis.offsetY,
        x2 + w.config.xaxis.axisTicks.offsetX,
        y2 + w.config.xaxis.offsetY,
        w.config.xaxis.axisTicks.color
      );
      appendToElement.add(line);
      line.node.classList.add("apexcharts-xaxis-tick");
    }
  }
  getXAxisTicksPositions() {
    const w = this.w;
    const xAxisTicksPositions = [];
    const xCount = this.xaxisLabels.length;
    let x1 = w.globals.padHorizontal;
    if (w.labelData.timescaleLabels.length > 0) {
      for (let i = 0; i < xCount; i++) {
        x1 = this.xaxisLabels[i].position;
        xAxisTicksPositions.push(x1);
      }
    } else {
      const xCountForCategoryCharts = xCount;
      for (let i = 0; i < xCountForCategoryCharts; i++) {
        let x1Count = xCountForCategoryCharts;
        if (w.axisFlags.isXNumeric && w.config.chart.type !== "bar") {
          x1Count -= 1;
        }
        x1 = x1 + w.layout.gridWidth / x1Count;
        xAxisTicksPositions.push(x1);
      }
    }
    return xAxisTicksPositions;
  }
  // to rotate x-axis labels or to put ... for longer text in xaxis
  xAxisLabelCorrections() {
    var _a, _b, _c;
    const w = this.w;
    const graphics = new Graphics(this.w);
    const xAxis = w.dom.baseEl.querySelector(".apexcharts-xaxis-texts-g");
    const xAxisTexts = w.dom.baseEl.querySelectorAll(
      ".apexcharts-xaxis-texts-g text:not(.apexcharts-xaxis-group-label)"
    );
    const yAxisTextsInversed = w.dom.baseEl.querySelectorAll(
      ".apexcharts-yaxis-inversed text"
    );
    const xAxisTextsInversed = w.dom.baseEl.querySelectorAll(
      ".apexcharts-xaxis-inversed-texts-g text tspan"
    );
    if (w.layout.rotateXLabels || w.config.xaxis.labels.rotateAlways) {
      for (let xat = 0; xat < xAxisTexts.length; xat++) {
        const textRotatingCenter = graphics.rotateAroundCenter(xAxisTexts[xat]);
        textRotatingCenter.y = textRotatingCenter.y - 1;
        textRotatingCenter.x = textRotatingCenter.x + 1;
        xAxisTexts[xat].setAttribute(
          "transform",
          `rotate(${w.config.xaxis.labels.rotate} ${textRotatingCenter.x} ${textRotatingCenter.y})`
        );
        xAxisTexts[xat].setAttribute("text-anchor", `end`);
        xAxis == null ? void 0 : xAxis.setAttribute("transform", `translate(0, ${-10})`);
        const tSpan = xAxisTexts[xat].childNodes;
        if (w.config.xaxis.labels.trim) {
          Array.prototype.forEach.call(tSpan, (ts) => {
            graphics.placeTextWithEllipsis(
              ts,
              ts.textContent,
              w.layout.xAxisLabelsHeight - (w.config.legend.position === "bottom" ? 20 : 10)
            );
          });
        }
      }
    } else {
      const width = w.layout.gridWidth / (w.labelData.labels.length + 1);
      for (let xat = 0; xat < xAxisTexts.length; xat++) {
        const tSpan = xAxisTexts[xat].childNodes;
        if (w.config.xaxis.labels.trim && w.config.xaxis.type !== "datetime") {
          Array.prototype.forEach.call(tSpan, (ts) => {
            graphics.placeTextWithEllipsis(ts, ts.textContent, width);
          });
        }
      }
    }
    if (yAxisTextsInversed.length > 0) {
      const firstLabelPosX = (
        /** @type {SVGGraphicsElement} */
        yAxisTextsInversed[yAxisTextsInversed.length - 1].getBBox()
      );
      const lastLabelPosX = (
        /** @type {SVGGraphicsElement} */
        yAxisTextsInversed[0].getBBox()
      );
      if (firstLabelPosX.x < -20) {
        (_a = yAxisTextsInversed[yAxisTextsInversed.length - 1].parentNode) == null ? void 0 : _a.removeChild(
          yAxisTextsInversed[yAxisTextsInversed.length - 1]
        );
      }
      if (lastLabelPosX.x + lastLabelPosX.width > w.layout.gridWidth && !w.globals.isBarHorizontal) {
        (_b = yAxisTextsInversed[0].parentNode) == null ? void 0 : _b.removeChild(yAxisTextsInversed[0]);
      }
      for (let xat = 0; xat < xAxisTextsInversed.length; xat++) {
        graphics.placeTextWithEllipsis(
          xAxisTextsInversed[xat],
          (_c = xAxisTextsInversed[xat].textContent) != null ? _c : "",
          w.config.yaxis[0].labels.maxWidth - (w.config.yaxis[0].title.text ? parseFloat(w.config.yaxis[0].title.style.fontSize) * 2 : 0) - 15
        );
      }
    }
  }
  // renderXAxisBands() {
  //   let w = this.w;
  //   let plotBand = document.createElementNS(SVGNS, 'rect')
  //   w.dom.elGraphical.add(plotBand)
  // }
}
class Grid {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   * @param {import('../../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
    this.xaxisLabels = w.labelData.labels.slice();
    this.axesUtils = new AxesUtils(ctx.w, {
      theme: ctx.theme,
      timeScale: ctx.timeScale
    });
    this.isRangeBar = w.rangeData.seriesRange.length && w.globals.isBarHorizontal;
    if (w.labelData.timescaleLabels.length > 0) {
      this.xaxisLabels = w.labelData.timescaleLabels.slice();
    }
  }
  /**
   * @param {any} elGrid
   */
  drawGridArea(elGrid = null) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    if (!elGrid) {
      elGrid = graphics.group({ class: "apexcharts-grid" });
    }
    const elVerticalLine = graphics.drawLine(
      w.globals.padHorizontal,
      1,
      w.globals.padHorizontal,
      w.layout.gridHeight,
      "transparent"
    );
    const elHorzLine = graphics.drawLine(
      w.globals.padHorizontal,
      w.layout.gridHeight,
      w.layout.gridWidth,
      w.layout.gridHeight,
      "transparent"
    );
    elGrid.add(elHorzLine);
    elGrid.add(elVerticalLine);
    return elGrid;
  }
  drawGrid() {
    const gl = this.w.globals;
    if (gl.axisCharts) {
      const elgrid = this.renderGrid();
      this.drawGridArea(elgrid.el);
      return elgrid;
    }
    return null;
  }
  createGridMask() {
    const w = this.w;
    const gl = w.globals;
    const graphics = new Graphics(this.w);
    const strokeSize = Array.isArray(w.config.stroke.width) ? Math.max(...w.config.stroke.width) : w.config.stroke.width;
    const createClipPath = (id) => {
      const clipPath = BrowserAPIs.createElementNS(SVGNS, "clipPath");
      clipPath.setAttribute("id", id);
      return clipPath;
    };
    w.dom.elGridRectMask = createClipPath(`gridRectMask${gl.cuid}`);
    w.dom.elGridRectBarMask = createClipPath(`gridRectBarMask${gl.cuid}`);
    w.dom.elGridRectMarkerMask = createClipPath(`gridRectMarkerMask${gl.cuid}`);
    w.dom.elForecastMask = createClipPath(`forecastMask${gl.cuid}`);
    w.dom.elNonForecastMask = createClipPath(`nonForecastMask${gl.cuid}`);
    const hasBar = ["bar", "rangeBar", "candlestick", "boxPlot"].includes(
      w.config.chart.type
    ) || w.globals.comboBarCount > 0;
    let barWidthLeft = 0;
    let barWidthRight = 0;
    if (hasBar && w.axisFlags.isXNumeric && !w.globals.isBarHorizontal) {
      barWidthLeft = Math.max(
        w.config.grid.padding.left,
        gl.barPadForNumericAxis
      );
      barWidthRight = Math.max(
        w.config.grid.padding.right,
        gl.barPadForNumericAxis
      );
    }
    w.dom.elGridRect = graphics.drawRect(
      -strokeSize / 2 - 2,
      -strokeSize / 2 - 2,
      w.layout.gridWidth + strokeSize + 4,
      w.layout.gridHeight + strokeSize + 4,
      0,
      "#fff"
    );
    w.dom.elGridRectBar = graphics.drawRect(
      -strokeSize / 2 - barWidthLeft - 2,
      -strokeSize / 2 - 2,
      w.layout.gridWidth + strokeSize + barWidthRight + barWidthLeft + 4,
      w.layout.gridHeight + strokeSize + 4,
      0,
      "#fff"
    );
    const markerSize = w.globals.markers.largestSize;
    w.dom.elGridRectMarker = graphics.drawRect(
      Math.min(-strokeSize / 2 - barWidthLeft - 2, -markerSize),
      -markerSize,
      w.layout.gridWidth + Math.max(strokeSize + barWidthRight + barWidthLeft + 4, markerSize * 2),
      w.layout.gridHeight + markerSize * 2,
      0,
      "#fff"
    );
    w.dom.elGridRectMask.appendChild(w.dom.elGridRect.node);
    w.dom.elGridRectBarMask.appendChild(w.dom.elGridRectBar.node);
    w.dom.elGridRectMarkerMask.appendChild(w.dom.elGridRectMarker.node);
    const defs = w.dom.elDefs.node;
    defs.appendChild(w.dom.elGridRectMask);
    defs.appendChild(w.dom.elGridRectBarMask);
    defs.appendChild(w.dom.elGridRectMarkerMask);
    defs.appendChild(w.dom.elForecastMask);
    defs.appendChild(w.dom.elNonForecastMask);
  }
  /** @param {{i: any, x1: any, y1: any, x2: any, y2: any, xCount: any, parent: any}} opts */
  _drawGridLines({ i, x1, y1, x2, y2, xCount, parent }) {
    const w = this.w;
    const shouldDraw = () => {
      if (i === 0 && w.globals.skipFirstTimelinelabel) return false;
      if (i === xCount - 1 && w.globals.skipLastTimelinelabel && !w.config.xaxis.labels.formatter)
        return false;
      if (w.config.chart.type === "radar") return false;
      return true;
    };
    if (shouldDraw()) {
      if (w.config.grid.xaxis.lines.show) {
        this._drawGridLine({ i, x1, y1, x2, y2, xCount, parent });
      }
      let y_2 = 0;
      if (w.labelData.hasXaxisGroups && w.config.xaxis.tickPlacement === "between") {
        const groups = w.labelData.groups;
        if (groups) {
          let gacc = 0;
          for (let gi = 0; gacc < i && gi < groups.length; gi++) {
            gacc += groups[gi].cols;
          }
          if (gacc === i) {
            y_2 = w.layout.xAxisLabelsHeight * 0.6;
          }
        }
      }
      const xAxis = new XAxis(this.w, this.ctx);
      xAxis.drawXaxisTicks(x1, y_2, w.dom.elGraphical);
    }
  }
  /** @param {{i: any, x1: any, y1: any, x2: any, y2: any, xCount: any, parent: any}} opts */
  _drawGridLine({ i, x1, y1, x2, y2, xCount, parent }) {
    const w = this.w;
    const isHorzLine = parent.node.classList.contains(
      "apexcharts-gridlines-horizontal"
    );
    const offX = w.globals.barPadForNumericAxis;
    const excludeBorders = y1 === 0 && y2 === 0 || x1 === 0 && x2 === 0 || y1 === w.layout.gridHeight && y2 === w.layout.gridHeight || w.globals.isBarHorizontal && (i === 0 || i === xCount - 1);
    const graphics = new Graphics(this.w);
    const line = graphics.drawLine(
      x1 - (isHorzLine ? offX : 0),
      y1,
      x2 + (isHorzLine ? offX : 0),
      y2,
      w.config.grid.borderColor,
      w.config.grid.strokeDashArray
    );
    line.node.classList.add("apexcharts-gridline");
    if (excludeBorders && w.config.grid.show) {
      this.elGridBorders.add(line);
    } else {
      parent.add(line);
    }
  }
  /** @param {{c: any, x1: any, y1: any, x2: any, y2: any, type: any}} opts */
  _drawGridBandRect({ c, x1, y1, x2, y2, type }) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const offX = w.globals.barPadForNumericAxis;
    const color = w.config.grid[type].colors[c];
    const rect = graphics.drawRect(
      x1 - (type === "row" ? offX : 0),
      y1,
      x2 + (type === "row" ? offX * 2 : 0),
      y2,
      0,
      color,
      w.config.grid[type].opacity
    );
    this.elg.add(rect);
    rect.attr("clip-path", `url(#gridRectMask${w.globals.cuid})`);
    rect.node.classList.add(`apexcharts-grid-${type}`);
  }
  /** @param {{xCount: any, tickAmount: any}} opts */
  _drawXYLines({ xCount, tickAmount }) {
    var _a;
    const w = this.w;
    const datetimeLines = ({ xC, x1, y1, x2, y2 }) => {
      for (let i = 0; i < xC; i++) {
        x1 = /** @type {any} */
        this.xaxisLabels[i].position;
        x2 = /** @type {any} */
        this.xaxisLabels[i].position;
        this._drawGridLines({
          i,
          x1,
          y1,
          x2,
          y2,
          xCount,
          parent: this.elgridLinesV
        });
      }
    };
    const categoryLines = ({ xC, x1, y1, x2, y2 }) => {
      for (let i = 0; i < xC + (w.axisFlags.isXNumeric ? 0 : 1); i++) {
        if (i === 0 && xC === 1 && w.globals.dataPoints === 1) {
          x1 = w.layout.gridWidth / 2;
          x2 = x1;
        }
        this._drawGridLines({
          i,
          x1,
          y1,
          x2,
          y2,
          xCount,
          parent: this.elgridLinesV
        });
        x1 += w.layout.gridWidth / (w.axisFlags.isXNumeric ? xC - 1 : xC);
        x2 = x1;
      }
    };
    if (w.config.grid.xaxis.lines.show || w.config.xaxis.axisTicks.show) {
      const x1 = w.globals.padHorizontal;
      const y1 = 0;
      let x2;
      const y2 = w.layout.gridHeight;
      if (w.labelData.timescaleLabels.length) {
        datetimeLines({ xC: xCount, x1, y1, x2, y2 });
      } else {
        if (w.axisFlags.isXNumeric) {
          xCount = (_a = w.globals.xAxisScale) == null ? void 0 : _a.result.length;
        }
        categoryLines({ xC: xCount, x1, y1, x2, y2 });
      }
    }
    if (w.config.grid.yaxis.lines.show) {
      const x1 = 0;
      let y1 = 0;
      let y2 = 0;
      const x2 = w.layout.gridWidth;
      let tA = tickAmount + 1;
      if (this.isRangeBar) {
        tA = w.labelData.labels.length;
      }
      for (let i = 0; i < tA + (this.isRangeBar ? 1 : 0); i++) {
        this._drawGridLine({
          i,
          xCount: tA + (this.isRangeBar ? 1 : 0),
          x1,
          y1,
          x2,
          y2,
          parent: this.elgridLinesH
        });
        y1 += w.layout.gridHeight / (this.isRangeBar ? tA : tickAmount);
        y2 = y1;
      }
    }
  }
  /** @param {{ xCount?: any, tickAmount?: any }} opts */
  _drawInvertedXYLines({ xCount }) {
    const w = this.w;
    if (w.config.grid.xaxis.lines.show || w.config.xaxis.axisTicks.show) {
      let x1 = w.globals.padHorizontal;
      const y1 = 0;
      let x2;
      const y2 = w.layout.gridHeight;
      for (let i = 0; i < xCount + 1; i++) {
        if (w.config.grid.xaxis.lines.show) {
          this._drawGridLine({
            i,
            xCount: xCount + 1,
            x1,
            y1,
            x2,
            y2,
            parent: this.elgridLinesV
          });
        }
        const xAxis = new XAxis(this.w, this.ctx);
        xAxis.drawXaxisTicks(x1, 0, w.dom.elGraphical);
        x1 += w.layout.gridWidth / xCount;
        x2 = x1;
      }
    }
    if (w.config.grid.yaxis.lines.show) {
      const x1 = 0;
      let y1 = 0;
      let y2 = 0;
      const x2 = w.layout.gridWidth;
      for (let i = 0; i < w.globals.dataPoints + 1; i++) {
        this._drawGridLine({
          i,
          xCount: w.globals.dataPoints + 1,
          x1,
          y1,
          x2,
          y2,
          parent: this.elgridLinesH
        });
        y1 += w.layout.gridHeight / w.globals.dataPoints;
        y2 = y1;
      }
    }
  }
  renderGrid() {
    var _a, _b, _c;
    const w = this.w;
    const gl = w.globals;
    const graphics = new Graphics(this.w);
    this.elg = graphics.group({ class: "apexcharts-grid" });
    this.elgridLinesH = graphics.group({
      class: "apexcharts-gridlines-horizontal"
    });
    this.elgridLinesV = graphics.group({
      class: "apexcharts-gridlines-vertical"
    });
    this.elGridBorders = graphics.group({ class: "apexcharts-grid-borders" });
    this.elg.add(this.elgridLinesH);
    this.elg.add(this.elgridLinesV);
    if (!w.config.grid.show) {
      this.elgridLinesV.hide();
      this.elgridLinesH.hide();
      this.elGridBorders.hide();
    }
    let gridAxisIndex = 0;
    while (gridAxisIndex < gl.seriesYAxisMap.length && gl.ignoreYAxisIndexes.includes(gridAxisIndex)) {
      gridAxisIndex++;
    }
    if (gridAxisIndex === gl.seriesYAxisMap.length) {
      gridAxisIndex = 0;
    }
    let yTickAmount = gl.yAxisScale[gridAxisIndex].result.length - 1;
    let xCount;
    if (!gl.isBarHorizontal || this.isRangeBar) {
      xCount = this.xaxisLabels.length;
      if (this.isRangeBar) {
        yTickAmount = w.labelData.labels.length;
        if (w.config.xaxis.tickAmount && w.config.xaxis.labels.formatter) {
          xCount = w.config.xaxis.tickAmount;
        }
        if (((_c = (_b = (_a = gl.yAxisScale) == null ? void 0 : _a[gridAxisIndex]) == null ? void 0 : _b.result) == null ? void 0 : _c.length) > 0 && w.config.xaxis.type !== "datetime") {
          xCount = gl.yAxisScale[gridAxisIndex].result.length - 1;
        }
      }
      this._drawXYLines({ xCount, tickAmount: yTickAmount });
    } else {
      xCount = yTickAmount;
      yTickAmount = gl.xTickAmount;
      this._drawInvertedXYLines({ xCount, tickAmount: yTickAmount });
    }
    this.drawGridBands(xCount, yTickAmount);
    return {
      el: this.elg,
      elGridBorders: this.elGridBorders,
      xAxisTickWidth: w.layout.gridWidth / xCount
    };
  }
  /**
   * @param {number} xCount
   * @param {number} tickAmount
   */
  drawGridBands(xCount, tickAmount) {
    var _a, _b, _c, _d, _e;
    const w = this.w;
    const drawBands = (type, count, x1, y1, x2, y2) => {
      for (let i = 0, c = 0; i < count; i++, c++) {
        if (c >= w.config.grid[type].colors.length) {
          c = 0;
        }
        this._drawGridBandRect({ c, x1, y1, x2, y2, type });
        y1 += w.layout.gridHeight / tickAmount;
      }
    };
    if (((_a = w.config.grid.row.colors) == null ? void 0 : _a.length) > 0) {
      drawBands(
        "row",
        tickAmount,
        0,
        0,
        w.layout.gridWidth,
        w.layout.gridHeight / tickAmount
      );
    }
    if (((_b = w.config.grid.column.colors) == null ? void 0 : _b.length) > 0) {
      let xc = !w.globals.isBarHorizontal && w.config.xaxis.tickPlacement === "on" && (w.config.xaxis.type === "category" || w.config.xaxis.convertedCatToNumeric) ? xCount - 1 : xCount;
      if (w.axisFlags.isXNumeric) {
        xc = ((_d = (_c = w.globals.xAxisScale) == null ? void 0 : _c.result.length) != null ? _d : 1) - 1;
      }
      let x1 = w.globals.padHorizontal;
      const y1 = 0;
      let x2 = w.globals.padHorizontal + w.layout.gridWidth / xc;
      const y2 = w.layout.gridHeight;
      for (let i = 0, c = 0; i < xCount; i++, c++) {
        if (c >= w.config.grid.column.colors.length) {
          c = 0;
        }
        if (w.config.xaxis.type === "datetime") {
          x1 = /** @type {any} */
          this.xaxisLabels[i].position;
          x2 = /** @type {any} */
          (((_e = this.xaxisLabels[i + 1]) == null ? void 0 : _e.position) || w.layout.gridWidth) - /** @type {any} */
          this.xaxisLabels[i].position;
        }
        this._drawGridBandRect({ c, x1, y1, x2, y2, type: "column" });
        x1 += w.layout.gridWidth / xc;
      }
    }
  }
}
class Scales {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
    this.coreUtils = new CoreUtils(this.w);
  }
  // http://stackoverflow.com/questions/326679/choosing-an-attractive-linear-scale-for-a-graphs-y-axis
  // This routine creates the Y axis values for a graph.
  /**
   * @param {number} yMin
   * @param {number} yMax
   */
  niceScale(yMin, yMax, index = 0) {
    const jsPrecision = 1e-11;
    const w = this.w;
    const gl = w.globals;
    let axisCnf;
    let maxTicks;
    let gotMin;
    let gotMax;
    if (gl.isBarHorizontal) {
      axisCnf = w.config.xaxis;
      maxTicks = Math.max((gl.svgWidth - 100) / 25, 2);
    } else {
      axisCnf = w.config.yaxis[index];
      maxTicks = Math.max((gl.svgHeight - 100) / 15, 2);
    }
    if (!Utils$1.isNumber(maxTicks)) {
      maxTicks = 10;
    }
    gotMin = axisCnf.min !== void 0 && axisCnf.min !== null;
    gotMax = axisCnf.max !== void 0 && axisCnf.min !== null;
    let gotStepSize = axisCnf.stepSize !== void 0 && axisCnf.stepSize !== null;
    let gotTickAmount = axisCnf.tickAmount !== void 0 && axisCnf.tickAmount !== null;
    let ticks = gotTickAmount ? axisCnf.tickAmount : NICE_SCALE_DEFAULT_TICKS[Math.min(
      Math.round(maxTicks / 2),
      NICE_SCALE_DEFAULT_TICKS.length - 1
    )];
    if (gl.isMultipleYAxis && !gotTickAmount && gl.multiAxisTickAmount > 0) {
      ticks = gl.multiAxisTickAmount;
      gotTickAmount = true;
    }
    if (ticks === "dataPoints") {
      ticks = gl.dataPoints - 1;
    } else {
      ticks = Math.abs(Math.round(ticks));
    }
    if (yMin === Number.MIN_VALUE && yMax === 0 || !Utils$1.isNumber(yMin) && !Utils$1.isNumber(yMax) || yMin === Number.MIN_VALUE && yMax === -Number.MAX_VALUE) {
      yMin = Utils$1.isNumber(axisCnf.min) ? axisCnf.min : 0;
      yMax = Utils$1.isNumber(axisCnf.max) ? axisCnf.max : yMin + ticks;
      gl.allSeriesCollapsed = false;
    }
    if (yMin > yMax) {
      console.warn(
        "axis.min cannot be greater than axis.max: swapping min and max"
      );
      const temp = yMax;
      yMax = yMin;
      yMin = temp;
    } else if (yMin === yMax) {
      yMin = yMin === 0 ? 0 : yMin - 1;
      yMax = yMax === 0 ? 2 : yMax + 1;
    }
    const result = [];
    if (ticks < 1) {
      ticks = 1;
    }
    let tiks = ticks;
    let range = Math.abs(yMax - yMin);
    const proximityRatio = 0.15;
    if (!gotMin && yMin > 0 && yMin / range < proximityRatio) {
      yMin = 0;
      gotMin = true;
    }
    if (!gotMax && yMax < 0 && -yMax / range < proximityRatio) {
      yMax = 0;
      gotMax = true;
    }
    range = Math.abs(yMax - yMin);
    let stepSize = range / tiks;
    let niceStep = stepSize;
    const mag = Math.floor(Math.log10(niceStep));
    const magPow = Math.pow(10, mag);
    let magMsd = Math.ceil(niceStep / magPow);
    magMsd = NICE_SCALE_ALLOWED_MAG_MSD[gl.yValueDecimal === 0 ? 0 : 1][magMsd];
    niceStep = magMsd * magPow;
    stepSize = niceStep;
    if (gl.isBarHorizontal && axisCnf.stepSize && axisCnf.type !== "datetime") {
      stepSize = axisCnf.stepSize;
      gotStepSize = true;
    } else if (gotStepSize) {
      stepSize = axisCnf.stepSize;
    }
    if (gotStepSize) {
      if (axisCnf.forceNiceScale) {
        const stepMag = Math.floor(Math.log10(stepSize));
        stepSize *= Math.pow(10, mag - stepMag);
      }
    }
    if (gotMin && gotMax) {
      let crudeStep = range / tiks;
      if (gotTickAmount) {
        if (gotStepSize) {
          if (Utils$1.mod(range, stepSize) != 0) {
            const gcdStep = Utils$1.getGCD(stepSize, crudeStep);
            if (crudeStep / gcdStep < 10) {
              stepSize = gcdStep;
            } else {
              stepSize = crudeStep;
            }
          } else {
            if (Utils$1.mod(stepSize, crudeStep) == 0) {
              stepSize = crudeStep;
            } else {
              crudeStep = stepSize;
              gotTickAmount = false;
            }
          }
        } else {
          stepSize = crudeStep;
        }
      } else {
        if (gotStepSize) {
          if (Utils$1.mod(range, stepSize) == 0) {
            crudeStep = stepSize;
          } else {
            stepSize = crudeStep;
          }
        } else {
          if (Utils$1.mod(range, stepSize) == 0) {
            crudeStep = stepSize;
          } else {
            tiks = Math.ceil(range / stepSize);
            crudeStep = range / tiks;
            const gcdStep = Utils$1.getGCD(range, stepSize);
            if (range / gcdStep < maxTicks) {
              crudeStep = gcdStep;
            }
            stepSize = crudeStep;
          }
        }
      }
      tiks = Math.round(range / stepSize);
    } else {
      if (!gotMin && !gotMax) {
        if (gl.isMultipleYAxis && gotTickAmount) {
          const tMin = stepSize * Math.floor(yMin / stepSize);
          let tMax = tMin + stepSize * tiks;
          if (tMax < yMax) {
            stepSize *= 2;
          }
          yMin = tMin;
          tMax = yMax;
          yMax = yMin + stepSize * tiks;
          range = Math.abs(yMax - yMin);
          if (yMin > 0 && yMin < Math.abs(tMax - yMax)) {
            yMin = 0;
            yMax = stepSize * tiks;
          }
          if (yMax < 0 && -yMax < Math.abs(tMin - yMin)) {
            yMax = 0;
            yMin = -stepSize * tiks;
          }
        } else {
          yMin = stepSize * Math.floor(yMin / stepSize);
          yMax = stepSize * Math.ceil(yMax / stepSize);
        }
      } else if (gotMax) {
        if (gotTickAmount) {
          yMin = yMax - stepSize * tiks;
        } else {
          const yMinPrev = yMin;
          yMin = stepSize * Math.floor(yMin / stepSize);
          if (Math.abs(yMax - yMin) / Utils$1.getGCD(range, stepSize) > maxTicks) {
            yMin = yMax - stepSize * ticks;
            yMin += stepSize * Math.floor((yMinPrev - yMin) / stepSize);
          }
        }
      } else if (gotMin) {
        if (gotTickAmount) {
          yMax = yMin + stepSize * tiks;
        } else {
          const yMaxPrev = yMax;
          yMax = stepSize * Math.ceil(yMax / stepSize);
          if (Math.abs(yMax - yMin) / Utils$1.getGCD(range, stepSize) > maxTicks) {
            yMax = yMin + stepSize * ticks;
            yMax += stepSize * Math.ceil((yMaxPrev - yMax) / stepSize);
          }
        }
      }
      range = Math.abs(yMax - yMin);
      stepSize = Utils$1.getGCD(range, stepSize);
      tiks = Math.round(range / stepSize);
    }
    if (!gotTickAmount && !(gotMin || gotMax)) {
      tiks = Math.ceil((range - jsPrecision) / (stepSize + jsPrecision));
      if (tiks > 16 && Utils$1.getPrimeFactors(tiks).length < 2) {
        tiks++;
      }
    }
    if (!gotTickAmount && axisCnf.forceNiceScale && gl.yValueDecimal === 0 && tiks > range) {
      tiks = range;
      stepSize = Math.round(range / tiks);
    }
    if (tiks > maxTicks && (!(gotTickAmount || gotStepSize) || axisCnf.forceNiceScale)) {
      const pf = Utils$1.getPrimeFactors(tiks);
      const last = pf.length - 1;
      let tt = tiks;
      reduceLoop: for (var xFactors = 0; xFactors < last; xFactors++) {
        for (var lowest = 0; lowest <= last - xFactors; lowest++) {
          const stop = Math.min(lowest + xFactors, last);
          let t = tt;
          let div = 1;
          for (var next = lowest; next <= stop; next++) {
            div *= pf[next];
          }
          t /= div;
          if (t < maxTicks) {
            tt = t;
            break reduceLoop;
          }
        }
      }
      if (tt === tiks) {
        stepSize = range;
      } else {
        stepSize = range / tt;
      }
      tiks = Math.round(range / stepSize);
    }
    if (gl.isMultipleYAxis && gl.multiAxisTickAmount == 0 && gl.ignoreYAxisIndexes.indexOf(index) < 0) {
      gl.multiAxisTickAmount = tiks;
    }
    let val = yMin - stepSize;
    const err = stepSize * jsPrecision;
    do {
      val += stepSize;
      result.push(Utils$1.stripNumber(val, 7));
    } while (yMax - val > err);
    return {
      result,
      niceMin: result[0],
      niceMax: result[result.length - 1]
    };
  }
  /** @param {number} yMin @param {number} yMax @param {number|string} ticks @param {number} index @param {number|undefined} step */
  linearScale(yMin, yMax, ticks = 10, index = 0, step = void 0) {
    const range = Math.abs(yMax - yMin);
    let result = [];
    if (yMin === yMax) {
      result = [yMin];
      return {
        result,
        niceMin: result[0],
        niceMax: result[result.length - 1]
      };
    }
    ticks = this._adjustTicksForSmallRange(ticks, index, range);
    if (
      /** @type {any} */
      ticks === "dataPoints"
    ) {
      ticks = this.w.globals.dataPoints - 1;
    }
    const ticksNum = (
      /** @type {number} */
      ticks
    );
    if (!step) {
      step = range / ticksNum;
    }
    const MIN_PRECISION = 2;
    if (step !== 0 && isFinite(step)) {
      const magnitude = Math.floor(Math.log10(Math.abs(step)));
      const precision = Math.max(MIN_PRECISION, -magnitude + MIN_PRECISION);
      const multiplier = Math.pow(10, precision);
      step = Math.round((step + Number.EPSILON) * multiplier) / multiplier;
    }
    let tickCount = ticks === Number.MAX_VALUE ? 5 : ticksNum;
    if (ticks === Number.MAX_VALUE) {
      step = 1;
    }
    let v = yMin;
    while (tickCount >= 0) {
      result.push(v);
      v = Utils$1.preciseAddition(v, step);
      tickCount -= 1;
    }
    return {
      result,
      niceMin: result[0],
      niceMax: result[result.length - 1]
    };
  }
  /**
   * @param {number} yMin
   * @param {number} yMax
   * @param {number} base
   */
  logarithmicScaleNice(yMin, yMax, base) {
    if (yMax <= 0) yMax = Math.max(yMin, base);
    if (yMin <= 0) yMin = Math.min(yMax, base);
    const logs = [];
    const logMax = Math.ceil(Math.log(yMax) / Math.log(base) + 1);
    const logMin = Math.floor(Math.log(yMin) / Math.log(base));
    for (let i = logMin; i < logMax; i++) {
      logs.push(Math.pow(base, i));
    }
    return {
      result: logs,
      niceMin: logs[0],
      niceMax: logs[logs.length - 1]
    };
  }
  /**
   * @param {number} yMin
   * @param {number} yMax
   * @param {number} base
   */
  logarithmicScale(yMin, yMax, base) {
    if (yMax <= 0) yMax = Math.max(yMin, base);
    if (yMin <= 0) yMin = Math.min(yMax, base);
    const logs = [];
    const logMax = Math.log(yMax) / Math.log(base);
    const logMin = Math.log(yMin) / Math.log(base);
    const logRange = logMax - logMin;
    const ticks = Math.round(logRange);
    const logTickSpacing = logRange / ticks;
    for (let i = 0, logTick = logMin; i < ticks; i++, logTick += logTickSpacing) {
      logs.push(Math.pow(base, logTick));
    }
    logs.push(Math.pow(base, logMax));
    return {
      result: logs,
      niceMin: yMin,
      niceMax: yMax
    };
  }
  /**
   * @param {number | string} ticks
   * @param {number} index
   * @param {number} range
   */
  _adjustTicksForSmallRange(ticks, index, range) {
    let newTicks = ticks;
    if (typeof index !== "undefined" && this.w.config.yaxis[index].labels.formatter && this.w.config.yaxis[index].tickAmount === void 0) {
      const formattedVal = Number(
        this.w.config.yaxis[index].labels.formatter(1)
      );
      if (Utils$1.isNumber(formattedVal) && this.w.globals.yValueDecimal === 0) {
        newTicks = Math.ceil(range);
      }
    }
    return newTicks < ticks ? newTicks : ticks;
  }
  /**
   * @param {number} index
   * @param {number} minY
   * @param {number} maxY
   */
  setYScaleForIndex(index, minY, maxY) {
    const gl = this.w.globals;
    const cnf = this.w.config;
    const y = gl.isBarHorizontal ? cnf.xaxis : cnf.yaxis[index];
    if (typeof gl.yAxisScale[index] === "undefined") {
      gl.yAxisScale[index] = [];
    }
    const range = Math.abs(maxY - minY);
    if (y.logarithmic && range <= 5) {
      gl.invalidLogScale = true;
    }
    if (y.logarithmic && range > 5) {
      gl.allSeriesCollapsed = false;
      gl.yAxisScale[index] = y.forceNiceScale ? this.logarithmicScaleNice(minY, maxY, y.logBase) : this.logarithmicScale(minY, maxY, y.logBase);
    } else {
      if (maxY === -Number.MAX_VALUE || !Utils$1.isNumber(maxY) || minY === Number.MAX_VALUE || !Utils$1.isNumber(minY)) {
        gl.yAxisScale[index] = this.niceScale(
          Number.MIN_VALUE,
          0,
          index
        );
      } else {
        gl.allSeriesCollapsed = false;
        gl.yAxisScale[index] = this.niceScale(
          minY,
          maxY,
          index
        );
      }
    }
  }
  /**
   * @param {number} minX
   * @param {number} maxX
   */
  setXScale(minX, maxX) {
    const w = this.w;
    const gl = w.globals;
    if (maxX === -Number.MAX_VALUE || !Utils$1.isNumber(maxX)) {
      gl.xAxisScale = this.linearScale(0, 10, 10);
    } else {
      const ticks = gl.xTickAmount;
      gl.xAxisScale = this.linearScale(
        minX,
        maxX,
        ticks,
        0,
        w.config.xaxis.max === void 0 ? w.config.xaxis.stepSize : void 0
      );
    }
    return gl.xAxisScale;
  }
  scaleMultipleYAxes() {
    const cnf = this.w.config;
    const gl = this.w.globals;
    this.coreUtils.setSeriesYAxisMappings();
    const axisSeriesMap = gl.seriesYAxisMap;
    const minYArr = gl.minYArr;
    const maxYArr = gl.maxYArr;
    gl.allSeriesCollapsed = true;
    gl.barGroups = [];
    axisSeriesMap.forEach((axisSeries, ai) => {
      const groupNames = [];
      axisSeries.forEach((as) => {
        var _a;
        const group = (
          /** @type {Record<string,any>} */
          (_a = cnf.series[as]) == null ? void 0 : _a.group
        );
        if (groupNames.indexOf(group) < 0) {
          groupNames.push(group);
        }
      });
      if (axisSeries.length > 0) {
        let minY = Number.MAX_VALUE;
        let maxY = -Number.MAX_VALUE;
        let lowestY = minY;
        let highestY = maxY;
        let seriesType;
        let seriesGroupName;
        if (cnf.chart.stacked) {
          const mapSeries = new Array(gl.dataPoints).fill(0);
          const sumSeries = [];
          const posSeries = [];
          const negSeries = [];
          groupNames.forEach(() => {
            sumSeries.push(mapSeries.map(() => Number.MIN_VALUE));
            posSeries.push(mapSeries.map(() => Number.MIN_VALUE));
            negSeries.push(mapSeries.map(() => Number.MIN_VALUE));
          });
          for (let i = 0; i < axisSeries.length; i++) {
            if (!seriesType && /** @type {Record<string,any>} */
            cnf.series[axisSeries[i]].type) {
              seriesType = /** @type {Record<string,any>} */
              cnf.series[axisSeries[i]].type;
            }
            const si = axisSeries[i];
            if (
              /** @type {Record<string,any>} */
              cnf.series[si].group
            ) {
              seriesGroupName = /** @type {Record<string,any>} */
              cnf.series[si].group;
            } else {
              seriesGroupName = "axis-".concat(ai.toString());
            }
            const collapsed = !(gl.collapsedSeriesIndices.indexOf(si) < 0 && gl.ancillaryCollapsedSeriesIndices.indexOf(si) < 0);
            if (!collapsed) {
              gl.allSeriesCollapsed = false;
              groupNames.forEach((gn, gni) => {
                if (
                  /** @type {Record<string,any>} */
                  cnf.series[si].group === gn
                ) {
                  for (let j = 0; j < this.w.seriesData.series[si].length; j++) {
                    const val = this.w.seriesData.series[si][j];
                    if (val >= 0) {
                      posSeries[gni][j] += val;
                    } else {
                      negSeries[gni][j] += val;
                    }
                    sumSeries[gni][j] += val;
                    lowestY = Math.min(lowestY, val);
                    highestY = Math.max(highestY, val);
                  }
                }
              });
            }
            if (seriesType === "bar" || seriesType === "column") {
              gl.barGroups.push(seriesGroupName);
            }
          }
          if (!seriesType) {
            seriesType = cnf.chart.type;
          }
          if (seriesType === "bar" || seriesType === "column") {
            groupNames.forEach((gn, gni) => {
              minY = Math.min(minY, Math.min.apply(null, negSeries[gni]));
              maxY = Math.max(maxY, Math.max.apply(null, posSeries[gni]));
            });
          } else {
            groupNames.forEach((gn, gni) => {
              lowestY = Math.min(lowestY, Math.min.apply(null, sumSeries[gni]));
              highestY = Math.max(
                highestY,
                Math.max.apply(null, sumSeries[gni])
              );
            });
            minY = lowestY;
            maxY = highestY;
          }
          if (minY === Number.MIN_VALUE && maxY === Number.MIN_VALUE) {
            maxY = -Number.MAX_VALUE;
          }
        } else {
          for (let i = 0; i < axisSeries.length; i++) {
            const si = axisSeries[i];
            minY = Math.min(minY, minYArr[si]);
            maxY = Math.max(maxY, maxYArr[si]);
            const collapsed = !(gl.collapsedSeriesIndices.indexOf(si) < 0 && gl.ancillaryCollapsedSeriesIndices.indexOf(si) < 0);
            if (!collapsed) {
              gl.allSeriesCollapsed = false;
            }
          }
        }
        if (cnf.yaxis[ai].min !== void 0) {
          if (typeof cnf.yaxis[ai].min === "function") {
            minY = cnf.yaxis[ai].min(minY);
          } else {
            minY = cnf.yaxis[ai].min;
          }
        }
        if (cnf.yaxis[ai].max !== void 0) {
          if (typeof cnf.yaxis[ai].max === "function") {
            maxY = cnf.yaxis[ai].max(maxY);
          } else {
            maxY = cnf.yaxis[ai].max;
          }
        }
        gl.barGroups = gl.barGroups.filter((v, i, a) => a.indexOf(v) === i);
        this.setYScaleForIndex(ai, minY, maxY);
        axisSeries.forEach((si) => {
          minYArr[si] = gl.yAxisScale[ai].niceMin;
          maxYArr[si] = gl.yAxisScale[ai].niceMax;
        });
      } else {
        this.setYScaleForIndex(ai, 0, -Number.MAX_VALUE);
      }
    });
  }
}
class Range {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
    this.scales = new Scales(this.w);
  }
  init() {
    this.setYRange();
    this.setXRange();
    this.setZRange();
  }
  /**
   * @param {number} startingSeriesIndex
   * @param {number | null} [endingSeriesIndex]
   */
  getMinYMaxY(startingSeriesIndex, lowestY = Number.MAX_VALUE, highestY = -Number.MAX_VALUE, endingSeriesIndex = null) {
    var _a, _b, _c, _d, _e;
    const cnf = this.w.config;
    const gl = this.w.globals;
    let maxY = -Number.MAX_VALUE;
    let minY = Number.MIN_VALUE;
    if (endingSeriesIndex === null) {
      endingSeriesIndex = startingSeriesIndex + 1;
    }
    const series = this.w.seriesData.series;
    let seriesMin = series;
    let seriesMax = series;
    if (cnf.chart.type === "candlestick") {
      seriesMin = this.w.candleData.seriesCandleL;
      seriesMax = this.w.candleData.seriesCandleH;
    } else if (cnf.chart.type === "boxPlot") {
      seriesMin = this.w.candleData.seriesCandleO;
      seriesMax = this.w.candleData.seriesCandleC;
    } else if (this.w.axisFlags.isRangeData) {
      seriesMin = this.w.rangeData.seriesRangeStart;
      seriesMax = this.w.rangeData.seriesRangeEnd;
    }
    let autoScaleYaxis = false;
    if (this.w.seriesData.seriesX.length >= endingSeriesIndex) {
      const brush = (
        /** @type {any} */
        (_a = gl.brushSource) == null ? void 0 : _a.w.config.chart.brush
      );
      if (cnf.chart.zoom.enabled && cnf.chart.zoom.autoScaleYaxis || (brush == null ? void 0 : brush.enabled) && (brush == null ? void 0 : brush.autoScaleYaxis)) {
        autoScaleYaxis = true;
      }
    }
    for (let i = startingSeriesIndex; i < endingSeriesIndex; i++) {
      gl.dataPoints = Math.max(gl.dataPoints, series[i].length);
      const seriesType = (
        /** @type {Record<string,any>} */
        cnf.series[i].type
      );
      if (this.w.labelData.categoryLabels.length) {
        gl.dataPoints = this.w.labelData.categoryLabels.filter(
          (label) => typeof label !== "undefined"
        ).length;
      }
      if (this.w.labelData.labels.length && cnf.xaxis.type !== "datetime" && /**
       * @param {number} a
       * @param {number[]} c
       */
      this.w.seriesData.series.reduce((a, c) => a + c.length, 0) !== 0) {
        gl.dataPoints = Math.max(gl.dataPoints, this.w.labelData.labels.length);
      }
      let firstXIndex = 0;
      let lastXIndex = series[i].length - 1;
      if (autoScaleYaxis) {
        if (cnf.xaxis.min) {
          for (; firstXIndex < lastXIndex && this.w.seriesData.seriesX[i][firstXIndex] < cnf.xaxis.min; firstXIndex++) {
          }
        }
        if (cnf.xaxis.max) {
          for (; lastXIndex > firstXIndex && this.w.seriesData.seriesX[i][lastXIndex] > cnf.xaxis.max; lastXIndex--) {
          }
        }
      }
      for (let j = firstXIndex; j <= lastXIndex && j < this.w.seriesData.series[i].length; j++) {
        let val = series[i][j];
        if (val !== null && Utils$1.isNumber(val)) {
          if (typeof ((_b = seriesMax[i]) == null ? void 0 : _b[j]) !== "undefined") {
            maxY = Math.max(maxY, seriesMax[i][j]);
            lowestY = Math.min(lowestY, seriesMax[i][j]);
          }
          if (typeof ((_c = seriesMin[i]) == null ? void 0 : _c[j]) !== "undefined") {
            lowestY = Math.min(lowestY, seriesMin[i][j]);
            highestY = Math.max(highestY, seriesMin[i][j]);
          }
          switch (seriesType) {
            case "candlestick":
              {
                if (typeof this.w.candleData.seriesCandleC[i][j] !== "undefined") {
                  maxY = Math.max(maxY, this.w.candleData.seriesCandleH[i][j]);
                  lowestY = Math.min(
                    lowestY,
                    this.w.candleData.seriesCandleL[i][j]
                  );
                }
              }
              break;
            case "boxPlot":
              {
                if (typeof this.w.candleData.seriesCandleC[i][j] !== "undefined") {
                  maxY = Math.max(maxY, this.w.candleData.seriesCandleC[i][j]);
                  lowestY = Math.min(
                    lowestY,
                    this.w.candleData.seriesCandleO[i][j]
                  );
                }
              }
              break;
          }
          if (seriesType && seriesType !== "candlestick" && seriesType !== "boxPlot" && seriesType !== "rangeArea" && seriesType !== "rangeBar") {
            maxY = Math.max(maxY, this.w.seriesData.series[i][j]);
            lowestY = Math.min(lowestY, this.w.seriesData.series[i][j]);
          }
          if (this.w.seriesData.seriesGoals[i] && this.w.seriesData.seriesGoals[i][j] && Array.isArray(this.w.seriesData.seriesGoals[i][j])) {
            this.w.seriesData.seriesGoals[i][j].forEach(
              (g) => {
                maxY = Math.max(maxY, g.value);
                lowestY = Math.min(lowestY, g.value);
              }
            );
          }
          highestY = maxY;
          val = Utils$1.noExponents(val);
          if (Utils$1.isFloat(val)) {
            gl.yValueDecimal = Math.max(
              gl.yValueDecimal,
              val.toString().split(".")[1].length
            );
          }
          if (minY > ((_d = seriesMin[i]) == null ? void 0 : _d[j]) && ((_e = seriesMin[i]) == null ? void 0 : _e[j]) < 0) {
            minY = seriesMin[i][j];
          }
        } else {
          gl.hasNullValues = true;
        }
      }
      if (seriesType === "bar" || seriesType === "column") {
        if (minY < 0 && maxY < 0) {
          maxY = 0;
          highestY = Math.max(highestY, 0);
        }
        if (minY === Number.MIN_VALUE) {
          minY = 0;
          lowestY = Math.min(lowestY, 0);
        }
      }
    }
    if (cnf.chart.type === "rangeBar" && this.w.rangeData.seriesRangeStart.length && gl.isBarHorizontal) {
      minY = lowestY;
    }
    if (cnf.chart.type === "bar") {
      if (minY < 0 && maxY < 0) {
        maxY = 0;
      }
      if (minY === Number.MIN_VALUE) {
        minY = 0;
      }
    }
    return {
      minY,
      maxY,
      lowestY,
      highestY
    };
  }
  setYRange() {
    const gl = this.w.globals;
    const cnf = this.w.config;
    gl.maxY = -Number.MAX_VALUE;
    gl.minY = Number.MIN_VALUE;
    let lowestYInAllSeries = Number.MAX_VALUE;
    let minYMaxY;
    if (gl.isMultipleYAxis) {
      lowestYInAllSeries = Number.MAX_VALUE;
      for (let i = 0; i < this.w.seriesData.series.length; i++) {
        minYMaxY = this.getMinYMaxY(i);
        gl.minYArr[i] = minYMaxY.lowestY;
        gl.maxYArr[i] = minYMaxY.highestY;
        lowestYInAllSeries = Math.min(lowestYInAllSeries, minYMaxY.lowestY);
      }
    }
    minYMaxY = this.getMinYMaxY(
      0,
      lowestYInAllSeries,
      void 0,
      this.w.seriesData.series.length
    );
    if (cnf.chart.type === "bar") {
      gl.minY = minYMaxY.minY;
      gl.maxY = minYMaxY.maxY;
    } else {
      gl.minY = minYMaxY.lowestY;
      gl.maxY = minYMaxY.highestY;
    }
    lowestYInAllSeries = minYMaxY.lowestY;
    if (cnf.chart.stacked) {
      this._setStackedMinMax();
    }
    if (cnf.chart.type === "line" || cnf.chart.type === "area" || cnf.chart.type === "scatter" || cnf.chart.type === "candlestick" || cnf.chart.type === "boxPlot" || cnf.chart.type === "rangeBar" && !gl.isBarHorizontal) {
      if (gl.minY === Number.MIN_VALUE && lowestYInAllSeries !== -Number.MAX_VALUE && lowestYInAllSeries !== gl.maxY) {
        gl.minY = lowestYInAllSeries;
      }
    } else {
      gl.minY = gl.minY !== Number.MIN_VALUE ? Math.min(minYMaxY.minY, gl.minY) : minYMaxY.minY;
    }
    cnf.yaxis.forEach((yaxe, index) => {
      if (yaxe.max !== void 0) {
        if (typeof yaxe.max === "number") {
          gl.maxYArr[index] = yaxe.max;
        } else if (typeof yaxe.max === "function") {
          gl.maxYArr[index] = yaxe.max(
            gl.isMultipleYAxis ? gl.maxYArr[index] : gl.maxY
          );
        }
        gl.maxY = gl.maxYArr[index];
      }
      if (yaxe.min !== void 0) {
        if (typeof yaxe.min === "number") {
          gl.minYArr[index] = yaxe.min;
        } else if (typeof yaxe.min === "function") {
          gl.minYArr[index] = yaxe.min(
            gl.isMultipleYAxis ? gl.minYArr[index] === Number.MIN_VALUE ? 0 : gl.minYArr[index] : gl.minY
          );
        }
        gl.minY = gl.minYArr[index];
      }
    });
    if (gl.isBarHorizontal) {
      const minmax = ["min", "max"];
      minmax.forEach((m) => {
        if (cnf.xaxis[m] !== void 0 && typeof cnf.xaxis[m] === "number") {
          m === "min" ? gl.minY = cnf.xaxis[m] : gl.maxY = cnf.xaxis[m];
        }
      });
    }
    if (gl.isMultipleYAxis) {
      this.scales.scaleMultipleYAxes();
      gl.minY = lowestYInAllSeries;
    } else {
      this.scales.setYScaleForIndex(0, gl.minY, gl.maxY);
      gl.minY = gl.yAxisScale[0].niceMin;
      gl.maxY = gl.yAxisScale[0].niceMax;
      gl.minYArr[0] = gl.minY;
      gl.maxYArr[0] = gl.maxY;
    }
    gl.barGroups = [];
    gl.lineGroups = [];
    gl.areaGroups = [];
    cnf.series.forEach((s) => {
      const _s = (
        /** @type {any} */
        s
      );
      const type = _s.type || cnf.chart.type;
      switch (type) {
        case "bar":
        case "column":
          gl.barGroups.push(_s.group);
          break;
        case "line":
          gl.lineGroups.push(_s.group);
          break;
        case "area":
          gl.areaGroups.push(_s.group);
          break;
      }
    });
    gl.barGroups = gl.barGroups.filter((v, i, a) => a.indexOf(v) === i);
    gl.lineGroups = gl.lineGroups.filter((v, i, a) => a.indexOf(v) === i);
    gl.areaGroups = gl.areaGroups.filter((v, i, a) => a.indexOf(v) === i);
    return {
      minY: gl.minY,
      maxY: gl.maxY,
      minYArr: gl.minYArr,
      maxYArr: gl.maxYArr,
      yAxisScale: gl.yAxisScale
    };
  }
  setXRange() {
    const gl = this.w.globals;
    const cnf = this.w.config;
    const isXNumeric = cnf.xaxis.type === "numeric" || cnf.xaxis.type === "datetime" || cnf.xaxis.type === "category" && !this.w.axisFlags.noLabelsProvided || this.w.axisFlags.noLabelsProvided || this.w.axisFlags.isXNumeric;
    const getInitialMinXMaxX = () => {
      for (let i = 0; i < this.w.seriesData.series.length; i++) {
        if (this.w.labelData.labels[i]) {
          for (let j = 0; j < this.w.labelData.labels[i].length; j++) {
            if (this.w.labelData.labels[i][j] !== null && Utils$1.isNumber(this.w.labelData.labels[i][j])) {
              gl.maxX = Math.max(
                gl.maxX,
                /** @type {number} */
                /** @type {any} */
                this.w.labelData.labels[i][j]
              );
              gl.initialMaxX = Math.max(
                gl.maxX,
                /** @type {number} */
                /** @type {any} */
                this.w.labelData.labels[i][j]
              );
              gl.minX = Math.min(
                gl.minX,
                /** @type {number} */
                /** @type {any} */
                this.w.labelData.labels[i][j]
              );
              gl.initialMinX = Math.min(
                gl.minX,
                /** @type {number} */
                /** @type {any} */
                this.w.labelData.labels[i][j]
              );
            }
          }
        }
      }
    };
    if (this.w.axisFlags.isXNumeric) {
      getInitialMinXMaxX();
    }
    if (this.w.axisFlags.noLabelsProvided) {
      if (cnf.xaxis.categories.length === 0) {
        gl.maxX = /** @type {any} */
        this.w.labelData.labels[this.w.labelData.labels.length - 1];
        gl.initialMaxX = /** @type {any} */
        this.w.labelData.labels[this.w.labelData.labels.length - 1];
        gl.minX = 1;
        gl.initialMinX = 1;
      }
    }
    if (this.w.axisFlags.isXNumeric || this.w.axisFlags.noLabelsProvided || this.w.axisFlags.dataFormatXNumeric) {
      let ticks = 10;
      if (cnf.xaxis.tickAmount === void 0) {
        ticks = Math.round(gl.svgWidth / 150);
        if (cnf.xaxis.type === "numeric" && gl.dataPoints < 30) {
          ticks = gl.dataPoints - 1;
        }
        if (ticks > gl.dataPoints && gl.dataPoints !== 0) {
          ticks = gl.dataPoints - 1;
        }
      } else if (cnf.xaxis.tickAmount === "dataPoints") {
        if (this.w.seriesData.series.length > 1) {
          ticks = this.w.seriesData.series[gl.maxValsInArrayIndex].length - 1;
        }
        if (this.w.axisFlags.isXNumeric) {
          const diff = Math.round(gl.maxX - gl.minX);
          if (diff < 30) {
            ticks = diff;
          }
        }
      } else {
        ticks = cnf.xaxis.tickAmount;
      }
      gl.xTickAmount = ticks;
      if (cnf.xaxis.max !== void 0 && typeof cnf.xaxis.max === "number") {
        gl.maxX = cnf.xaxis.max;
      }
      if (cnf.xaxis.min !== void 0 && typeof cnf.xaxis.min === "number") {
        gl.minX = cnf.xaxis.min;
      }
      if (cnf.xaxis.range !== void 0) {
        gl.minX = gl.maxX - cnf.xaxis.range;
      }
      if (gl.minX !== Number.MAX_VALUE && gl.maxX !== -Number.MAX_VALUE) {
        if (cnf.xaxis.convertedCatToNumeric && !this.w.axisFlags.dataFormatXNumeric) {
          const catScale = [];
          for (let i = gl.minX - 1; i < gl.maxX; i++) {
            catScale.push(i + 1);
          }
          gl.xAxisScale = {
            result: catScale,
            niceMin: catScale[0],
            niceMax: catScale[catScale.length - 1]
          };
        } else {
          gl.xAxisScale = this.scales.setXScale(gl.minX, gl.maxX);
        }
      } else {
        gl.xAxisScale = this.scales.linearScale(
          0,
          ticks,
          ticks,
          0,
          cnf.xaxis.stepSize
        );
        if (this.w.axisFlags.noLabelsProvided && this.w.labelData.labels.length > 0) {
          gl.xAxisScale = this.scales.linearScale(
            1,
            this.w.labelData.labels.length,
            ticks - 1,
            0,
            cnf.xaxis.stepSize
          );
          this.w.seriesData.seriesX = /** @type {any} */
          this.w.labelData.labels.slice();
        }
      }
      if (isXNumeric) {
        this.w.labelData.labels = /** @type {any} */
        gl.xAxisScale.result.slice();
      }
    }
    if (gl.isBarHorizontal && this.w.labelData.labels.length) {
      gl.xTickAmount = this.w.labelData.labels.length;
    }
    this._handleSingleDataPoint();
    this._getMinXDiff();
    return {
      minX: gl.minX,
      maxX: gl.maxX
    };
  }
  setZRange() {
    const gl = this.w.globals;
    if (!this.w.axisFlags.isDataXYZ) return;
    for (let i = 0; i < this.w.seriesData.series.length; i++) {
      if (typeof this.w.seriesData.seriesZ[i] !== "undefined") {
        for (let j = 0; j < this.w.seriesData.seriesZ[i].length; j++) {
          if (this.w.seriesData.seriesZ[i][j] !== null && Utils$1.isNumber(this.w.seriesData.seriesZ[i][j])) {
            gl.maxZ = Math.max(gl.maxZ, this.w.seriesData.seriesZ[i][j]);
            gl.minZ = Math.min(gl.minZ, this.w.seriesData.seriesZ[i][j]);
          }
        }
      }
    }
  }
  _handleSingleDataPoint() {
    const gl = this.w.globals;
    const cnf = this.w.config;
    if (gl.minX === gl.maxX) {
      const datetimeObj = new DateTime(this.w);
      if (cnf.xaxis.type === "datetime") {
        const newMinX = datetimeObj.getDate(gl.minX);
        if (cnf.xaxis.labels.datetimeUTC) {
          newMinX.setUTCDate(newMinX.getUTCDate() - 2);
        } else {
          newMinX.setDate(newMinX.getDate() - 2);
        }
        gl.minX = new Date(newMinX).getTime();
        const newMaxX = datetimeObj.getDate(gl.maxX);
        if (cnf.xaxis.labels.datetimeUTC) {
          newMaxX.setUTCDate(newMaxX.getUTCDate() + 2);
        } else {
          newMaxX.setDate(newMaxX.getDate() + 2);
        }
        gl.maxX = new Date(newMaxX).getTime();
      } else if (cnf.xaxis.type === "numeric" || cnf.xaxis.type === "category" && !this.w.axisFlags.noLabelsProvided) {
        gl.minX = gl.minX - 2;
        gl.initialMinX = gl.minX;
        gl.maxX = gl.maxX + 2;
        gl.initialMaxX = gl.maxX;
      }
    }
  }
  _getMinXDiff() {
    const gl = this.w.globals;
    if (this.w.axisFlags.isXNumeric) {
      this.w.seriesData.seriesX.forEach((sX) => {
        if (sX.length) {
          if (sX.length === 1) {
            sX.push(
              this.w.seriesData.seriesX[gl.maxValsInArrayIndex][this.w.seriesData.seriesX[gl.maxValsInArrayIndex].length - 1]
            );
          }
          const seriesX = sX.slice();
          seriesX.sort((a, b) => a - b);
          seriesX.forEach((s, j) => {
            if (j > 0) {
              const xDiff = s - seriesX[j - 1];
              if (xDiff > 0) {
                gl.minXDiff = Math.min(xDiff, gl.minXDiff);
              }
            }
          });
          if (gl.dataPoints === 1 || gl.minXDiff === Number.MAX_VALUE) {
            gl.minXDiff = 0.5;
          }
        }
      });
    }
  }
  _setStackedMinMax() {
    const gl = this.w.globals;
    if (!this.w.seriesData.series.length) return;
    let seriesGroups = this.w.labelData.seriesGroups;
    if (!seriesGroups.length) {
      seriesGroups = [this.w.seriesData.seriesNames.map((name2) => name2)];
    }
    const stackedPoss = {};
    const stackedNegs = {};
    seriesGroups.forEach((group) => {
      stackedPoss[group] = [];
      stackedNegs[group] = [];
      const indicesOfSeriesInGroup = this.w.config.series.map(
        (serie, si) => group.indexOf(this.w.seriesData.seriesNames[si]) > -1 ? si : null
      ).filter((f) => f !== null);
      indicesOfSeriesInGroup.forEach((i) => {
        var _a, _b, _c, _d;
        for (let j = 0; j < this.w.seriesData.series[gl.maxValsInArrayIndex].length; j++) {
          if (typeof stackedPoss[group][j] === "undefined") {
            stackedPoss[group][j] = 0;
            stackedNegs[group][j] = 0;
          }
          const stackSeries = this.w.config.chart.stacked && !gl.comboCharts || this.w.config.chart.stacked && gl.comboCharts && (!this.w.config.chart.stackOnlyBar || /** @type {Record<string,any>} */
          ((_b = (_a = this.w.config.series) == null ? void 0 : _a[i]) == null ? void 0 : _b.type) === "bar" || /** @type {Record<string,any>} */
          ((_d = (_c = this.w.config.series) == null ? void 0 : _c[i]) == null ? void 0 : _d.type) === "column");
          if (stackSeries) {
            if (this.w.seriesData.series[i][j] !== null && Utils$1.isNumber(this.w.seriesData.series[i][j])) {
              this.w.seriesData.series[i][j] > 0 ? stackedPoss[group][j] += parseFloat(String(this.w.seriesData.series[i][j])) + 1e-4 : stackedNegs[group][j] += parseFloat(
                String(this.w.seriesData.series[i][j])
              );
            }
          }
        }
      });
    });
    Object.entries(stackedPoss).forEach(([key]) => {
      stackedPoss[key].forEach(
        (_, stgi) => {
          gl.maxY = Math.max(gl.maxY, stackedPoss[key][stgi]);
          gl.minY = Math.min(gl.minY, stackedNegs[key][stgi]);
        }
      );
    });
  }
}
function getThemePalettes() {
  return {
    palette1: ["#008FFB", "#00E396", "#FEB019", "#FF4560", "#775DD0"],
    palette2: ["#3F51B5", "#03A9F4", "#4CAF50", "#F9CE1D", "#FF9800"],
    palette3: ["#33B2DF", "#546E7A", "#D4526E", "#13D8AA", "#A5978B"],
    palette4: ["#4ECDC4", "#C7F464", "#81D4FA", "#FD6A6A", "#546E7A"],
    palette5: ["#2B908F", "#F9A3A4", "#90EE7E", "#FA4443", "#69D2E7"],
    palette6: ["#449DD1", "#F86624", "#EA3546", "#662E9B", "#C5D86D"],
    palette7: ["#D7263D", "#1B998B", "#2E294E", "#F46036", "#E2C044"],
    palette8: ["#662E9B", "#F86624", "#F9C80E", "#EA3546", "#43BCCD"],
    palette9: ["#5C4742", "#A5978B", "#8D5B4C", "#5A2A27", "#C4BBAF"],
    palette10: ["#A300D6", "#7D02EB", "#5653FE", "#2983FF", "#00B1F2"],
    // CVD-safe palettes (Wong 2011 / IBM design)
    cvdDeuteranopia: ["#0072B2", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#D55E00", "#CC79A7"],
    cvdProtanopia: ["#0077BB", "#EE7733", "#009988", "#EE3377", "#BBBBBB", "#33BBEE", "#CC3311"],
    cvdTritanopia: ["#CC3311", "#009988", "#EE7733", "#0077BB", "#EE3377", "#BBBBBB", "#33BBEE"],
    highContrast: ["#005A9C", "#C00000", "#007A33", "#6C3483", "#7B3F00", "#0097A7", "#4A235A"]
  };
}
class YAxis {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   * @param {any} [elgrid]
   */
  constructor(w, { theme = null, timeScale = null } = {}, elgrid) {
    this.w = w;
    this.elgrid = elgrid;
    this.xaxisFontSize = w.config.xaxis.labels.style.fontSize;
    this.axisFontFamily = w.config.xaxis.labels.style.fontFamily;
    this.xaxisForeColors = w.config.xaxis.labels.style.colors;
    this.isCategoryBarHorizontal = w.config.chart.type === "bar" && w.config.plotOptions.bar.horizontal;
    this.xAxisoffX = w.config.xaxis.position === "bottom" ? w.layout.gridHeight : 0;
    this.drawnLabels = [];
    this.axesUtils = new AxesUtils(w, { theme, timeScale });
  }
  /**
   * @param {number} realIndex
   */
  drawYaxis(realIndex) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const yaxisStyle = w.config.yaxis[realIndex].labels.style;
    const {
      fontSize: yaxisFontSize,
      fontFamily: yaxisFontFamily,
      fontWeight: yaxisFontWeight
    } = yaxisStyle;
    const elYaxis = graphics.group({
      class: "apexcharts-yaxis",
      rel: realIndex,
      transform: `translate(${w.globals.translateYAxisX[realIndex]}, 0)`
    });
    if (this.axesUtils.isYAxisHidden(realIndex)) return elYaxis;
    const elYaxisTexts = graphics.group({ class: "apexcharts-yaxis-texts-g" });
    elYaxis.add(elYaxisTexts);
    const tickAmount = w.globals.yAxisScale[realIndex].result.length - 1;
    const labelsDivider = w.layout.gridHeight / tickAmount;
    const lbFormatter = w.formatters.yLabelFormatters[realIndex];
    const labels = this.axesUtils.checkForReversedLabels(
      realIndex,
      w.globals.yAxisScale[realIndex].result.slice()
    );
    if (w.config.yaxis[realIndex].labels.show) {
      let lY = w.layout.translateY + w.config.yaxis[realIndex].labels.offsetY;
      if (w.globals.isBarHorizontal) lY = 0;
      else if (w.config.chart.type === "heatmap") lY -= labelsDivider / 2;
      lY += parseInt(yaxisFontSize, 10) / 3;
      let firstLabel = null;
      for (let i = tickAmount; i >= 0; i--) {
        const val = lbFormatter(labels[i], i, w);
        let xPad = w.config.yaxis[realIndex].labels.padding;
        if (w.config.yaxis[realIndex].opposite && w.config.yaxis.length !== 0)
          xPad *= -1;
        const textAnchor = this.getTextAnchor(
          w.config.yaxis[realIndex].labels.align,
          w.config.yaxis[realIndex].opposite
        );
        const yColors = this.axesUtils.getYAxisForeColor(
          yaxisStyle.colors,
          realIndex
        );
        const foreColor = Array.isArray(yColors) ? yColors[i] : yColors;
        const existingYLabels = Array.from(
          w.dom.baseEl.querySelectorAll(
            `.apexcharts-yaxis[rel='${realIndex}'] .apexcharts-yaxis-label tspan`
          )
        ).map((label2) => label2.textContent);
        const label = graphics.drawText({
          x: xPad,
          y: lY,
          text: existingYLabels.includes(val) && !w.config.yaxis[realIndex].labels.showDuplicates ? "" : val,
          textAnchor,
          fontSize: yaxisFontSize,
          fontFamily: yaxisFontFamily,
          fontWeight: yaxisFontWeight,
          maxWidth: w.config.yaxis[realIndex].labels.maxWidth,
          foreColor,
          isPlainText: false,
          cssClass: `apexcharts-yaxis-label ${yaxisStyle.cssClass}`
        });
        elYaxisTexts.add(label);
        this.addTooltip(label, val);
        if (firstLabel === null) {
          firstLabel = label;
        }
        if (w.config.yaxis[realIndex].labels.rotate !== 0) {
          this.rotateLabel(
            graphics,
            label,
            firstLabel,
            w.config.yaxis[realIndex].labels.rotate
          );
        }
        lY += labelsDivider;
      }
    }
    this.addYAxisTitle(graphics, elYaxis, realIndex);
    this.addAxisBorder(graphics, elYaxis, realIndex, tickAmount, labelsDivider);
    return elYaxis;
  }
  /**
   * @param {string} align
   * @param {boolean} opposite
   */
  getTextAnchor(align, opposite) {
    if (align === "left") return "start";
    if (align === "center") return "middle";
    if (align === "right") return "end";
    return opposite ? "start" : "end";
  }
  /**
   * @param {any} label
   * @param {any} val
   */
  addTooltip(label, val) {
    const elTooltipTitle = BrowserAPIs.createElementNS(SVGNS, "title");
    elTooltipTitle.textContent = Array.isArray(val) ? val.join(" ") : val;
    label.node.appendChild(elTooltipTitle);
  }
  /**
   * @param {import('../Graphics').default} graphics
   * @param {any} label
   * @param {any} firstLabel
   * @param {number} rotate
   */
  rotateLabel(graphics, label, firstLabel, rotate) {
    const firstLabelCenter = graphics.rotateAroundCenter(firstLabel.node);
    const labelCenter = graphics.rotateAroundCenter(label.node);
    label.node.setAttribute(
      "transform",
      `rotate(${rotate} ${firstLabelCenter.x} ${labelCenter.y})`
    );
  }
  /**
   * @param {import('../Graphics').default} graphics
   * @param {any} elYaxis
   * @param {number} realIndex
   */
  addYAxisTitle(graphics, elYaxis, realIndex) {
    const w = this.w;
    if (w.config.yaxis[realIndex].title.text !== void 0) {
      const elYaxisTitle = graphics.group({ class: "apexcharts-yaxis-title" });
      const x = w.config.yaxis[realIndex].opposite ? w.globals.translateYAxisX[realIndex] : 0;
      const elYAxisTitleText = graphics.drawText({
        x,
        y: w.layout.gridHeight / 2 + w.layout.translateY + w.config.yaxis[realIndex].title.offsetY,
        text: w.config.yaxis[realIndex].title.text,
        textAnchor: "end",
        foreColor: w.config.yaxis[realIndex].title.style.color,
        fontSize: w.config.yaxis[realIndex].title.style.fontSize,
        fontWeight: w.config.yaxis[realIndex].title.style.fontWeight,
        fontFamily: w.config.yaxis[realIndex].title.style.fontFamily,
        cssClass: `apexcharts-yaxis-title-text ${w.config.yaxis[realIndex].title.style.cssClass}`
      });
      elYaxisTitle.add(elYAxisTitleText);
      elYaxis.add(elYaxisTitle);
    }
  }
  /**
   * @param {import('../Graphics').default} graphics
   * @param {any} elYaxis
   * @param {number} realIndex
   * @param {number} tickAmount
   * @param {number} labelsDivider
   */
  addAxisBorder(graphics, elYaxis, realIndex, tickAmount, labelsDivider) {
    const w = this.w;
    const axisBorder = w.config.yaxis[realIndex].axisBorder;
    let x = 31 + axisBorder.offsetX;
    if (w.config.yaxis[realIndex].opposite) x = -31 - axisBorder.offsetX;
    if (axisBorder.show) {
      const elVerticalLine = graphics.drawLine(
        x,
        w.layout.translateY + axisBorder.offsetY - 2,
        x,
        w.layout.gridHeight + w.layout.translateY + axisBorder.offsetY + 2,
        axisBorder.color,
        0,
        axisBorder.width
      );
      elYaxis.add(elVerticalLine);
    }
    if (w.config.yaxis[realIndex].axisTicks.show) {
      this.axesUtils.drawYAxisTicks(
        x,
        tickAmount,
        axisBorder,
        w.config.yaxis[realIndex].axisTicks,
        realIndex,
        labelsDivider,
        elYaxis
      );
    }
  }
  /**
   * @param {number} realIndex
   */
  drawYaxisInversed(realIndex) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const elXaxis = graphics.group({
      class: "apexcharts-xaxis apexcharts-yaxis-inversed"
    });
    const elXaxisTexts = graphics.group({
      class: "apexcharts-xaxis-texts-g",
      transform: `translate(${w.layout.translateXAxisX}, ${w.layout.translateXAxisY})`
    });
    elXaxis.add(elXaxisTexts);
    let tickAmount = w.globals.yAxisScale[realIndex].result.length - 1;
    const labelsDivider = w.layout.gridWidth / tickAmount + 0.1;
    let l = labelsDivider + w.config.xaxis.labels.offsetX;
    const lbFormatter = w.formatters.xLabelFormatter;
    let labels = this.axesUtils.checkForReversedLabels(
      realIndex,
      w.globals.yAxisScale[realIndex].result.slice()
    );
    const timescaleLabels = w.labelData.timescaleLabels;
    if (timescaleLabels.length > 0) {
      this.xaxisLabels = timescaleLabels.slice();
      labels = timescaleLabels.slice();
      tickAmount = labels.length;
    }
    if (w.config.xaxis.labels.show) {
      for (let i = timescaleLabels.length ? 0 : tickAmount; timescaleLabels.length ? i < timescaleLabels.length : i >= 0; timescaleLabels.length ? i++ : i--) {
        let val = lbFormatter == null ? void 0 : lbFormatter(labels[i], i, w);
        let x = w.layout.gridWidth + w.globals.padHorizontal - (l - labelsDivider + w.config.xaxis.labels.offsetX);
        if (timescaleLabels.length) {
          const label = this.axesUtils.getLabel(
            labels,
            timescaleLabels,
            x,
            i,
            this.drawnLabels,
            this.xaxisFontSize
          );
          x = label.x;
          val = label.text;
          this.drawnLabels.push(label.text);
          if (i === 0 && w.globals.skipFirstTimelinelabel) val = "";
          if (i === labels.length - 1 && w.globals.skipLastTimelinelabel)
            val = "";
        }
        const elTick = graphics.drawText({
          x,
          y: this.xAxisoffX + w.config.xaxis.labels.offsetY + 30 - (w.config.xaxis.position === "top" ? w.layout.xAxisHeight + w.config.xaxis.axisTicks.height - 2 : 0),
          text: val,
          textAnchor: "middle",
          foreColor: Array.isArray(this.xaxisForeColors) ? this.xaxisForeColors[realIndex] : this.xaxisForeColors,
          fontSize: this.xaxisFontSize,
          fontFamily: this.axisFontFamily,
          fontWeight: w.config.xaxis.labels.style.fontWeight,
          isPlainText: false,
          cssClass: `apexcharts-xaxis-label ${w.config.xaxis.labels.style.cssClass}`
        });
        elXaxisTexts.add(elTick);
        this.addTooltip(elTick, val);
        l += labelsDivider;
      }
    }
    this.inversedYAxisTitleText(elXaxis);
    this.inversedYAxisBorder(elXaxis);
    return elXaxis;
  }
  /**
   * @param {any} parent
   */
  inversedYAxisBorder(parent) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const axisBorder = w.config.xaxis.axisBorder;
    if (axisBorder.show) {
      let lineCorrection = 0;
      if (w.config.chart.type === "bar" && w.axisFlags.isXNumeric)
        lineCorrection -= 15;
      const elHorzLine = graphics.drawLine(
        w.globals.padHorizontal + lineCorrection + axisBorder.offsetX,
        this.xAxisoffX,
        w.layout.gridWidth,
        this.xAxisoffX,
        axisBorder.color,
        0,
        axisBorder.height
      );
      if (this.elgrid && this.elgrid.elGridBorders && w.config.grid.show) {
        this.elgrid.elGridBorders.add(elHorzLine);
      } else {
        parent.add(elHorzLine);
      }
    }
  }
  /**
   * @param {any} parent
   */
  inversedYAxisTitleText(parent) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    if (w.config.xaxis.title.text !== void 0) {
      const elYaxisTitle = graphics.group({
        class: "apexcharts-xaxis-title apexcharts-yaxis-title-inversed"
      });
      const elYAxisTitleText = graphics.drawText({
        x: w.layout.gridWidth / 2 + w.config.xaxis.title.offsetX,
        y: this.xAxisoffX + parseFloat(this.xaxisFontSize) + parseFloat(w.config.xaxis.title.style.fontSize) + w.config.xaxis.title.offsetY + 20,
        text: w.config.xaxis.title.text,
        textAnchor: "middle",
        fontSize: w.config.xaxis.title.style.fontSize,
        fontFamily: w.config.xaxis.title.style.fontFamily,
        fontWeight: w.config.xaxis.title.style.fontWeight,
        foreColor: w.config.xaxis.title.style.color,
        cssClass: `apexcharts-xaxis-title-text ${w.config.xaxis.title.style.cssClass}`
      });
      elYaxisTitle.add(elYAxisTitleText);
      parent.add(elYaxisTitle);
    }
  }
  /**
   * @param {number} realIndex
   * @param {boolean} yAxisOpposite
   */
  yAxisTitleRotate(realIndex, yAxisOpposite) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const elYAxisLabelsWrap = w.dom.baseEl.querySelector(
      `.apexcharts-yaxis[rel='${realIndex}'] .apexcharts-yaxis-texts-g`
    );
    const yAxisLabelsCoord = elYAxisLabelsWrap ? elYAxisLabelsWrap.getBoundingClientRect() : { width: 0, height: 0 };
    const yAxisTitle = w.dom.baseEl.querySelector(
      `.apexcharts-yaxis[rel='${realIndex}'] .apexcharts-yaxis-title text`
    );
    const yAxisTitleCoord = yAxisTitle ? yAxisTitle.getBoundingClientRect() : { width: 0, height: 0 };
    if (yAxisTitle) {
      const x = this.xPaddingForYAxisTitle(
        realIndex,
        yAxisLabelsCoord,
        yAxisTitleCoord,
        yAxisOpposite
      );
      yAxisTitle.setAttribute("x", String(x.xPos - (yAxisOpposite ? 10 : 0)));
      const titleRotatingCenter = graphics.rotateAroundCenter(yAxisTitle);
      yAxisTitle.setAttribute(
        "transform",
        `rotate(${yAxisOpposite ? w.config.yaxis[realIndex].title.rotate * -1 : w.config.yaxis[realIndex].title.rotate} ${titleRotatingCenter.x} ${titleRotatingCenter.y})`
      );
    }
  }
  /**
   * @param {number} realIndex
   * @param {{width: number, height: number}} yAxisLabelsCoord
   * @param {{width: number, height: number}} yAxisTitleCoord
   * @param {boolean} yAxisOpposite
   */
  xPaddingForYAxisTitle(realIndex, yAxisLabelsCoord, yAxisTitleCoord, yAxisOpposite) {
    const w = this.w;
    let x = 0;
    let padd = 10;
    if (w.config.yaxis[realIndex].title.text === void 0 || realIndex < 0) {
      return { xPos: x, padd: 0 };
    }
    if (yAxisOpposite) {
      x = yAxisLabelsCoord.width + w.config.yaxis[realIndex].title.offsetX + yAxisTitleCoord.width / 2 + padd / 2;
    } else {
      x = yAxisLabelsCoord.width * -1 + w.config.yaxis[realIndex].title.offsetX + padd / 2 + yAxisTitleCoord.width / 2;
      if (w.globals.isBarHorizontal) {
        padd = 25;
        x = yAxisLabelsCoord.width * -1 - w.config.yaxis[realIndex].title.offsetX - padd;
      }
    }
    return { xPos: x, padd };
  }
  /**
   * @param {Array<{width: number, height: number}>} yaxisLabelCoords
   * @param {Array<{width: number, height: number}>} yTitleCoords
   */
  setYAxisXPosition(yaxisLabelCoords, yTitleCoords) {
    const w = this.w;
    let xLeft = 0;
    let xRight = 0;
    let leftOffsetX = 18;
    let rightOffsetX = 1;
    if (w.config.yaxis.length > 1) this.multipleYs = true;
    w.config.yaxis.forEach((yaxe, index) => {
      const shouldNotDrawAxis = w.globals.ignoreYAxisIndexes.includes(index) || !yaxe.show || yaxe.floating || yaxisLabelCoords[index].width === 0;
      const axisWidth = yaxisLabelCoords[index].width + yTitleCoords[index].width;
      if (!yaxe.opposite) {
        xLeft = w.layout.translateX - leftOffsetX;
        if (!shouldNotDrawAxis) leftOffsetX += axisWidth + 20;
        w.globals.translateYAxisX[index] = xLeft + yaxe.labels.offsetX;
      } else {
        if (w.globals.isBarHorizontal) {
          xRight = w.layout.gridWidth + w.layout.translateX - 1;
          w.globals.translateYAxisX[index] = xRight - yaxe.labels.offsetX;
        } else {
          xRight = w.layout.gridWidth + w.layout.translateX + rightOffsetX;
          if (!shouldNotDrawAxis) rightOffsetX += axisWidth + 20;
          w.globals.translateYAxisX[index] = xRight - yaxe.labels.offsetX + 20;
        }
      }
    });
  }
  setYAxisTextAlignments() {
    const w = this.w;
    const yaxis = Array.from(
      w.dom.baseEl.getElementsByClassName("apexcharts-yaxis")
    );
    yaxis.forEach((y, index) => {
      const yaxe = w.config.yaxis[index];
      if (yaxe && !yaxe.floating && yaxe.labels.align !== void 0) {
        const yAxisInner = w.dom.baseEl.querySelector(
          `.apexcharts-yaxis[rel='${index}'] .apexcharts-yaxis-texts-g`
        );
        const yAxisTexts = Array.from(
          w.dom.baseEl.querySelectorAll(
            `.apexcharts-yaxis[rel='${index}'] .apexcharts-yaxis-label`
          )
        );
        const rect = (
          /** @type {Element} */
          yAxisInner.getBoundingClientRect()
        );
        yAxisTexts.forEach((label) => {
          label.setAttribute("text-anchor", yaxe.labels.align);
        });
        if (yaxe.labels.align === "left" && !yaxe.opposite) {
          yAxisInner.setAttribute(
            "transform",
            `translate(-${rect.width}, 0)`
          );
        } else if (yaxe.labels.align === "center") {
          yAxisInner.setAttribute(
            "transform",
            `translate(${rect.width / 2 * (!yaxe.opposite ? -1 : 1)}, 0)`
          );
        } else if (yaxe.labels.align === "right" && yaxe.opposite) {
          yAxisInner.setAttribute(
            "transform",
            `translate(${rect.width}, 0)`
          );
        }
      }
    });
  }
}
class Events {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
    this.documentEvent = this.documentEvent.bind(this);
  }
  /**
   * @param {string} name
   * @param {Function} handler
   */
  addEventListener(name2, handler) {
    const w = this.w;
    if (Object.prototype.hasOwnProperty.call(w.globals.events, name2)) {
      w.globals.events[name2].push(handler);
    } else {
      w.globals.events[name2] = [handler];
    }
  }
  /**
   * @param {string} name
   * @param {Function} handler
   */
  removeEventListener(name2, handler) {
    const w = this.w;
    if (!Object.prototype.hasOwnProperty.call(w.globals.events, name2)) {
      return;
    }
    const index = (
      /** @type {Record<string,any>} */
      w.globals.events[name2].indexOf(handler)
    );
    if (index !== -1) {
      w.globals.events[name2].splice(
        index,
        1
      );
    }
  }
  /**
   * @param {string} name
   * @param {any[]} args
   */
  fireEvent(name2, args) {
    const w = this.w;
    if (!Object.prototype.hasOwnProperty.call(w.globals.events, name2)) {
      return;
    }
    if (!args || !args.length) {
      args = [];
    }
    const evs = (
      /** @type {Record<string,any>} */
      w.globals.events[name2]
    );
    const l = evs.length;
    for (let i = 0; i < l; i++) {
      evs[i].apply(null, args);
    }
  }
  setupEventHandlers() {
    const w = this.w;
    const me = this.ctx;
    const clickableArea = w.dom.baseEl.querySelector(w.globals.chartClass);
    this.ctx.eventList.forEach((event) => {
      clickableArea == null ? void 0 : clickableArea.addEventListener(
        event,
        (e) => {
          const capturedSeriesIndex = e.target.getAttribute("i") === null && w.interact.capturedSeriesIndex !== -1 ? w.interact.capturedSeriesIndex : e.target.getAttribute("i");
          const capturedDataPointIndex = e.target.getAttribute("j") === null && w.interact.capturedDataPointIndex !== -1 ? w.interact.capturedDataPointIndex : e.target.getAttribute("j");
          const opts = Object.assign({}, w, {
            seriesIndex: w.globals.axisCharts ? capturedSeriesIndex : 0,
            dataPointIndex: capturedDataPointIndex
          });
          if (e.type === "keydown") {
            if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled) {
              if (me.ctx.keyboardNavigation) {
                me.ctx.keyboardNavigation.handleKey(e);
              }
              if (typeof w.config.chart.events.keyDown === "function") {
                w.config.chart.events.keyDown(e, me, opts);
              }
              me.ctx.events.fireEvent("keydown", [e, me, opts]);
            }
          } else if (e.type === "keyup") {
            if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled) {
              if (typeof w.config.chart.events.keyUp === "function") {
                w.config.chart.events.keyUp(e, me, opts);
              }
              me.ctx.events.fireEvent("keyup", [e, me, opts]);
            }
          } else if (e.type === "mousemove" || e.type === "touchmove") {
            if (typeof w.config.chart.events.mouseMove === "function") {
              w.config.chart.events.mouseMove(e, me, opts);
            }
          } else if (e.type === "mouseleave" || e.type === "touchleave") {
            if (typeof w.config.chart.events.mouseLeave === "function") {
              w.config.chart.events.mouseLeave(e, me, opts);
            }
          } else if (e.type === "mouseup" && e.which === 1 || e.type === "touchend") {
            if (typeof w.config.chart.events.click === "function") {
              w.config.chart.events.click(e, me, opts);
            }
            me.ctx.events.fireEvent("click", [e, me, opts]);
          }
        },
        { capture: false, passive: true }
      );
    });
    this.ctx.eventList.forEach((event) => {
      w.dom.baseEl.addEventListener(event, this.documentEvent, {
        passive: true
      });
    });
    this.ctx.core.setupBrushHandler();
  }
  /**
   * @param {any} e
   */
  documentEvent(e) {
    const w = this.w;
    const target = e.target.className;
    if (e.type === "click") {
      const elMenu = w.dom.baseEl.querySelector(".apexcharts-menu");
      if (elMenu && elMenu.classList.contains("apexcharts-menu-open") && target !== "apexcharts-menu-icon") {
        elMenu.classList.remove("apexcharts-menu-open");
      }
    }
    w.interact.clientX = e.type === "touchmove" ? e.touches[0].clientX : e.clientX;
    w.interact.clientY = e.type === "touchmove" ? e.touches[0].clientY : e.clientY;
  }
}
class Localization {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
  }
  /**
   * @param {string} localeName
   */
  setCurrentLocaleValues(localeName) {
    let locales = this.w.config.chart.locales;
    const globalApex = Environment.getApex();
    if (globalApex.chart && globalApex.chart.locales && globalApex.chart.locales.length > 0) {
      locales = this.w.config.chart.locales.concat(globalApex.chart.locales);
    }
    const selectedLocale = locales.filter(
      (c) => c.name === localeName
    )[0];
    if (selectedLocale) {
      const ret = Utils$1.extend(en, selectedLocale);
      this.w.globals.locale = ret.options;
    } else {
      throw new Error(
        "Wrong locale name provided. Please make sure you set the correct locale name in options"
      );
    }
  }
}
class Axes {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   * @param {import('../../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
  }
  /**
   * @param {string} type
   * @param {any} elgrid
   */
  drawAxis(type, elgrid) {
    const gl = this.w.globals;
    const cnf = this.w.config;
    const xAxis = new XAxis(this.w, this.ctx, elgrid);
    const yAxis = new YAxis(this.w, { theme: this.ctx.theme, timeScale: this.ctx.timeScale }, elgrid);
    if (gl.axisCharts && type !== "radar") {
      let elXaxis, elYaxis;
      if (gl.isBarHorizontal) {
        elYaxis = yAxis.drawYaxisInversed(0);
        elXaxis = xAxis.drawXaxisInversed(0);
        this.w.dom.elGraphical.add(elXaxis);
        this.w.dom.elGraphical.add(elYaxis);
      } else {
        elXaxis = xAxis.drawXaxis();
        this.w.dom.elGraphical.add(elXaxis);
        cnf.yaxis.map((yaxe, index) => {
          if (gl.ignoreYAxisIndexes.indexOf(index) === -1) {
            elYaxis = yAxis.drawYaxis(index);
            this.w.dom.Paper.add(elYaxis);
            if (this.w.config.grid.position === "back") {
              const inner = this.w.dom.Paper.children()[1];
              if (inner) {
                inner.remove();
                this.w.dom.Paper.add(inner);
              }
            }
          }
        });
      }
    }
  }
}
class Crosshairs {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
  }
  drawXCrosshairs() {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const filters = new Filters(this.w);
    const crosshairGradient = w.config.xaxis.crosshairs.fill.gradient;
    const crosshairShadow = w.config.xaxis.crosshairs.dropShadow;
    const fillType = w.config.xaxis.crosshairs.fill.type;
    const gradientFrom = crosshairGradient.colorFrom;
    const gradientTo = crosshairGradient.colorTo;
    const opacityFrom = crosshairGradient.opacityFrom;
    const opacityTo = crosshairGradient.opacityTo;
    const stops = crosshairGradient.stops;
    const shadow = "none";
    const dropShadow = crosshairShadow.enabled;
    const shadowLeft = crosshairShadow.left;
    const shadowTop = crosshairShadow.top;
    const shadowBlur = crosshairShadow.blur;
    const shadowColor = crosshairShadow.color;
    const shadowOpacity = crosshairShadow.opacity;
    let xcrosshairsFill = w.config.xaxis.crosshairs.fill.color;
    if (w.config.xaxis.crosshairs.show) {
      if (fillType === "gradient") {
        xcrosshairsFill = graphics.drawGradient(
          "vertical",
          gradientFrom,
          gradientTo,
          opacityFrom,
          opacityTo,
          null,
          stops,
          []
        );
      }
      let xcrosshairs = graphics.drawRect();
      if (w.config.xaxis.crosshairs.width === 1) {
        xcrosshairs = graphics.drawLine(0, 0, 0, 0);
      }
      let gridHeight = w.layout.gridHeight;
      if (!Utils$1.isNumber(gridHeight) || gridHeight < 0) {
        gridHeight = 0;
      }
      let crosshairsWidth = w.config.xaxis.crosshairs.width;
      if (!Utils$1.isNumber(crosshairsWidth) || Number(crosshairsWidth) < 0) {
        crosshairsWidth = 0;
      }
      xcrosshairs.attr({
        class: "apexcharts-xcrosshairs",
        x: 0,
        y: 0,
        y2: gridHeight,
        width: crosshairsWidth,
        height: gridHeight,
        fill: xcrosshairsFill,
        filter: shadow,
        "fill-opacity": w.config.xaxis.crosshairs.opacity,
        stroke: w.config.xaxis.crosshairs.stroke.color,
        "stroke-width": w.config.xaxis.crosshairs.stroke.width,
        "stroke-dasharray": w.config.xaxis.crosshairs.stroke.dashArray
      });
      if (dropShadow) {
        xcrosshairs = filters.dropShadow(xcrosshairs, {
          left: shadowLeft,
          top: shadowTop,
          blur: shadowBlur,
          color: shadowColor,
          opacity: shadowOpacity
        });
      }
      w.dom.elGraphical.add(xcrosshairs);
    }
  }
  drawYCrosshairs() {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const crosshair = (
      /** @type {any[]} */
      w.config.yaxis[0].crosshairs
    );
    const offX = w.globals.barPadForNumericAxis;
    if (
      /** @type {any[]} */
      w.config.yaxis[0].crosshairs.show
    ) {
      const ycrosshairs = graphics.drawLine(
        -offX,
        0,
        w.layout.gridWidth + offX,
        0,
        crosshair.stroke.color,
        crosshair.stroke.dashArray,
        crosshair.stroke.width
      );
      ycrosshairs.attr({
        class: "apexcharts-ycrosshairs"
      });
      w.dom.elGraphical.add(ycrosshairs);
    }
    const ycrosshairsHidden = graphics.drawLine(
      -offX,
      0,
      w.layout.gridWidth + offX,
      0,
      crosshair.stroke.color,
      0,
      0
    );
    ycrosshairsHidden.attr({
      class: "apexcharts-ycrosshairs-hidden"
    });
    w.dom.elGraphical.add(ycrosshairsHidden);
  }
}
class Responsive {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
    this._activeBreakpoint = null;
  }
  // the opts parameter if not null has to be set overriding everything
  // as the opts is set by user externally
  /**
   * @param {object} opts
   */
  checkResponsiveConfig(opts) {
    const w = this.w;
    const cnf = w.config;
    if (cnf.responsive.length === 0) return;
    const res = cnf.responsive.slice();
    res.sort(
      (a, b) => a.breakpoint > b.breakpoint ? 1 : b.breakpoint > a.breakpoint ? -1 : 0
    ).reverse();
    const config = new Config({});
    const iterateResponsiveOptions = (newOptions = {}) => {
      const largestBreakpoint = res[0].breakpoint;
      const width = Environment.isBrowser() ? window.innerWidth > 0 ? window.innerWidth : screen.width : 0;
      if (width > largestBreakpoint) {
        if (this._activeBreakpoint !== null) {
          if (!w.globals.initialConfig) return;
          const initialConfig = Utils$1.clone(w.globals.initialConfig);
          initialConfig.series = Utils$1.clone(w.config.series);
          const options2 = CoreUtils.extendArrayProps(config, initialConfig, w);
          newOptions = Utils$1.extend(options2, newOptions);
          this.overrideResponsiveOptions(newOptions);
          this._activeBreakpoint = null;
        }
      } else {
        for (let i = 0; i < res.length; i++) {
          if (width < res[i].breakpoint) {
            newOptions = CoreUtils.extendArrayProps(config, res[i].options, w);
            newOptions = Utils$1.extend(w.config, newOptions);
            this.overrideResponsiveOptions(newOptions);
            this._activeBreakpoint = res[i].breakpoint;
          }
        }
      }
    };
    if (opts) {
      let options2 = CoreUtils.extendArrayProps(config, opts, w);
      options2 = Utils$1.extend(w.config, options2);
      options2 = Utils$1.extend(options2, opts);
      iterateResponsiveOptions(options2);
    } else {
      iterateResponsiveOptions({});
    }
  }
  /**
   * @param {Record<string, any>} newOptions
   */
  overrideResponsiveOptions(newOptions) {
    const newConfig = new Config(newOptions).init({ responsiveOverride: true });
    this.w.config = /** @type {any} */
    newConfig;
  }
}
class Series {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {{ toggleDataSeries?: Function, revertDefaultAxisMinMax?: Function, updateSeries?: Function }} [callbacks]
   */
  constructor(w, {
    toggleDataSeries = void 0,
    revertDefaultAxisMinMax = void 0,
    updateSeries = void 0
  } = {}) {
    this.w = w;
    this._toggleDataSeries = toggleDataSeries || null;
    this._revertDefaultAxisMinMax = revertDefaultAxisMinMax || null;
    this._updateSeries = updateSeries || null;
    this.legendInactiveClass = "legend-mouseover-inactive";
  }
  clearSeriesCache() {
    const w = this.w;
    if (w.globals.cachedSelectors) {
      delete w.globals.cachedSelectors.allSeriesEls;
      delete w.globals.cachedSelectors.highlightSeriesEls;
    }
  }
  getAllSeriesEls() {
    const w = this.w;
    const cacheKey = "allSeriesEls";
    if (!w.globals.cachedSelectors[cacheKey]) {
      w.globals.cachedSelectors[cacheKey] = /** @type {any} */
      w.dom.baseEl.getElementsByClassName(`apexcharts-series`);
    }
    return w.globals.cachedSelectors[cacheKey];
  }
  /**
   * @param {string} seriesName
   */
  getSeriesByName(seriesName) {
    return this.w.dom.baseEl.querySelector(
      `.apexcharts-inner .apexcharts-series[seriesName='${Utils$1.escapeString(
        seriesName
      )}']`
    );
  }
  /**
   * @param {string} seriesName
   */
  isSeriesHidden(seriesName) {
    var _a;
    const targetElement = this.getSeriesByName(seriesName);
    const el = (
      /** @type {Element} */
      targetElement
    );
    const realIndex = parseInt((_a = el.getAttribute("data:realIndex")) != null ? _a : "0", 10);
    const isHidden = el.classList.contains("apexcharts-series-collapsed");
    return { isHidden, realIndex };
  }
  /**
   * @param {any} elSeries
   * @param {number} index
   */
  addCollapsedClassToSeries(elSeries, index) {
    Series.addCollapsedClassToSeries(this.w, elSeries, index);
  }
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {any} elSeries
   * @param {number} index
   */
  static addCollapsedClassToSeries(w, elSeries, index) {
    function iterateOnAllCollapsedSeries(series) {
      for (let cs = 0; cs < series.length; cs++) {
        if (series[cs].index === index) {
          elSeries.node.classList.add("apexcharts-series-collapsed");
        }
      }
    }
    iterateOnAllCollapsedSeries(w.globals.collapsedSeries);
    iterateOnAllCollapsedSeries(w.globals.ancillaryCollapsedSeries);
  }
  /**
   * @param {string} seriesName
   */
  toggleSeries(seriesName) {
    var _a;
    const isSeriesHidden = this.isSeriesHidden(seriesName);
    (_a = this._toggleDataSeries) == null ? void 0 : _a.call(this, isSeriesHidden.realIndex, isSeriesHidden.isHidden);
    return isSeriesHidden.isHidden;
  }
  /**
   * @param {string} seriesName
   */
  showSeries(seriesName) {
    var _a;
    const isSeriesHidden = this.isSeriesHidden(seriesName);
    if (isSeriesHidden.isHidden) {
      (_a = this._toggleDataSeries) == null ? void 0 : _a.call(this, isSeriesHidden.realIndex, true);
    }
  }
  /**
   * @param {string} seriesName
   */
  hideSeries(seriesName) {
    var _a;
    const isSeriesHidden = this.isSeriesHidden(seriesName);
    if (!isSeriesHidden.isHidden) {
      (_a = this._toggleDataSeries) == null ? void 0 : _a.call(this, isSeriesHidden.realIndex, false);
    }
  }
  resetSeries(shouldUpdateChart = true, shouldResetZoom = true, shouldResetCollapsed = true) {
    var _a, _b;
    const w = this.w;
    this.clearSeriesCache();
    let series = Utils$1.clone(w.globals.initialSeries);
    w.globals.previousPaths = [];
    if (shouldResetCollapsed) {
      w.globals.collapsedSeries = [];
      w.globals.ancillaryCollapsedSeries = [];
      w.globals.collapsedSeriesIndices = [];
      w.globals.ancillaryCollapsedSeriesIndices = [];
    } else {
      series = this.emptyCollapsedSeries(series);
    }
    w.config.series = series;
    if (shouldUpdateChart) {
      if (shouldResetZoom) {
        w.interact.zoomed = false;
        (_a = this._revertDefaultAxisMinMax) == null ? void 0 : _a.call(this);
      }
      (_b = this._updateSeries) == null ? void 0 : _b.call(
        this,
        series,
        w.config.chart.animations.dynamicAnimation.enabled
      );
    }
  }
  /**
   * @param {any[]} series
   */
  emptyCollapsedSeries(series) {
    const w = this.w;
    for (let i = 0; i < series.length; i++) {
      if (w.globals.collapsedSeriesIndices.indexOf(i) > -1) {
        series[i].data = [];
      }
    }
    return series;
  }
  /**
   * @param {string} seriesName
   */
  highlightSeries(seriesName) {
    var _a;
    const w = this.w;
    const targetElement = this.getSeriesByName(seriesName);
    const realIndex = parseInt(
      (_a = targetElement == null ? void 0 : targetElement.getAttribute("data:realIndex")) != null ? _a : "",
      10
    );
    const cacheKey = "highlightSeriesEls";
    let allSeriesEls = w.globals.cachedSelectors[cacheKey];
    if (!allSeriesEls) {
      allSeriesEls = w.dom.baseEl.querySelectorAll(
        `.apexcharts-series, .apexcharts-datalabels, .apexcharts-yaxis`
      );
      w.globals.cachedSelectors[cacheKey] = allSeriesEls;
    }
    let seriesEl = null;
    let dataLabelEl = null;
    let yaxisEl = null;
    if (w.globals.axisCharts || w.config.chart.type === "radialBar") {
      if (w.globals.axisCharts) {
        seriesEl = w.dom.baseEl.querySelector(
          `.apexcharts-series[data\\:realIndex='${realIndex}']`
        );
        dataLabelEl = w.dom.baseEl.querySelector(
          `.apexcharts-datalabels[data\\:realIndex='${realIndex}']`
        );
        const yaxisIndex = w.globals.seriesYAxisReverseMap[realIndex];
        yaxisEl = w.dom.baseEl.querySelector(
          `.apexcharts-yaxis[rel='${yaxisIndex}']`
        );
      } else {
        seriesEl = w.dom.baseEl.querySelector(
          `.apexcharts-series[rel='${realIndex + 1}']`
        );
      }
    } else {
      seriesEl = w.dom.baseEl.querySelector(
        `.apexcharts-series[rel='${realIndex + 1}'] path`
      );
    }
    for (let se = 0; se < allSeriesEls.length; se++) {
      const serEl = (
        /** @type {Element} */
        allSeriesEls[se]
      );
      serEl.classList.add(this.legendInactiveClass);
    }
    if (seriesEl) {
      if (!w.globals.axisCharts) {
        const parentEl = (
          /** @type {Element} */
          seriesEl.parentNode
        );
        parentEl == null ? void 0 : parentEl.classList.remove(this.legendInactiveClass);
      }
      seriesEl.classList.remove(this.legendInactiveClass);
      if (dataLabelEl !== null) {
        dataLabelEl.classList.remove(this.legendInactiveClass);
      }
      if (yaxisEl !== null) {
        yaxisEl.classList.remove(this.legendInactiveClass);
      }
    } else {
      for (let se = 0; se < allSeriesEls.length; se++) {
        const serEl = (
          /** @type {Element} */
          allSeriesEls[se]
        );
        serEl.classList.remove(this.legendInactiveClass);
      }
    }
  }
  /**
   * @param {Event} e
   * @param {any} targetElement
   */
  toggleSeriesOnHover(e, targetElement) {
    const w = this.w;
    if (!targetElement) targetElement = e.target;
    const allSeriesEls = w.dom.baseEl.querySelectorAll(
      `.apexcharts-series, .apexcharts-datalabels, .apexcharts-yaxis`
    );
    if (e.type === "mousemove") {
      const realIndex = parseInt(targetElement.getAttribute("rel"), 10) - 1;
      this.highlightSeries(w.seriesData.seriesNames[realIndex]);
    } else if (e.type === "mouseout") {
      for (let se = 0; se < allSeriesEls.length; se++) {
        allSeriesEls[se].classList.remove(this.legendInactiveClass);
      }
    }
  }
  /**
   * @param {Event} e
   * @param {any} targetElement
   */
  highlightRangeInSeries(e, targetElement) {
    const w = this.w;
    const allHeatMapElements = w.dom.baseEl.getElementsByClassName(
      "apexcharts-heatmap-rect"
    );
    const activeInactive = (action) => {
      for (let i = 0; i < allHeatMapElements.length; i++) {
        const actionFn = (
          /** @type {any} */
          allHeatMapElements[i].classList[action]
        );
        if (typeof actionFn === "function") {
          actionFn.call(
            /** @type {any} */
            allHeatMapElements[i].classList,
            this.legendInactiveClass
          );
        }
      }
    };
    const removeInactiveClassFromHoveredRange = (range, rangeMax) => {
      for (let i = 0; i < allHeatMapElements.length; i++) {
        const val = Number(allHeatMapElements[i].getAttribute("val"));
        if (val >= range.from && (val < range.to || range.to === rangeMax && val === rangeMax)) {
          allHeatMapElements[i].classList.remove(this.legendInactiveClass);
        }
      }
    };
    if (e.type === "mousemove") {
      const seriesCnt = parseInt(targetElement.getAttribute("rel"), 10) - 1;
      activeInactive("add");
      const ranges = w.config.plotOptions.heatmap.colorScale.ranges;
      const range = ranges[seriesCnt];
      const rangeMax = ranges.reduce(
        (acc, cur) => Math.max(acc, cur.to),
        0
      );
      removeInactiveClassFromHoveredRange(range, rangeMax);
    } else if (e.type === "mouseout") {
      activeInactive("remove");
    }
  }
  /**
   * @param {string[]} chartTypes
   */
  getActiveConfigSeriesIndex(order = "asc", chartTypes = []) {
    const w = this.w;
    let activeIndex = 0;
    if (w.config.series.length > 1) {
      const activeSeriesIndex = w.config.series.map((s, index) => {
        const checkChartType = () => {
          if (w.globals.comboCharts) {
            return chartTypes.length === 0 || chartTypes.length && chartTypes.indexOf(
              /** @type {Record<string,any>} */
              w.config.series[index].type
            ) > -1;
          }
          return true;
        };
        const hasData = (
          /** @type {any} */
          s.data && /** @type {any} */
          s.data.length > 0 && w.globals.collapsedSeriesIndices.indexOf(index) === -1
        );
        return hasData && checkChartType() ? index : -1;
      });
      for (let a = order === "asc" ? 0 : activeSeriesIndex.length - 1; order === "asc" ? a < activeSeriesIndex.length : a >= 0; order === "asc" ? a++ : a--) {
        if (activeSeriesIndex[a] !== -1) {
          activeIndex = activeSeriesIndex[a];
          break;
        }
      }
    }
    return activeIndex;
  }
  getBarSeriesIndices() {
    const w = this.w;
    if (w.globals.comboCharts) {
      return this.w.config.series.map((s, i) => {
        return s.type === "bar" || s.type === "column" ? i : -1;
      }).filter((i) => {
        return i !== -1;
      });
    }
    return this.w.config.series.map((s, i) => {
      return i;
    });
  }
  getPreviousPaths() {
    var _a, _b, _c, _d;
    const w = this.w;
    w.globals.previousPaths = [];
    function pushPaths(seriesEls, i, type) {
      const paths = seriesEls[i].childNodes;
      const dArr = {
        type,
        paths: (
          /** @type {any[]} */
          []
        ),
        realIndex: seriesEls[i].getAttribute("data:realIndex")
      };
      for (let j = 0; j < paths.length; j++) {
        if (paths[j].hasAttribute("pathTo")) {
          const d = paths[j].getAttribute("pathTo");
          dArr.paths.push({ d });
        }
      }
      w.globals.previousPaths.push(dArr);
    }
    const getPaths = (chartType) => {
      return w.dom.baseEl.querySelectorAll(
        `.apexcharts-${chartType}-series .apexcharts-series`
      );
    };
    const chartTypes = [
      "line",
      "area",
      "bar",
      "rangebar",
      "rangeArea",
      "candlestick",
      "radar"
    ];
    chartTypes.forEach((type) => {
      const paths = getPaths(type);
      for (let p = 0; p < paths.length; p++) {
        pushPaths(paths, p, type);
      }
    });
    const heatTreeSeries = w.dom.baseEl.querySelectorAll(
      `.apexcharts-${w.config.chart.type} .apexcharts-series`
    );
    if (heatTreeSeries.length > 0) {
      for (let h = 0; h < heatTreeSeries.length; h++) {
        const seriesEls = w.dom.baseEl.querySelectorAll(
          `.apexcharts-${w.config.chart.type} .apexcharts-series[data\\:realIndex='${h}'] rect`
        );
        const dArr = [];
        for (let i = 0; i < seriesEls.length; i++) {
          const getAttr = (x) => {
            return (
              /** @type {Element} */
              seriesEls[i].getAttribute(x)
            );
          };
          const rect = {
            x: parseFloat((_a = getAttr("x")) != null ? _a : "0"),
            y: parseFloat((_b = getAttr("y")) != null ? _b : "0"),
            width: parseFloat((_c = getAttr("width")) != null ? _c : "0"),
            height: parseFloat((_d = getAttr("height")) != null ? _d : "0")
          };
          dArr.push({
            rect,
            color: seriesEls[i].getAttribute("color")
          });
        }
        w.globals.previousPaths.push(dArr);
      }
    }
    if (!w.globals.axisCharts) {
      w.globals.previousPaths = w.seriesData.series;
    }
  }
  clearPreviousPaths() {
    const w = this.w;
    w.globals.previousPaths = [];
    w.globals.allSeriesCollapsed = false;
  }
  handleNoData() {
    const w = this.w;
    const me = this;
    const noDataOpts = w.config.noData;
    const graphics = new Graphics(me.w);
    let x = w.globals.svgWidth / 2;
    let y = w.globals.svgHeight / 2;
    let textAnchor = "middle";
    w.globals.noData = true;
    w.globals.animationEnded = true;
    if (noDataOpts.align === "left") {
      x = 10;
      textAnchor = "start";
    } else if (noDataOpts.align === "right") {
      x = w.globals.svgWidth - 10;
      textAnchor = "end";
    }
    if (noDataOpts.verticalAlign === "top") {
      y = 50;
    } else if (noDataOpts.verticalAlign === "bottom") {
      y = w.globals.svgHeight - 50;
    }
    x = x + noDataOpts.offsetX;
    y = y + parseInt(noDataOpts.style.fontSize, 10) + 2 + noDataOpts.offsetY;
    if (noDataOpts.text !== void 0 && noDataOpts.text !== "") {
      const titleText = graphics.drawText({
        x,
        y,
        text: noDataOpts.text,
        textAnchor,
        fontSize: noDataOpts.style.fontSize,
        fontFamily: noDataOpts.style.fontFamily,
        foreColor: noDataOpts.style.color,
        opacity: 1,
        cssClass: "apexcharts-text-nodata"
      });
      w.dom.Paper.add(titleText);
    }
  }
  // When user clicks on legends, the collapsed series is filled with [0,0,0,...,0]
  // This is because we don't want to alter the series' length as it is used at many places
  /**
   * @param {any[]} series
   */
  setNullSeriesToZeroValues(series) {
    const w = this.w;
    for (let sl = 0; sl < series.length; sl++) {
      if (series[sl].length === 0) {
        for (let j = 0; j < series[w.globals.maxValsInArrayIndex].length; j++) {
          series[sl].push(0);
        }
      }
    }
    return series;
  }
  hasAllSeriesEqualX() {
    let equalLen = true;
    const w = this.w;
    const filteredSerX = this.filteredSeriesX();
    for (let i = 0; i < filteredSerX.length - 1; i++) {
      if (filteredSerX[i][0] !== filteredSerX[i + 1][0]) {
        equalLen = false;
        break;
      }
    }
    w.globals.allSeriesHasEqualX = equalLen;
    return equalLen;
  }
  filteredSeriesX() {
    const w = this.w;
    const filteredSeriesX = w.seriesData.seriesX.map(
      (ser) => ser.length > 0 ? ser : []
    );
    return filteredSeriesX;
  }
}
class Theme {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
    this.colors = [];
    this.isColorFn = false;
    this.isHeatmapDistributed = this.checkHeatmapDistributed();
    this.isBarDistributed = this.checkBarDistributed();
  }
  checkHeatmapDistributed() {
    const { chart, plotOptions } = this.w.config;
    return chart.type === "treemap" && plotOptions.treemap && plotOptions.treemap.distributed || chart.type === "heatmap" && plotOptions.heatmap && plotOptions.heatmap.distributed;
  }
  checkBarDistributed() {
    const { chart, plotOptions } = this.w.config;
    return plotOptions.bar && plotOptions.bar.distributed && (chart.type === "bar" || chart.type === "rangeBar");
  }
  init() {
    this.setDefaultColors();
  }
  setDefaultColors() {
    var _a;
    const w = this.w;
    const utils = new Utils$1();
    w.dom.elWrap.classList.add(
      `apexcharts-theme-${w.config.theme.mode || "light"}`
    );
    const colorBlindMode = (_a = w.config.theme.accessibility) == null ? void 0 : _a.colorBlindMode;
    if (colorBlindMode) {
      w.globals.colors = this.getColorBlindColors(colorBlindMode);
      this.applySeriesColors(w.seriesData.seriesColors, w.globals.colors);
      const defaultColors2 = w.globals.colors.slice();
      this.pushExtraColors(w.globals.colors);
      this.applyColorTypes(["fill", "stroke"], defaultColors2);
      this.applyDataLabelsColors(defaultColors2);
      this.applyRadarPolygonsColors();
      this.applyMarkersColors(defaultColors2);
      if (colorBlindMode === "highContrast") {
        w.dom.elWrap.classList.add("apexcharts-high-contrast");
      }
      return;
    }
    const configColors = [...w.config.colors || w.config.fill.colors || []];
    w.globals.colors = this.getColors(configColors);
    this.applySeriesColors(w.seriesData.seriesColors, w.globals.colors);
    if (w.config.theme.monochrome.enabled) {
      w.globals.colors = this.getMonochromeColors(
        w.config.theme.monochrome,
        w.seriesData.series,
        utils
      );
    }
    const defaultColors = w.globals.colors.slice();
    this.pushExtraColors(w.globals.colors);
    this.applyColorTypes(["fill", "stroke"], defaultColors);
    this.applyDataLabelsColors(defaultColors);
    this.applyRadarPolygonsColors();
    this.applyMarkersColors(defaultColors);
  }
  /**
   * @param {any[]} configColors
   */
  getColors(configColors) {
    const w = this.w;
    if (!configColors || configColors.length === 0) {
      return this.predefined();
    }
    if (Array.isArray(configColors) && configColors.length > 0 && typeof configColors[0] === "function") {
      this.isColorFn = true;
      return w.config.series.map((s, i) => {
        const c = configColors[i] || configColors[0];
        return typeof c === "function" ? c({
          value: w.globals.axisCharts ? w.seriesData.series[i][0] || 0 : w.seriesData.series[i],
          seriesIndex: i,
          dataPointIndex: i,
          w: this.w
        }) : c;
      });
    }
    return configColors;
  }
  /**
   * @param {any[]} seriesColors
   * @param {any[]} globalsColors
   */
  applySeriesColors(seriesColors, globalsColors) {
    seriesColors.forEach((c, i) => {
      if (c) {
        globalsColors[i] = c;
      }
    });
  }
  /**
   * @param {Record<string, any>} monochrome
   * @param {any[]} series
   * @param {any} utils
   */
  getMonochromeColors(monochrome, series, utils) {
    const { color, shadeIntensity, shadeTo } = monochrome;
    const glsCnt = this.isBarDistributed || this.isHeatmapDistributed ? series[0].length * series.length : series.length;
    const part = 1 / (glsCnt / shadeIntensity);
    let percent = 0;
    return Array.from({ length: glsCnt }, () => {
      const newColor = shadeTo === "dark" ? utils.shadeColor(percent * -1, color) : utils.shadeColor(percent, color);
      percent += part;
      return newColor;
    });
  }
  /**
   * @param {string[]} colorTypes
   * @param {string[]} defaultColors
   */
  applyColorTypes(colorTypes, defaultColors) {
    const w = this.w;
    colorTypes.forEach((c) => {
      w.globals[c].colors = w.config[c].colors === void 0 ? this.isColorFn ? w.config.colors : defaultColors : w.config[c].colors.slice();
      this.pushExtraColors(
        /** @type {Record<string,any>} */
        w.globals[c].colors
      );
    });
  }
  /**
   * @param {string[]} defaultColors
   */
  applyDataLabelsColors(defaultColors) {
    const w = this.w;
    w.globals.dataLabels.style.colors = w.config.dataLabels.style.colors === void 0 ? defaultColors : w.config.dataLabels.style.colors.slice();
    this.pushExtraColors(w.globals.dataLabels.style.colors, 50);
  }
  applyRadarPolygonsColors() {
    const w = this.w;
    w.globals.radarPolygons.fill.colors = w.config.plotOptions.radar.polygons.fill.colors === void 0 ? [w.config.theme.mode === "dark" ? "#343A3F" : "none"] : w.config.plotOptions.radar.polygons.fill.colors.slice();
    this.pushExtraColors(w.globals.radarPolygons.fill.colors, 20);
  }
  /**
   * @param {string[]} defaultColors
   */
  applyMarkersColors(defaultColors) {
    const w = this.w;
    w.globals.markers.colors = w.config.markers.colors === void 0 ? defaultColors : w.config.markers.colors.slice();
    this.pushExtraColors(w.globals.markers.colors);
  }
  /**
   * @param {any} colorSeries
   * @param {number} [length]
   * @param {boolean | null} [distributed]
   */
  pushExtraColors(colorSeries, length, distributed = null) {
    const w = this.w;
    let len = length || w.seriesData.series.length;
    if (distributed === null) {
      distributed = this.isBarDistributed || this.isHeatmapDistributed || w.config.chart.type === "heatmap" && w.config.plotOptions.heatmap && w.config.plotOptions.heatmap.colorScale.inverse;
    }
    if (distributed && w.seriesData.series.length) {
      len = w.seriesData.series[w.globals.maxValsInArrayIndex].length * w.seriesData.series.length;
    }
    if (colorSeries.length < len) {
      const diff = len - colorSeries.length;
      for (let i = 0; i < diff; i++) {
        colorSeries.push(colorSeries[i]);
      }
    }
  }
  /**
   * @param {'light' | 'dark'} mode
   */
  getColorBlindColors(mode) {
    const palettes = getThemePalettes();
    const map = {
      deuteranopia: palettes.cvdDeuteranopia,
      protanopia: palettes.cvdProtanopia,
      tritanopia: palettes.cvdTritanopia,
      highContrast: palettes.highContrast
    };
    return (
      /** @type {Record<string,any>} */
      /** @type {any} */
      (map[mode] || palettes.palette1).slice()
    );
  }
  /**
   * @param {Record<string, any>} options
   */
  updateThemeOptions(options2) {
    options2.chart = options2.chart || {};
    options2.tooltip = options2.tooltip || {};
    const mode = options2.theme.mode;
    const palette = mode === "dark" ? "palette4" : mode === "light" ? "palette1" : options2.theme.palette || "palette1";
    const foreColor = mode === "dark" ? "#f6f7f8" : mode === "light" ? "#373d3f" : options2.chart.foreColor || "#373d3f";
    options2.tooltip.theme = mode || "light";
    options2.chart.foreColor = foreColor;
    options2.theme.palette = palette;
    return options2;
  }
  predefined() {
    const palette = this.w.config.theme.palette;
    const palettes = getThemePalettes();
    return (
      /** @type {Record<string,any>} */
      palettes[palette] || palettes.palette1
    );
  }
}
class TitleSubtitle {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
  }
  draw() {
    this.drawTitleSubtitle("title");
    this.drawTitleSubtitle("subtitle");
  }
  /**
   * @param {'title' | 'subtitle'} type
   */
  drawTitleSubtitle(type) {
    const w = this.w;
    const tsConfig = type === "title" ? w.config.title : w.config.subtitle;
    let x = w.globals.svgWidth / 2;
    let y = tsConfig.offsetY;
    let textAnchor = "middle";
    if (tsConfig.align === "left") {
      x = 10;
      textAnchor = "start";
    } else if (tsConfig.align === "right") {
      x = w.globals.svgWidth - 10;
      textAnchor = "end";
    }
    x = x + tsConfig.offsetX;
    y = y + parseInt(tsConfig.style.fontSize, 10) + tsConfig.margin / 2;
    if (tsConfig.text !== void 0) {
      const graphics = new Graphics(this.w);
      const titleText = graphics.drawText({
        x,
        y,
        text: tsConfig.text,
        textAnchor,
        fontSize: tsConfig.style.fontSize,
        fontFamily: tsConfig.style.fontFamily,
        fontWeight: tsConfig.style.fontWeight,
        foreColor: tsConfig.style.color,
        opacity: 1
      });
      titleText.node.setAttribute("class", `apexcharts-${type}-text`);
      w.dom.Paper.add(titleText);
    }
  }
}
let Helpers$4 = class Helpers {
  /**
   * @param {import('./Dimensions').default} dCtx
   */
  constructor(dCtx) {
    this.w = dCtx.w;
    this.dCtx = dCtx;
  }
  /**
   * Get Chart Title/Subtitle Dimensions
   * @memberof Dimensions
   * @return {{width: number, height: number}}
   * @param {string} type
   **/
  getTitleSubtitleCoords(type) {
    const w = this.w;
    let width = 0;
    let height = 0;
    const floating = type === "title" ? w.config.title.floating : w.config.subtitle.floating;
    const el = w.dom.baseEl.querySelector(`.apexcharts-${type}-text`);
    if (el !== null && !floating) {
      const coord = el.getBoundingClientRect();
      width = coord.width;
      height = w.globals.axisCharts ? coord.height + 5 : coord.height;
    }
    return {
      width,
      height
    };
  }
  getLegendsRect() {
    const w = this.w;
    const elLegendWrap = w.dom.elLegendWrap;
    if (!w.config.legend.height && (w.config.legend.position === "top" || w.config.legend.position === "bottom")) {
      if (elLegendWrap)
        elLegendWrap.style.maxHeight = w.globals.svgHeight / 2 + "px";
    }
    const lgRect = (
      /** @type {any} */
      Object.assign({}, Utils$1.getBoundingClientRect(elLegendWrap))
    );
    if (elLegendWrap !== null && !w.config.legend.floating && w.config.legend.show) {
      this.dCtx.lgRect = {
        x: lgRect.x,
        y: lgRect.y,
        height: lgRect.height,
        width: lgRect.height === 0 ? 0 : lgRect.width
      };
    } else {
      this.dCtx.lgRect = {
        x: 0,
        y: 0,
        height: 0,
        width: 0
      };
    }
    if (w.config.legend.position === "left" || w.config.legend.position === "right") {
      if (this.dCtx.lgRect.width * 1.5 > w.globals.svgWidth) {
        this.dCtx.lgRect.width = w.globals.svgWidth / 1.5;
      }
    }
    return this.dCtx.lgRect;
  }
  /**
   * Get Y Axis Dimensions
   * @memberof Dimensions
   * @return {{width: number, height: number}}
   **/
  getDatalabelsRect() {
    const w = this.w;
    const allLabels = [];
    w.config.series.forEach(
      (serie, seriesIndex) => {
        serie.data.forEach(
          (datum, dataPointIndex) => {
            const getText = (v) => {
              return w.config.dataLabels.formatter(v, {
                seriesIndex,
                dataPointIndex,
                w
              });
            };
            const labelText = getText(
              w.seriesData.series[seriesIndex][dataPointIndex]
            );
            allLabels.push(labelText);
          }
        );
      }
    );
    const val = Utils$1.getLargestStringFromArr(allLabels);
    const graphics = new Graphics(this.w);
    const dataLabelsStyle = w.config.dataLabels.style;
    const labelrect = graphics.getTextRects(
      val,
      parseInt(dataLabelsStyle.fontSize).toString(),
      dataLabelsStyle.fontFamily
    );
    return {
      width: labelrect.width * 1.05,
      height: labelrect.height
    };
  }
  /**
   * @param {any} val
   * @param {any[]} arr
   */
  getLargestStringFromMultiArr(val, arr) {
    const w = this.w;
    let valArr = val;
    if (w.axisFlags.isMultiLineX) {
      const maxArrs = arr.map((xl) => {
        return Array.isArray(xl) ? xl.length : 1;
      });
      const maxArrLen = Math.max(...maxArrs);
      const maxArrIndex = maxArrs.indexOf(maxArrLen);
      valArr = arr[maxArrIndex];
    }
    return valArr;
  }
};
class DimXAxis {
  /**
   * @param {import('./Dimensions').default} dCtx
   */
  constructor(dCtx) {
    this.w = dCtx.w;
    this.dCtx = dCtx;
  }
  /**
   * Get X Axis Dimensions
   * @memberof Dimensions
   * @return {{width: number, height: number}}
   **/
  getxAxisLabelsCoords() {
    const w = this.w;
    let xaxisLabels = w.labelData.labels.slice();
    if (w.config.xaxis.convertedCatToNumeric && xaxisLabels.length === 0) {
      xaxisLabels = w.labelData.categoryLabels;
    }
    let rect;
    if (w.labelData.timescaleLabels.length > 0) {
      const coords = this.getxAxisTimeScaleLabelsCoords();
      rect = {
        width: coords.width,
        height: coords.height
      };
      w.layout.rotateXLabels = false;
    } else {
      this.dCtx.lgWidthForSideLegends = (w.config.legend.position === "left" || w.config.legend.position === "right") && !w.config.legend.floating ? this.dCtx.lgRect.width : 0;
      const xlbFormatter = w.formatters.xLabelFormatter;
      let val = Utils$1.getLargestStringFromArr(xaxisLabels);
      let valArr = this.dCtx.dimHelpers.getLargestStringFromMultiArr(
        val,
        xaxisLabels
      );
      if (w.globals.isBarHorizontal) {
        val = w.globals.yAxisScale[0].result.reduce(
          (a, b) => a.length > b.length ? a : b,
          0
        );
        valArr = val;
      }
      const xFormat = new Formatters(this.w);
      const timestamp = val;
      val = xFormat.xLabelFormat(
        /** @type {Function} */
        xlbFormatter,
        val,
        timestamp,
        {
          i: void 0,
          dateFormatter: new DateTime(this.w).formatDate,
          w
        }
      );
      valArr = xFormat.xLabelFormat(
        /** @type {Function} */
        xlbFormatter,
        valArr,
        timestamp,
        {
          i: void 0,
          dateFormatter: new DateTime(this.w).formatDate,
          w
        }
      );
      if (w.config.xaxis.convertedCatToNumeric && typeof val === "undefined" || String(val).trim() === "") {
        val = "1";
        valArr = val;
      }
      const graphics = new Graphics(this.w);
      let xLabelrect = graphics.getTextRects(
        val,
        w.config.xaxis.labels.style.fontSize
      );
      let xArrLabelrect = xLabelrect;
      if (val !== valArr) {
        xArrLabelrect = graphics.getTextRects(
          valArr,
          w.config.xaxis.labels.style.fontSize
        );
      }
      rect = {
        width: xLabelrect.width >= xArrLabelrect.width ? xLabelrect.width : xArrLabelrect.width,
        height: xLabelrect.height >= xArrLabelrect.height ? xLabelrect.height : xArrLabelrect.height
      };
      if (rect.width * xaxisLabels.length > w.globals.svgWidth - this.dCtx.lgWidthForSideLegends - this.dCtx.yAxisWidth - this.dCtx.gridPad.left - this.dCtx.gridPad.right && w.config.xaxis.labels.rotate !== 0 || w.config.xaxis.labels.rotateAlways) {
        if (!w.globals.isBarHorizontal) {
          w.layout.rotateXLabels = true;
          const getRotatedTextRects = (text) => {
            return graphics.getTextRects(
              text,
              w.config.xaxis.labels.style.fontSize,
              w.config.xaxis.labels.style.fontFamily,
              `rotate(${w.config.xaxis.labels.rotate} 0 0)`,
              false
            );
          };
          xLabelrect = getRotatedTextRects(val);
          if (val !== valArr) {
            xArrLabelrect = getRotatedTextRects(valArr);
          }
          rect.height = (xLabelrect.height > xArrLabelrect.height ? xLabelrect.height : xArrLabelrect.height) / 1.5;
          rect.width = xLabelrect.width > xArrLabelrect.width ? xLabelrect.width : xArrLabelrect.width;
        }
      } else {
        w.layout.rotateXLabels = false;
      }
    }
    if (!w.config.xaxis.labels.show) {
      rect = {
        width: 0,
        height: 0
      };
    }
    return {
      width: rect.width,
      height: rect.height
    };
  }
  /**
   * Get X Axis Label Group height
   * @memberof Dimensions
   * @return {{width: number, height: number}}
   */
  getxAxisGroupLabelsCoords() {
    var _a;
    const w = this.w;
    if (!w.labelData.hasXaxisGroups) {
      return { width: 0, height: 0 };
    }
    const fontSize = ((_a = w.config.xaxis.group.style) == null ? void 0 : _a.fontSize) || w.config.xaxis.labels.style.fontSize;
    const xaxisLabels = w.labelData.groups.map(
      (g) => g.title
    );
    let rect;
    const val = Utils$1.getLargestStringFromArr(xaxisLabels);
    const valArr = this.dCtx.dimHelpers.getLargestStringFromMultiArr(
      val,
      xaxisLabels
    );
    const graphics = new Graphics(this.w);
    const xLabelrect = graphics.getTextRects(val, fontSize);
    let xArrLabelrect = xLabelrect;
    if (val !== valArr) {
      xArrLabelrect = graphics.getTextRects(valArr, fontSize);
    }
    rect = {
      width: xLabelrect.width >= xArrLabelrect.width ? xLabelrect.width : xArrLabelrect.width,
      height: xLabelrect.height >= xArrLabelrect.height ? xLabelrect.height : xArrLabelrect.height
    };
    if (!w.config.xaxis.labels.show) {
      rect = {
        width: 0,
        height: 0
      };
    }
    return {
      width: rect.width,
      height: rect.height
    };
  }
  /**
   * Get X Axis Title Dimensions
   * @memberof Dimensions
   * @return {{width: number, height: number}}
   **/
  getxAxisTitleCoords() {
    const w = this.w;
    let width = 0;
    let height = 0;
    if (w.config.xaxis.title.text !== void 0) {
      const graphics = new Graphics(this.w);
      const rect = graphics.getTextRects(
        w.config.xaxis.title.text,
        w.config.xaxis.title.style.fontSize
      );
      width = rect.width;
      height = rect.height;
    }
    return {
      width,
      height
    };
  }
  getxAxisTimeScaleLabelsCoords() {
    const w = this.w;
    this.dCtx.timescaleLabels = w.labelData.timescaleLabels.slice();
    const labels = this.dCtx.timescaleLabels.map(
      (label) => label.value
    );
    const val = labels.reduce((a, b) => {
      if (typeof a === "undefined") {
        console.error(
          "You have possibly supplied invalid Date format. Please supply a valid JavaScript Date"
        );
        return 0;
      } else {
        return a.length > b.length ? a : b;
      }
    }, 0);
    const graphics = new Graphics(this.w);
    const rect = graphics.getTextRects(
      val,
      w.config.xaxis.labels.style.fontSize
    );
    const totalWidthRotated = rect.width * 1.05 * labels.length;
    if (totalWidthRotated > w.layout.gridWidth && w.config.xaxis.labels.rotate !== 0) {
      w.globals.overlappingXLabels = true;
    }
    return rect;
  }
  // In certain cases, the last labels gets cropped in xaxis.
  // Hence, we add some additional padding based on the label length to avoid the last label being cropped or we don't draw it at all
  /**
   * @param {Record<string, any>} xaxisLabelCoords
   */
  additionalPaddingXLabels(xaxisLabelCoords) {
    const w = this.w;
    const gl = w.globals;
    const cnf = w.config;
    const xtype = cnf.xaxis.type;
    const lbWidth = xaxisLabelCoords.width;
    gl.skipLastTimelinelabel = false;
    gl.skipFirstTimelinelabel = false;
    const isBarOpposite = w.config.yaxis[0].opposite && w.globals.isBarHorizontal;
    const isCollapsed = (i) => gl.collapsedSeriesIndices.indexOf(i) !== -1;
    const rightPad = (yaxe) => {
      if (this.dCtx.timescaleLabels && this.dCtx.timescaleLabels.length) {
        const firstimescaleLabel = this.dCtx.timescaleLabels[0];
        const lastTimescaleLabel = this.dCtx.timescaleLabels[this.dCtx.timescaleLabels.length - 1];
        const lastLabelPosition = lastTimescaleLabel.position + lbWidth / 1.75 - this.dCtx.yAxisWidthRight;
        const firstLabelPosition = firstimescaleLabel.position - lbWidth / 1.75 + this.dCtx.yAxisWidthLeft;
        const lgRightRectWidth = w.config.legend.position === "right" && this.dCtx.lgRect.width > 0 ? this.dCtx.lgRect.width : 0;
        if (lastLabelPosition > gl.svgWidth - w.layout.translateX - lgRightRectWidth) {
          gl.skipLastTimelinelabel = true;
        }
        if (firstLabelPosition < -((!yaxe.show || yaxe.floating) && (cnf.chart.type === "bar" || cnf.chart.type === "candlestick" || cnf.chart.type === "rangeBar" || cnf.chart.type === "boxPlot") ? lbWidth / 1.75 : 10)) {
          gl.skipFirstTimelinelabel = true;
        }
      } else if (xtype === "datetime") {
        if (this.dCtx.gridPad.right < lbWidth && !w.layout.rotateXLabels) {
          gl.skipLastTimelinelabel = true;
        }
      } else if (xtype !== "datetime") {
        if (this.dCtx.gridPad.right < lbWidth / 2 - this.dCtx.yAxisWidthRight && !w.layout.rotateXLabels && !w.config.xaxis.labels.trim) {
          this.dCtx.xPadRight = lbWidth / 2 + 1;
        }
      }
    };
    const padYAxe = (yaxe, i) => {
      if (cnf.yaxis.length > 1 && isCollapsed(i)) return;
      rightPad(yaxe);
    };
    cnf.yaxis.forEach((yaxe, i) => {
      if (isBarOpposite) {
        if (this.dCtx.gridPad.left < lbWidth) {
          this.dCtx.xPadLeft = lbWidth / 2 + 1;
        }
        this.dCtx.xPadRight = lbWidth / 2 + 1;
      } else {
        padYAxe(yaxe, i);
      }
    });
  }
}
class DimYAxis {
  /**
   * @param {import('./Dimensions').default} dCtx
   */
  constructor(dCtx) {
    this.w = dCtx.w;
    this.dCtx = dCtx;
  }
  /**
   * Get Y Axis Dimensions
   * @memberof Dimensions
   * @returns {Array<{width: number, height: number}>}
   **/
  getyAxisLabelsCoords() {
    const w = this.w;
    const width = 0;
    const height = 0;
    const ret = [];
    let labelPad = 10;
    const axesUtils = new AxesUtils(this.w, { theme: this.dCtx.theme, timeScale: this.dCtx.timeScale });
    w.config.yaxis.map((yaxe, index) => {
      const formatterArgs = {
        seriesIndex: index,
        dataPointIndex: -1,
        w
      };
      const yS = w.globals.yAxisScale[index];
      let yAxisMinWidth = 0;
      if (!axesUtils.isYAxisHidden(index) && yaxe.labels.show && yaxe.labels.minWidth !== void 0)
        yAxisMinWidth = yaxe.labels.minWidth;
      if (!axesUtils.isYAxisHidden(index) && yaxe.labels.show && yS.result.length) {
        const lbFormatter = w.formatters.yLabelFormatters[index];
        const minV = yS.niceMin === Number.MIN_VALUE ? 0 : yS.niceMin;
        let val = yS.result.reduce((acc, curr) => {
          var _a, _b;
          return ((_a = String(lbFormatter(acc, formatterArgs))) == null ? void 0 : _a.length) > ((_b = String(lbFormatter(curr, formatterArgs))) == null ? void 0 : _b.length) ? acc : curr;
        }, minV);
        val = lbFormatter(val, formatterArgs);
        let valArr = val;
        if (typeof val === "undefined" || val.length === 0) {
          val = yS.niceMax;
        }
        if (String(val).length === 1) {
          val = val + ".0";
          valArr = val;
        }
        if (w.globals.isBarHorizontal) {
          labelPad = 0;
          const barYaxisLabels = w.labelData.labels.slice();
          val = Utils$1.getLargestStringFromArr(barYaxisLabels);
          val = lbFormatter(val, { seriesIndex: index, dataPointIndex: -1, w });
          valArr = this.dCtx.dimHelpers.getLargestStringFromMultiArr(
            val,
            barYaxisLabels
          );
        }
        const graphics = new Graphics(this.w);
        const rotateStr = "rotate(".concat(yaxe.labels.rotate, " 0 0)");
        const rect = graphics.getTextRects(
          val,
          yaxe.labels.style.fontSize,
          yaxe.labels.style.fontFamily,
          rotateStr,
          false
        );
        let arrLabelrect = rect;
        if (val !== valArr) {
          arrLabelrect = graphics.getTextRects(
            valArr,
            yaxe.labels.style.fontSize,
            yaxe.labels.style.fontFamily,
            rotateStr,
            false
          );
        }
        ret.push({
          width: (yAxisMinWidth > arrLabelrect.width || yAxisMinWidth > rect.width ? yAxisMinWidth : arrLabelrect.width > rect.width ? arrLabelrect.width : rect.width) + labelPad,
          height: arrLabelrect.height > rect.height ? arrLabelrect.height : rect.height
        });
      } else {
        ret.push({
          width,
          height
        });
      }
    });
    return ret;
  }
  /**
   * Get Y Axis Dimensions
   * @memberof Dimensions
   * @returns {Array<{width: number, height: number}>}
   **/
  getyAxisTitleCoords() {
    const w = this.w;
    const ret = [];
    w.config.yaxis.map((yaxe) => {
      if (yaxe.show && yaxe.title.text !== void 0) {
        const graphics = new Graphics(this.w);
        const rotateStr = "rotate(".concat(yaxe.title.rotate, " 0 0)");
        const rect = graphics.getTextRects(
          yaxe.title.text,
          yaxe.title.style.fontSize,
          yaxe.title.style.fontFamily,
          rotateStr,
          false
        );
        ret.push({
          width: rect.width,
          height: rect.height
        });
      } else {
        ret.push({
          width: 0,
          height: 0
        });
      }
    });
    return ret;
  }
  getTotalYAxisWidth() {
    const w = this.w;
    let yAxisWidth = 0;
    let yAxisWidthLeft = 0;
    let yAxisWidthRight = 0;
    const padding = w.globals.yAxisScale.length > 1 ? 10 : 0;
    const axesUtils = new AxesUtils(this.w, { theme: this.dCtx.theme, timeScale: this.dCtx.timeScale });
    const isHiddenYAxis = function(index) {
      return w.globals.ignoreYAxisIndexes.indexOf(index) > -1;
    };
    const padForLabelTitle = (coord, index) => {
      const floating = w.config.yaxis[index].floating;
      let width = 0;
      if (coord.width > 0 && !floating) {
        width = coord.width + padding;
        if (isHiddenYAxis(index)) {
          width = width - coord.width - padding;
        }
      } else {
        width = floating || axesUtils.isYAxisHidden(index) ? 0 : 5;
      }
      w.config.yaxis[index].opposite ? yAxisWidthRight = yAxisWidthRight + width : yAxisWidthLeft = yAxisWidthLeft + width;
      yAxisWidth = yAxisWidth + width;
    };
    w.layout.yLabelsCoords.map((yLabelCoord, index) => {
      padForLabelTitle(yLabelCoord, index);
    });
    w.layout.yTitleCoords.map((yTitleCoord, index) => {
      padForLabelTitle(yTitleCoord, index);
    });
    if (w.globals.isBarHorizontal && !w.config.yaxis[0].floating) {
      yAxisWidth = w.layout.yLabelsCoords[0].width + w.layout.yTitleCoords[0].width + 15;
    }
    this.dCtx.yAxisWidthLeft = yAxisWidthLeft;
    this.dCtx.yAxisWidthRight = yAxisWidthRight;
    return yAxisWidth;
  }
}
class DimGrid {
  /**
   * @param {import('./Dimensions').default} dCtx
   */
  constructor(dCtx) {
    this.w = dCtx.w;
    this.dCtx = dCtx;
  }
  /**
   * @param {number} gridWidth
   */
  gridPadForColumnsInNumericAxis(gridWidth) {
    const { w } = this;
    const { config: cnf, globals: gl } = w;
    if (gl.noData || gl.collapsedSeries.length + gl.ancillaryCollapsedSeries.length === cnf.series.length) {
      return 0;
    }
    const hasBar = (type2) => ["bar", "rangeBar", "candlestick", "boxPlot"].includes(type2);
    const type = cnf.chart.type;
    let barWidth = 0;
    let seriesLen = hasBar(type) ? cnf.series.length : 1;
    if (gl.comboBarCount > 0) {
      seriesLen = gl.comboBarCount;
    }
    gl.collapsedSeries.forEach((c) => {
      if (hasBar(c.type)) {
        seriesLen -= 1;
      }
    });
    if (cnf.chart.stacked) {
      seriesLen = 1;
    }
    const barsPresent = hasBar(type) || gl.comboBarCount > 0;
    let xRange = Math.abs(gl.initialMaxX - gl.initialMinX);
    if (barsPresent && w.axisFlags.isXNumeric && !gl.isBarHorizontal && seriesLen > 0 && xRange !== 0) {
      if (xRange <= 3) {
        xRange = gl.dataPoints;
      }
      const xRatio = xRange / gridWidth;
      let xDivision = gl.minXDiff && gl.minXDiff / xRatio > 0 ? gl.minXDiff / xRatio : 0;
      if (xDivision > gridWidth / 2) {
        xDivision /= 2;
      }
      barWidth = xDivision * parseInt(cnf.plotOptions.bar.columnWidth, 10) / 100;
      if (barWidth < 1) {
        barWidth = 1;
      }
      gl.barPadForNumericAxis = barWidth;
    }
    return barWidth;
  }
  gridPadFortitleSubtitle() {
    const { w } = this;
    const { globals: gl } = w;
    let gridShrinkOffset = this.dCtx.isSparkline || !gl.axisCharts ? 0 : 10;
    const titleSubtitle = ["title", "subtitle"];
    titleSubtitle.forEach((t) => {
      if (w.config[t].text !== void 0) {
        gridShrinkOffset += w.config[t].margin;
      } else {
        gridShrinkOffset += this.dCtx.isSparkline || !gl.axisCharts ? 0 : 5;
      }
    });
    if (w.config.legend.show && w.config.legend.position === "bottom" && !w.config.legend.floating && !gl.axisCharts) {
      gridShrinkOffset += 10;
    }
    const titleCoords = this.dCtx.dimHelpers.getTitleSubtitleCoords("title");
    const subtitleCoords = this.dCtx.dimHelpers.getTitleSubtitleCoords("subtitle");
    w.layout.gridHeight -= titleCoords.height + subtitleCoords.height + gridShrinkOffset;
    w.layout.translateY += titleCoords.height + subtitleCoords.height + gridShrinkOffset;
  }
  /**
   * @param {{width: number, height: number}[]} yTitleCoords
   * @param {{width: number, height: number}[]} yaxisLabelCoords
   */
  setGridXPosForDualYAxis(yTitleCoords, yaxisLabelCoords) {
    const { w } = this;
    const axesUtils = new AxesUtils(this.w, { theme: this.dCtx.theme, timeScale: this.dCtx.timeScale });
    w.config.yaxis.forEach((yaxe, index) => {
      if (w.globals.ignoreYAxisIndexes.indexOf(index) === -1 && !yaxe.floating && !axesUtils.isYAxisHidden(index)) {
        if (yaxe.opposite) {
          w.layout.translateX -= yaxisLabelCoords[index].width + yTitleCoords[index].width + parseInt(yaxe.labels.style.fontSize, 10) / 1.2 + 12;
        }
        if (w.layout.translateX < 2) {
          w.layout.translateX = 2;
        }
      }
    });
  }
}
class Dimensions {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   * @param {import('../../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
    this.theme = ctx.theme;
    this.timeScale = ctx.timeScale;
    this.lgRect = /** @type {any} */
    {};
    this.yAxisWidth = 0;
    this.yAxisWidthLeft = 0;
    this.yAxisWidthRight = 0;
    this.xAxisHeight = 0;
    this.isSparkline = this.w.config.chart.sparkline.enabled;
    this.dimHelpers = new Helpers$4(this);
    this.dimYAxis = new DimYAxis(this);
    this.dimXAxis = new DimXAxis(this);
    this.dimGrid = new DimGrid(this);
    this.lgWidthForSideLegends = 0;
    this.gridPad = this.w.config.grid.padding;
    this.xPadRight = 0;
    this.xPadLeft = 0;
    this.datalabelsCoords = { width: 0, height: 0 };
    this.xAxisWidth = 0;
    this.timescaleLabels = [];
  }
  /**
   * @memberof Dimensions
   **/
  plotCoords() {
    const w = this.w;
    const gl = w.globals;
    this.lgRect = this.dimHelpers.getLegendsRect();
    this.datalabelsCoords = { width: 0, height: 0 };
    const maxStrokeWidth = Array.isArray(w.config.stroke.width) ? Math.max(...w.config.stroke.width) : w.config.stroke.width;
    if (this.isSparkline) {
      if (w.config.markers.discrete.length > 0 || w.config.markers.size > 0) {
        Object.entries(this.gridPad).forEach(([k, v]) => {
          this.gridPad[k] = Math.max(
            v,
            this.w.globals.markers.largestSize / 1.5
          );
        });
      }
      this.gridPad.top = Math.max(maxStrokeWidth / 2, this.gridPad.top);
      this.gridPad.bottom = Math.max(maxStrokeWidth / 2, this.gridPad.bottom);
    }
    if (gl.axisCharts) {
      this.setDimensionsForAxisCharts();
    } else {
      this.setDimensionsForNonAxisCharts();
    }
    this.dimGrid.gridPadFortitleSubtitle();
    w.layout.gridHeight = w.layout.gridHeight - this.gridPad.top - this.gridPad.bottom;
    w.layout.gridWidth = w.layout.gridWidth - this.gridPad.left - this.gridPad.right - this.xPadRight - this.xPadLeft;
    const barWidth = this.dimGrid.gridPadForColumnsInNumericAxis(
      w.layout.gridWidth
    );
    w.layout.gridWidth = w.layout.gridWidth - barWidth * 2;
    w.layout.translateX = w.layout.translateX + this.gridPad.left + this.xPadLeft + (barWidth > 0 ? barWidth : 0);
    w.layout.translateY = w.layout.translateY + this.gridPad.top;
    return {
      // w.layout (future slice)
      layout: {
        gridHeight: w.layout.gridHeight,
        gridWidth: w.layout.gridWidth,
        translateX: w.layout.translateX,
        translateY: w.layout.translateY,
        translateXAxisX: w.layout.translateXAxisX,
        translateXAxisY: w.layout.translateXAxisY,
        rotateXLabels: w.layout.rotateXLabels,
        xAxisHeight: w.layout.xAxisHeight,
        xAxisLabelsHeight: w.layout.xAxisLabelsHeight,
        xAxisGroupLabelsHeight: w.layout.xAxisGroupLabelsHeight,
        xAxisLabelsWidth: w.layout.xAxisLabelsWidth,
        yLabelsCoords: w.layout.yLabelsCoords,
        yTitleCoords: w.layout.yTitleCoords
      }
    };
  }
  setDimensionsForAxisCharts() {
    const w = this.w;
    const gl = w.globals;
    const yaxisLabelCoords = this.dimYAxis.getyAxisLabelsCoords();
    const yTitleCoords = this.dimYAxis.getyAxisTitleCoords();
    if (gl.isSlopeChart) {
      this.datalabelsCoords = this.dimHelpers.getDatalabelsRect();
    }
    w.layout.yLabelsCoords = [];
    w.layout.yTitleCoords = [];
    w.config.yaxis.map((yaxe, index) => {
      w.layout.yLabelsCoords.push({
        width: yaxisLabelCoords[index].width,
        index
      });
      w.layout.yTitleCoords.push(
        /** @type {any} */
        {
          width: yTitleCoords[index].width,
          index
        }
      );
    });
    this.yAxisWidth = this.dimYAxis.getTotalYAxisWidth();
    const xaxisLabelCoords = this.dimXAxis.getxAxisLabelsCoords();
    const xaxisGroupLabelCoords = this.dimXAxis.getxAxisGroupLabelsCoords();
    const xtitleCoords = this.dimXAxis.getxAxisTitleCoords();
    this.conditionalChecksForAxisCoords(
      xaxisLabelCoords,
      xtitleCoords,
      xaxisGroupLabelCoords
    );
    w.layout.translateXAxisY = w.layout.rotateXLabels ? this.xAxisHeight / 8 : -4;
    w.layout.translateXAxisX = w.layout.rotateXLabels && w.axisFlags.isXNumeric && w.config.xaxis.labels.rotate <= -45 ? -this.xAxisWidth / 4 : 0;
    if (w.globals.isBarHorizontal) {
      w.layout.rotateXLabels = false;
      w.layout.translateXAxisY = -1 * (parseInt(w.config.xaxis.labels.style.fontSize, 10) / 1.5);
    }
    w.layout.translateXAxisY = w.layout.translateXAxisY + w.config.xaxis.labels.offsetY;
    w.layout.translateXAxisX = w.layout.translateXAxisX + w.config.xaxis.labels.offsetX;
    let yAxisWidth = this.yAxisWidth;
    let xAxisHeight = this.xAxisHeight;
    w.layout.xAxisLabelsHeight = this.xAxisHeight - xtitleCoords.height;
    w.layout.xAxisGroupLabelsHeight = w.layout.xAxisLabelsHeight - xaxisLabelCoords.height;
    w.layout.xAxisLabelsWidth = this.xAxisWidth;
    w.layout.xAxisHeight = this.xAxisHeight;
    let translateY = 10;
    if (w.config.chart.type === "radar" || this.isSparkline) {
      yAxisWidth = 0;
      xAxisHeight = 0;
    }
    if (this.isSparkline) {
      this.lgRect = {
        height: 0,
        width: 0
      };
    }
    if (this.isSparkline || w.config.chart.type === "treemap") {
      yAxisWidth = 0;
      xAxisHeight = 0;
      translateY = 0;
    }
    if (!this.isSparkline && w.config.chart.type !== "treemap") {
      this.dimXAxis.additionalPaddingXLabels(xaxisLabelCoords);
    }
    const legendTopBottom = () => {
      w.layout.translateX = yAxisWidth + this.datalabelsCoords.width;
      w.layout.gridHeight = gl.svgHeight - this.lgRect.height - xAxisHeight - (!this.isSparkline && w.config.chart.type !== "treemap" ? w.layout.rotateXLabels ? 10 : 15 : 0);
      w.layout.gridWidth = gl.svgWidth - yAxisWidth - this.datalabelsCoords.width * 2;
    };
    if (w.config.xaxis.position === "top")
      translateY = w.layout.xAxisHeight - w.config.xaxis.axisTicks.height - 5;
    switch (w.config.legend.position) {
      case "bottom":
        w.layout.translateY = translateY;
        legendTopBottom();
        break;
      case "top":
        w.layout.translateY = this.lgRect.height + translateY;
        legendTopBottom();
        break;
      case "left":
        w.layout.translateY = translateY;
        w.layout.translateX = this.lgRect.width + yAxisWidth + this.datalabelsCoords.width;
        w.layout.gridHeight = gl.svgHeight - xAxisHeight - 12;
        w.layout.gridWidth = gl.svgWidth - this.lgRect.width - yAxisWidth - this.datalabelsCoords.width * 2;
        break;
      case "right":
        w.layout.translateY = translateY;
        w.layout.translateX = yAxisWidth + this.datalabelsCoords.width;
        w.layout.gridHeight = gl.svgHeight - xAxisHeight - 12;
        w.layout.gridWidth = gl.svgWidth - this.lgRect.width - yAxisWidth - this.datalabelsCoords.width * 2 - 5;
        break;
      default:
        throw new Error("Legend position not supported");
    }
    this.dimGrid.setGridXPosForDualYAxis(yTitleCoords, yaxisLabelCoords);
    const objyAxis = new YAxis(this.w, {
      theme: this.theme,
      timeScale: this.timeScale
    });
    objyAxis.setYAxisXPosition(yaxisLabelCoords, yTitleCoords);
  }
  setDimensionsForNonAxisCharts() {
    const w = this.w;
    const gl = w.globals;
    const cnf = w.config;
    let xPad = 0;
    if (w.config.legend.show && !w.config.legend.floating) {
      xPad = 20;
    }
    const type = cnf.chart.type === "pie" || cnf.chart.type === "polarArea" || cnf.chart.type === "donut" ? "pie" : "radialBar";
    const offY = cnf.plotOptions[type].offsetY;
    const offX = cnf.plotOptions[type].offsetX;
    if (!cnf.legend.show || cnf.legend.floating) {
      w.layout.gridHeight = gl.svgHeight;
      const maxWidth = w.dom.elWrap.getBoundingClientRect().width;
      w.layout.gridWidth = Math.min(maxWidth, w.layout.gridHeight);
      w.layout.translateY = offY;
      w.layout.translateX = offX + (gl.svgWidth - w.layout.gridWidth) / 2;
      return;
    }
    switch (cnf.legend.position) {
      case "bottom":
        w.layout.gridHeight = gl.svgHeight - this.lgRect.height;
        w.layout.gridWidth = gl.svgWidth;
        w.layout.translateY = offY - 10;
        w.layout.translateX = offX + (gl.svgWidth - w.layout.gridWidth) / 2;
        break;
      case "top":
        w.layout.gridHeight = gl.svgHeight - this.lgRect.height;
        w.layout.gridWidth = gl.svgWidth;
        w.layout.translateY = this.lgRect.height + offY + 10;
        w.layout.translateX = offX + (gl.svgWidth - w.layout.gridWidth) / 2;
        break;
      case "left":
        w.layout.gridWidth = gl.svgWidth - this.lgRect.width - xPad;
        w.layout.gridHeight = cnf.chart.height !== "auto" ? gl.svgHeight : w.layout.gridWidth;
        w.layout.translateY = offY;
        w.layout.translateX = offX + this.lgRect.width + xPad;
        break;
      case "right":
        w.layout.gridWidth = gl.svgWidth - this.lgRect.width - xPad - 5;
        w.layout.gridHeight = cnf.chart.height !== "auto" ? gl.svgHeight : w.layout.gridWidth;
        w.layout.translateY = offY;
        w.layout.translateX = offX + 10;
        break;
      default:
        throw new Error("Legend position not supported");
    }
  }
  /**
   * @param {any} xaxisLabelCoords
   * @param {any} xtitleCoords
   * @param {any} xaxisGroupLabelCoords
   */
  conditionalChecksForAxisCoords(xaxisLabelCoords, xtitleCoords, xaxisGroupLabelCoords) {
    const w = this.w;
    const xAxisNum = w.labelData.hasXaxisGroups ? 2 : 1;
    const baseXAxisHeight = xaxisGroupLabelCoords.height + xaxisLabelCoords.height + xtitleCoords.height;
    const xAxisHeightMultiplicate = w.axisFlags.isMultiLineX ? 1.2 : LINE_HEIGHT_RATIO;
    const rotatedXAxisOffset = w.layout.rotateXLabels ? 22 : 10;
    const rotatedXAxisLegendOffset = w.layout.rotateXLabels && w.config.legend.position === "bottom";
    const additionalOffset = rotatedXAxisLegendOffset ? 10 : 0;
    this.xAxisHeight = baseXAxisHeight * xAxisHeightMultiplicate + xAxisNum * rotatedXAxisOffset + additionalOffset;
    this.xAxisWidth = xaxisLabelCoords.width;
    if (this.xAxisHeight - xtitleCoords.height > w.config.xaxis.labels.maxHeight) {
      this.xAxisHeight = w.config.xaxis.labels.maxHeight;
    }
    if (w.config.xaxis.labels.minHeight && this.xAxisHeight < w.config.xaxis.labels.minHeight) {
      this.xAxisHeight = w.config.xaxis.labels.minHeight;
    }
    if (w.config.xaxis.floating) {
      this.xAxisHeight = 0;
    }
    let minYAxisWidth = 0;
    let maxYAxisWidth = 0;
    w.config.yaxis.forEach((y) => {
      minYAxisWidth += y.labels.minWidth;
      maxYAxisWidth += y.labels.maxWidth;
    });
    if (this.yAxisWidth < minYAxisWidth) {
      this.yAxisWidth = minYAxisWidth;
    }
    if (this.yAxisWidth > maxYAxisWidth) {
      this.yAxisWidth = maxYAxisWidth;
    }
  }
}
const MINUTES_IN_DAY = 24 * 60;
const SECONDS_IN_DAY = MINUTES_IN_DAY * 60;
const MIN_ZOOM_DAYS = 10 / SECONDS_IN_DAY;
class TimeScale {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
    this.timeScaleArray = [];
    this.utc = this.w.config.xaxis.labels.datetimeUTC;
  }
  /**
   * @param {number} minX
   * @param {number} maxX
   */
  calculateTimeScaleTicks(minX, maxX) {
    const w = this.w;
    if (w.globals.allSeriesCollapsed) {
      w.labelData.labels = [];
      w.labelData.timescaleLabels = [];
      return [];
    }
    const dt = new DateTime(this.w);
    const daysDiff = (maxX - minX) / (1e3 * SECONDS_IN_DAY);
    this.determineInterval(daysDiff);
    w.interact.disableZoomIn = false;
    w.interact.disableZoomOut = false;
    if (daysDiff < MIN_ZOOM_DAYS) {
      w.interact.disableZoomIn = true;
    } else if (daysDiff > 5e4) {
      w.interact.disableZoomOut = true;
    }
    const timeIntervals = dt.getTimeUnitsfromTimestamp(minX, maxX);
    const daysWidthOnXAxis = w.layout.gridWidth / daysDiff;
    const hoursWidthOnXAxis = daysWidthOnXAxis / 24;
    const minutesWidthOnXAxis = hoursWidthOnXAxis / 60;
    const secondsWidthOnXAxis = minutesWidthOnXAxis / 60;
    const numberOfHours = Math.floor(daysDiff * 24);
    const numberOfMinutes = Math.floor(daysDiff * MINUTES_IN_DAY);
    const numberOfSeconds = Math.floor(daysDiff * SECONDS_IN_DAY);
    const numberOfDays = Math.floor(daysDiff);
    const numberOfMonths = Math.floor(daysDiff / 30);
    const numberOfYears = Math.floor(daysDiff / 365);
    const firstVal = {
      minMillisecond: timeIntervals.minMillisecond,
      minSecond: timeIntervals.minSecond,
      minMinute: timeIntervals.minMinute,
      minHour: timeIntervals.minHour,
      minDate: timeIntervals.minDate,
      minMonth: timeIntervals.minMonth,
      minYear: timeIntervals.minYear
    };
    const currentMillisecond = firstVal.minMillisecond;
    const currentSecond = firstVal.minSecond;
    const currentMinute = firstVal.minMinute;
    const currentHour = firstVal.minHour;
    const currentMonthDate = firstVal.minDate;
    const currentDate = firstVal.minDate;
    const currentMonth = firstVal.minMonth;
    const currentYear = firstVal.minYear;
    const params = {
      firstVal,
      currentMillisecond,
      currentSecond,
      currentMinute,
      currentHour,
      currentMonthDate,
      currentDate,
      currentMonth,
      currentYear,
      daysWidthOnXAxis,
      hoursWidthOnXAxis,
      minutesWidthOnXAxis,
      secondsWidthOnXAxis,
      numberOfSeconds,
      numberOfMinutes,
      numberOfHours,
      numberOfDays,
      numberOfMonths,
      numberOfYears
    };
    switch (this.tickInterval) {
      case "years": {
        this.generateYearScale(params);
        break;
      }
      case "months":
      case "half_year": {
        this.generateMonthScale(params);
        break;
      }
      case "months_days":
      case "months_fortnight":
      case "days":
      case "week_days": {
        this.generateDayScale(params);
        break;
      }
      case "hours": {
        this.generateHourScale(params);
        break;
      }
      case "minutes_fives":
      case "minutes":
        this.generateMinuteScale(params);
        break;
      case "seconds_tens":
      case "seconds_fives":
      case "seconds":
        this.generateSecondScale(params);
        break;
    }
    const adjustedMonthInTimeScaleArray = this.timeScaleArray.map(
      (ts) => {
        const defaultReturn = {
          position: ts.position,
          unit: ts.unit,
          year: ts.year,
          day: ts.day ? ts.day : 1,
          hour: ts.hour ? ts.hour : 0,
          month: ts.month + 1
        };
        if (ts.unit === "month") {
          return __spreadProps(__spreadValues({}, defaultReturn), {
            day: 1,
            value: ts.value + 1
          });
        } else if (ts.unit === "day" || ts.unit === "hour") {
          return __spreadProps(__spreadValues({}, defaultReturn), {
            value: ts.value
          });
        } else if (ts.unit === "minute") {
          return __spreadProps(__spreadValues({}, defaultReturn), {
            value: ts.value,
            minute: ts.value
          });
        } else if (ts.unit === "second") {
          return __spreadProps(__spreadValues({}, defaultReturn), {
            value: ts.value,
            minute: ts.minute,
            second: ts.second
          });
        }
        return ts;
      }
    );
    const filteredTimeScale = adjustedMonthInTimeScaleArray.filter(
      (ts) => {
        let modulo = 1;
        let ticks = Math.ceil(w.layout.gridWidth / 120);
        const value = ts.value;
        if (w.config.xaxis.tickAmount !== void 0) {
          ticks = w.config.xaxis.tickAmount;
        }
        if (adjustedMonthInTimeScaleArray.length > ticks) {
          modulo = Math.floor(adjustedMonthInTimeScaleArray.length / ticks);
        }
        let shouldNotSkipUnit = false;
        let shouldNotPrint = false;
        switch (this.tickInterval) {
          case "years":
            if (ts.unit === "year") {
              shouldNotSkipUnit = true;
            }
            break;
          case "half_year":
            modulo = 7;
            if (ts.unit === "year") {
              shouldNotSkipUnit = true;
            }
            break;
          case "months":
            modulo = 1;
            if (ts.unit === "year") {
              shouldNotSkipUnit = true;
            }
            break;
          case "months_fortnight":
            modulo = 15;
            if (ts.unit === "year" || ts.unit === "month") {
              shouldNotSkipUnit = true;
            }
            if (value === 30) {
              shouldNotPrint = true;
            }
            break;
          case "months_days":
            modulo = 10;
            if (ts.unit === "month") {
              shouldNotSkipUnit = true;
            }
            if (value === 30) {
              shouldNotPrint = true;
            }
            break;
          case "week_days":
            modulo = 8;
            if (ts.unit === "month") {
              shouldNotSkipUnit = true;
            }
            break;
          case "days":
            modulo = 1;
            if (ts.unit === "month") {
              shouldNotSkipUnit = true;
            }
            break;
          case "hours":
            if (ts.unit === "day") {
              shouldNotSkipUnit = true;
            }
            break;
          case "minutes_fives":
            if (value % 5 !== 0) {
              shouldNotPrint = true;
            }
            break;
          case "seconds_tens":
            if (value % 10 !== 0) {
              shouldNotPrint = true;
            }
            break;
          case "seconds_fives":
            if (value % 5 !== 0) {
              shouldNotPrint = true;
            }
            break;
        }
        if (this.tickInterval === "hours" || this.tickInterval === "minutes_fives" || this.tickInterval === "seconds_tens" || this.tickInterval === "seconds_fives") {
          if (!shouldNotPrint) {
            return true;
          }
        } else {
          if ((value % modulo === 0 || shouldNotSkipUnit) && !shouldNotPrint) {
            return true;
          }
        }
      }
    );
    return filteredTimeScale;
  }
  /**
   * @param {Array<Record<string, any>>} filteredTimeScale
   */
  recalcDimensionsBasedOnFormat(filteredTimeScale) {
    const w = this.w;
    const reformattedTimescaleArray = this.formatDates(filteredTimeScale);
    const removedOverlappingTS = this.removeOverlappingTS(
      reformattedTimescaleArray
    );
    w.labelData.timescaleLabels = removedOverlappingTS.slice();
    const dimensions = new Dimensions(this.w, this.ctx);
    const layoutState = dimensions.plotCoords();
    this.ctx._writeLayoutCoords(layoutState.layout);
  }
  /**
   * @param {number} daysDiff
   */
  determineInterval(daysDiff) {
    const yearsDiff = daysDiff / 365;
    const hoursDiff = daysDiff * 24;
    const minutesDiff = hoursDiff * 60;
    const secondsDiff = minutesDiff * 60;
    switch (true) {
      case yearsDiff > 5:
        this.tickInterval = "years";
        break;
      case daysDiff > 800:
        this.tickInterval = "half_year";
        break;
      case daysDiff > 180:
        this.tickInterval = "months";
        break;
      case daysDiff > 90:
        this.tickInterval = "months_fortnight";
        break;
      case daysDiff > 60:
        this.tickInterval = "months_days";
        break;
      case daysDiff > 30:
        this.tickInterval = "week_days";
        break;
      case daysDiff > 2:
        this.tickInterval = "days";
        break;
      case hoursDiff > 2.4:
        this.tickInterval = "hours";
        break;
      case minutesDiff > 15:
        this.tickInterval = "minutes_fives";
        break;
      case minutesDiff > 5:
        this.tickInterval = "minutes";
        break;
      case minutesDiff > 1:
        this.tickInterval = "seconds_tens";
        break;
      case secondsDiff > 20:
        this.tickInterval = "seconds_fives";
        break;
      default:
        this.tickInterval = "seconds";
        break;
    }
  }
  /** @param {{firstVal: any, currentMonth: any, currentYear: any, daysWidthOnXAxis: any, numberOfYears: any}} opts */
  generateYearScale({
    firstVal,
    currentMonth,
    currentYear,
    daysWidthOnXAxis,
    numberOfYears
  }) {
    let firstTickValue = firstVal.minYear;
    let firstTickPosition = 0;
    const dt = new DateTime(this.w);
    const unit = "year";
    if (firstVal.minDate > 1 || firstVal.minMonth > 0) {
      const remainingDays = dt.determineRemainingDaysOfYear(
        firstVal.minYear,
        firstVal.minMonth,
        firstVal.minDate
      );
      const remainingDaysOfFirstYear = dt.determineDaysOfYear(firstVal.minYear) - remainingDays + 1;
      firstTickPosition = remainingDaysOfFirstYear * daysWidthOnXAxis;
      firstTickValue = firstVal.minYear + 1;
      this.timeScaleArray.push({
        position: firstTickPosition,
        value: firstTickValue,
        unit,
        year: firstTickValue,
        month: 1
      });
    } else if (firstVal.minDate === 1 && firstVal.minMonth === 0) {
      this.timeScaleArray.push({
        position: firstTickPosition,
        value: firstTickValue,
        unit,
        year: currentYear,
        month: Utils$1.monthMod(currentMonth + 1)
      });
    }
    let year = firstTickValue;
    let pos = firstTickPosition;
    for (let i = 0; i < numberOfYears; i++) {
      year++;
      pos = dt.determineDaysOfYear(year - 1) * daysWidthOnXAxis + pos;
      this.timeScaleArray.push({
        position: pos,
        value: year,
        unit,
        year,
        month: 1
      });
    }
  }
  /** @param {{firstVal: any, currentMonthDate: any, currentMonth: any, currentYear: any, daysWidthOnXAxis: any, numberOfMonths: any}} opts */
  generateMonthScale({
    firstVal,
    currentMonthDate,
    currentMonth,
    currentYear,
    daysWidthOnXAxis,
    numberOfMonths
  }) {
    let firstTickValue = currentMonth;
    let firstTickPosition = 0;
    const dt = new DateTime(this.w);
    let unit = "month";
    let yrCounter = 0;
    if (firstVal.minDate > 1) {
      const remainingDaysOfFirstMonth = dt.determineDaysOfMonths(currentMonth + 1, firstVal.minYear) - currentMonthDate + 1;
      firstTickPosition = remainingDaysOfFirstMonth * daysWidthOnXAxis;
      firstTickValue = Utils$1.monthMod(currentMonth + 1);
      let year = currentYear + yrCounter;
      let month2 = Utils$1.monthMod(firstTickValue);
      let value = firstTickValue;
      if (firstTickValue === 0) {
        unit = "year";
        value = year;
        month2 = 1;
        yrCounter += 1;
        year = year + yrCounter;
      }
      this.timeScaleArray.push({
        position: firstTickPosition,
        value,
        unit,
        year,
        month: month2
      });
    } else {
      this.timeScaleArray.push({
        position: firstTickPosition,
        value: firstTickValue,
        unit,
        year: currentYear,
        month: Utils$1.monthMod(currentMonth)
      });
    }
    let month = firstTickValue + 1;
    let pos = firstTickPosition;
    for (let i = 0, j = 1; i < numberOfMonths; i++, j++) {
      month = Utils$1.monthMod(month);
      if (month === 0) {
        unit = "year";
        yrCounter += 1;
      } else {
        unit = "month";
      }
      const year = this._getYear(currentYear, month, yrCounter);
      pos = dt.determineDaysOfMonths(month, year) * daysWidthOnXAxis + pos;
      const monthVal = month === 0 ? year : month;
      this.timeScaleArray.push({
        position: pos,
        value: monthVal,
        unit,
        year,
        month: month === 0 ? 1 : month
      });
      month++;
    }
  }
  /** @param {{firstVal: any, currentMonth: any, currentYear: any, hoursWidthOnXAxis: any, numberOfDays: any}} opts */
  generateDayScale({
    firstVal,
    currentMonth,
    currentYear,
    hoursWidthOnXAxis,
    numberOfDays
  }) {
    const dt = new DateTime(this.w);
    let unit = "day";
    let firstTickValue = firstVal.minDate + 1;
    let date = firstTickValue;
    const changeMonth = (dateVal, month2, year) => {
      const monthdays = dt.determineDaysOfMonths(month2 + 1, year);
      if (dateVal > monthdays) {
        month2 = month2 + 1;
        date = 1;
        unit = "month";
        val = month2;
        return month2;
      }
      return month2;
    };
    const remainingHours = 24 - firstVal.minHour;
    const yrCounter = 0;
    let firstTickPosition = remainingHours * hoursWidthOnXAxis;
    let val = firstTickValue;
    let month = changeMonth(date, currentMonth, currentYear);
    if (firstVal.minHour === 0 && firstVal.minDate === 1) {
      firstTickPosition = 0;
      val = Utils$1.monthMod(firstVal.minMonth);
      unit = "month";
      date = firstVal.minDate;
    } else if (firstVal.minDate !== 1 && firstVal.minHour === 0 && firstVal.minMinute === 0) {
      firstTickPosition = 0;
      firstTickValue = firstVal.minDate;
      date = firstTickValue;
      val = firstTickValue;
      month = changeMonth(date, currentMonth, currentYear);
      if (val !== 1) {
        unit = "day";
      }
    }
    this.timeScaleArray.push({
      position: firstTickPosition,
      value: val,
      unit,
      year: this._getYear(currentYear, month, yrCounter),
      month: Utils$1.monthMod(month),
      day: date
    });
    let pos = firstTickPosition;
    for (let i = 0; i < numberOfDays; i++) {
      date += 1;
      unit = "day";
      month = changeMonth(
        date,
        month,
        this._getYear(currentYear, month, yrCounter)
      );
      const year = this._getYear(currentYear, month, yrCounter);
      pos = 24 * hoursWidthOnXAxis + pos;
      const value = date === 1 ? Utils$1.monthMod(month) : date;
      this.timeScaleArray.push({
        position: pos,
        value,
        unit,
        year,
        month: Utils$1.monthMod(month),
        day: value
      });
    }
  }
  /** @param {{firstVal: any, currentDate: any, currentMonth: any, currentYear: any, minutesWidthOnXAxis: any, numberOfHours: any}} opts */
  generateHourScale({
    firstVal,
    currentDate,
    currentMonth,
    currentYear,
    minutesWidthOnXAxis,
    numberOfHours
  }) {
    const dt = new DateTime(this.w);
    const yrCounter = 0;
    let unit = "hour";
    const changeDate = (dateVal, month2) => {
      const monthdays = dt.determineDaysOfMonths(month2 + 1, currentYear);
      if (dateVal > monthdays) {
        date = 1;
        month2 = month2 + 1;
      }
      return { month: month2, date };
    };
    const changeMonth = (dateVal, month2) => {
      const monthdays = dt.determineDaysOfMonths(month2 + 1, currentYear);
      if (dateVal > monthdays) {
        month2 = month2 + 1;
        return month2;
      }
      return month2;
    };
    const remainingMins = 60 - (firstVal.minMinute + firstVal.minSecond / 60);
    let firstTickPosition = remainingMins * minutesWidthOnXAxis;
    let firstTickValue = firstVal.minHour + 1;
    let hour = firstTickValue;
    if (remainingMins === 60) {
      firstTickPosition = 0;
      firstTickValue = firstVal.minHour;
      hour = firstTickValue;
    }
    let date = currentDate;
    if (hour >= 24) {
      hour = 0;
      date += 1;
      unit = "day";
      firstTickValue = date;
    }
    const checkNextMonth = changeDate(date, currentMonth);
    let month = checkNextMonth.month;
    month = changeMonth(date, month);
    if (unit === "day") {
      firstTickValue = date;
    }
    this.timeScaleArray.push({
      position: firstTickPosition,
      value: firstTickValue,
      unit,
      day: date,
      hour,
      year: currentYear,
      month: Utils$1.monthMod(month)
    });
    hour++;
    let pos = firstTickPosition;
    for (let i = 0; i < numberOfHours; i++) {
      unit = "hour";
      if (hour >= 24) {
        hour = 0;
        date += 1;
        unit = "day";
        const checkNextMonth2 = changeDate(date, month);
        month = checkNextMonth2.month;
        month = changeMonth(date, month);
      }
      const year = this._getYear(currentYear, month, yrCounter);
      pos = 60 * minutesWidthOnXAxis + pos;
      const val = hour === 0 ? date : hour;
      this.timeScaleArray.push({
        position: pos,
        value: val,
        unit,
        hour,
        day: date,
        year,
        month: Utils$1.monthMod(month)
      });
      hour++;
    }
  }
  /** @param {{currentMillisecond: any, currentSecond: any, currentMinute: any, currentHour: any, currentDate: any, currentMonth: any, currentYear: any, minutesWidthOnXAxis: any, secondsWidthOnXAxis: any, numberOfMinutes: any}} opts */
  generateMinuteScale({
    currentMillisecond,
    currentSecond,
    currentMinute,
    currentHour,
    currentDate,
    currentMonth,
    currentYear,
    minutesWidthOnXAxis,
    secondsWidthOnXAxis,
    numberOfMinutes
  }) {
    const dt = new DateTime(this.w);
    const yrCounter = 0;
    const unit = "minute";
    const remainingSecs = 60 - currentSecond;
    let firstTickPosition = (remainingSecs - currentMillisecond / 1e3) * secondsWidthOnXAxis;
    let minute = currentMinute + 1;
    if (currentSecond === 0 && currentMillisecond === 0) {
      firstTickPosition = 0;
      minute = currentMinute;
    }
    let date = currentDate;
    let month = currentMonth;
    const year = currentYear;
    let hour = currentHour;
    let pos = firstTickPosition;
    for (let i = 0; i < numberOfMinutes; i++) {
      if (minute >= 60) {
        minute = 0;
        hour += 1;
        if (hour === 24) {
          hour = 0;
          date += 1;
          const monthDays = dt.determineDaysOfMonths(
            month + 1,
            this._getYear(year, month, yrCounter)
          );
          if (date > monthDays) {
            date = 1;
            month += 1;
          }
        }
      }
      this.timeScaleArray.push({
        position: pos,
        value: minute,
        unit,
        hour,
        minute,
        day: date,
        year: this._getYear(year, month, yrCounter),
        month: Utils$1.monthMod(month)
      });
      pos += minutesWidthOnXAxis;
      minute++;
    }
  }
  /** @param {{currentMillisecond: any, currentSecond: any, currentMinute: any, currentHour: any, currentDate: any, currentMonth: any, currentYear: any, secondsWidthOnXAxis: any, numberOfSeconds: any}} opts */
  generateSecondScale({
    currentMillisecond,
    currentSecond,
    currentMinute,
    currentHour,
    currentDate,
    currentMonth,
    currentYear,
    secondsWidthOnXAxis,
    numberOfSeconds
  }) {
    const yrCounter = 0;
    const unit = "second";
    const remainingMillisecs = 1e3 - currentMillisecond;
    let firstTickPosition = remainingMillisecs / 1e3 * secondsWidthOnXAxis;
    let second = currentSecond + 1;
    if (currentMillisecond === 0) {
      firstTickPosition = 0;
      second = currentSecond;
    }
    let minute = currentMinute;
    const date = currentDate;
    const month = currentMonth;
    const year = currentYear;
    let hour = currentHour;
    let pos = firstTickPosition;
    for (let i = 0; i < numberOfSeconds; i++) {
      if (second >= 60) {
        minute++;
        second = 0;
        if (minute >= 60) {
          hour++;
          minute = 0;
          if (hour === 24) {
            hour = 0;
          }
        }
      }
      this.timeScaleArray.push({
        position: pos,
        value: second,
        unit,
        hour,
        minute,
        second,
        day: date,
        year: this._getYear(year, month, yrCounter),
        month: Utils$1.monthMod(month)
      });
      pos += secondsWidthOnXAxis;
      second++;
    }
  }
  /**
   * @param {Record<string, any>} ts
   * @param {string | number} value
   */
  createRawDateString(ts, value) {
    let raw = ts.year;
    if (ts.month === 0) {
      ts.month = 1;
    }
    raw += "-" + ("0" + ts.month.toString()).slice(-2);
    if (ts.unit === "day") {
      raw += "-" + ("0" + value).slice(-2);
    } else {
      raw += "-" + ("0" + (ts.day ? ts.day : "1")).slice(-2);
    }
    if (ts.unit === "hour") {
      raw += "T" + ("0" + value).slice(-2);
    } else {
      raw += "T" + ("0" + (ts.hour ? ts.hour : "0")).slice(-2);
    }
    if (ts.unit === "minute") {
      raw += ":" + ("0" + value).slice(-2);
    } else {
      raw += ":" + (ts.minute ? ("0" + ts.minute).slice(-2) : "00");
    }
    if (ts.unit === "second") {
      raw += ":" + ("0" + value).slice(-2);
    } else {
      raw += ":00";
    }
    if (this.utc) {
      raw += ".000Z";
    }
    return raw;
  }
  /**
   * @param {Array<Record<string, any>>} filteredTimeScale
   */
  formatDates(filteredTimeScale) {
    const w = this.w;
    const reformattedTimescaleArray = filteredTimeScale.map(
      (ts) => {
        let value = ts.value.toString();
        const dt = new DateTime(this.w);
        const raw = this.createRawDateString(ts, value);
        let dateToFormat = dt.getDate(dt.parseDate(raw));
        if (!this.utc) {
          dateToFormat = dt.getDate(dt.parseDateWithTimezone(raw));
        }
        if (w.config.xaxis.labels.format === void 0) {
          let customFormat = "dd MMM";
          const dtFormatter = w.config.xaxis.labels.datetimeFormatter;
          if (ts.unit === "year") customFormat = dtFormatter.year;
          if (ts.unit === "month") customFormat = dtFormatter.month;
          if (ts.unit === "day") customFormat = dtFormatter.day;
          if (ts.unit === "hour") customFormat = dtFormatter.hour;
          if (ts.unit === "minute") customFormat = dtFormatter.minute;
          if (ts.unit === "second") customFormat = dtFormatter.second;
          value = dt.formatDate(dateToFormat, customFormat);
        } else {
          value = dt.formatDate(dateToFormat, w.config.xaxis.labels.format);
        }
        return {
          dateString: raw,
          position: ts.position,
          value,
          unit: ts.unit,
          year: ts.year,
          month: ts.month
        };
      }
    );
    return reformattedTimescaleArray;
  }
  /**
   * @param {any[]} arr
   */
  removeOverlappingTS(arr) {
    const graphics = new Graphics(this.w);
    let equalLabelLengthFlag = false;
    let constantLabelWidth;
    if (arr.length > 0 && // check arr length
    arr[0].value && // check arr[0] contains value
    /**
     * @param {Record<string, any>} lb
     */
    arr.every((lb) => lb.value.length === arr[0].value.length)) {
      equalLabelLengthFlag = true;
      constantLabelWidth = graphics.getTextRects(
        arr[0].value,
        this.w.config.xaxis.labels.style.fontSize
      ).width;
    }
    let lastDrawnIndex = 0;
    let filteredArray = arr.map((item, index) => {
      if (index > 0 && this.w.config.xaxis.labels.hideOverlappingLabels) {
        const prevLabelWidth = !equalLabelLengthFlag ? graphics.getTextRects(
          /** @type {any} */
          arr[lastDrawnIndex].value,
          this.w.config.xaxis.labels.style.fontSize
        ).width : constantLabelWidth;
        const prevPos = arr[lastDrawnIndex].position;
        const pos = item.position;
        if (pos > prevPos + prevLabelWidth + 10) {
          lastDrawnIndex = index;
          return item;
        } else {
          return null;
        }
      } else {
        return item;
      }
    });
    filteredArray = filteredArray.filter((f) => f !== null);
    return filteredArray;
  }
  /**
   * @param {number} currentYear
   * @param {number} month
   * @param {number} yrCounter
   */
  _getYear(currentYear, month, yrCounter) {
    return currentYear + Math.floor(month / 12) + yrCounter;
  }
}
const REGISTRY_KEY = "__apexcharts_registry__";
if (!/** @type {any} */
globalThis[REGISTRY_KEY]) {
  globalThis[REGISTRY_KEY] = {};
}
function getRegistry() {
  return (
    /** @type {any} */
    globalThis[REGISTRY_KEY]
  );
}
function register(typeMap) {
  Object.assign(getRegistry(), typeMap);
}
function getChartClass(type) {
  const Cls = getRegistry()[type];
  if (!Cls) {
    throw new Error(
      `ApexCharts: chart type "${type}" is not registered. Import it via ApexCharts.use() or use the full apexcharts bundle.`
    );
  }
  return Cls;
}
class Core {
  /**
   * @param {Element} el
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(el, w, ctx) {
    this.w = w;
    this.ctx = ctx;
    this.el = el;
  }
  setupElements() {
    const { globals: gl, config: cnf } = this.w;
    const ct = cnf.chart.type;
    const xyChartsArrTypes = [
      "line",
      "area",
      "bar",
      "rangeBar",
      "rangeArea",
      "candlestick",
      "boxPlot",
      "scatter",
      "bubble"
    ];
    const axisChartsArrTypes = [
      ...xyChartsArrTypes,
      "radar",
      "heatmap",
      "treemap"
    ];
    gl.axisCharts = axisChartsArrTypes.includes(ct);
    gl.xyCharts = xyChartsArrTypes.includes(ct);
    gl.isBarHorizontal = ["bar", "rangeBar", "boxPlot"].includes(ct) && cnf.plotOptions.bar.horizontal;
    gl.chartClass = `.apexcharts${gl.chartID}`;
    this.w.dom.baseEl = this.el;
    this.w.dom.elWrap = BrowserAPIs.createElementNS(
      "http://www.w3.org/1999/xhtml",
      "div"
    );
    Graphics.setAttrs(this.w.dom.elWrap, {
      id: gl.chartClass.substring(1),
      class: `apexcharts-canvas ${gl.chartClass.substring(1)}`
    });
    this.el.appendChild(this.w.dom.elWrap);
    const SVG2 = Environment.isBrowser() ? (
      /** @type {any} */
      window.SVG
    ) : (
      /** @type {any} */
      global.SVG
    );
    this.w.dom.Paper = SVG2().addTo(this.w.dom.elWrap);
    this.w.dom.Paper.attr({
      class: "apexcharts-svg",
      "xmlns:data": "ApexChartsNS",
      transform: `translate(${cnf.chart.offsetX}, ${cnf.chart.offsetY})`
    });
    this.w.dom.Paper.node.style.background = cnf.theme.mode === "dark" && !cnf.chart.background ? "#343A3F" : cnf.theme.mode === "light" && !cnf.chart.background ? "#fff" : cnf.chart.background;
    this.setSVGDimensions();
    this.w.dom.elLegendForeign = BrowserAPIs.createElementNS(
      SVGNS,
      "foreignObject"
    );
    Graphics.setAttrs(this.w.dom.elLegendForeign, {
      x: 0,
      y: 0,
      width: gl.svgWidth,
      height: gl.svgHeight
    });
    this.w.dom.elLegendWrap = BrowserAPIs.createElementNS(
      "http://www.w3.org/1999/xhtml",
      "div"
    );
    this.w.dom.elLegendWrap.classList.add("apexcharts-legend");
    this.w.dom.elWrap.appendChild(this.w.dom.elLegendWrap);
    this.w.dom.Paper.node.appendChild(this.w.dom.elLegendForeign);
    if (cnf.chart.accessibility.enabled && cnf.chart.accessibility.announcements.enabled) {
      const srStatus = BrowserAPIs.createElement("div");
      srStatus.className = "apexcharts-sr-status";
      srStatus.setAttribute("role", "status");
      srStatus.setAttribute("aria-live", "polite");
      srStatus.setAttribute("aria-atomic", "true");
      this.w.dom.elWrap.appendChild(srStatus);
    }
    if (cnf.chart.accessibility.enabled) {
      const ariaLabel = this.getAccessibleChartLabel();
      const svgRole = cnf.chart.accessibility.keyboard.enabled && cnf.chart.accessibility.keyboard.navigation.enabled ? "application" : "img";
      this.w.dom.Paper.attr({
        role: svgRole,
        "aria-label": ariaLabel
      });
      const titleEl = BrowserAPIs.createElementNS(SVGNS, "title");
      titleEl.textContent = ariaLabel;
      this.w.dom.Paper.node.insertBefore(
        titleEl,
        this.w.dom.elLegendForeign.nextSibling
      );
      if (cnf.chart.accessibility.description) {
        const descEl = BrowserAPIs.createElementNS(SVGNS, "desc");
        descEl.textContent = cnf.chart.accessibility.description;
        this.w.dom.Paper.node.insertBefore(
          descEl,
          this.w.dom.elLegendForeign.nextSibling
        );
      }
    }
    this.w.dom.elGraphical = this.w.dom.Paper.group().attr({
      class: "apexcharts-inner apexcharts-graphical"
    });
    this.w.dom.elDefs = this.w.dom.Paper.defs();
    this.w.dom.Paper.add(this.w.dom.elGraphical);
    this.w.dom.elGraphical.add(this.w.dom.elDefs);
  }
  /**
   * @param {any[]} ser
   * @param {import('../types/internal').XYRatios} xyRatios
   */
  plotChartType(ser, xyRatios) {
    const { w, ctx } = this;
    const { config: cnf, globals: gl } = w;
    const seriesTypes = {
      line: { series: [], i: [] },
      area: { series: [], i: [] },
      scatter: { series: [], i: [] },
      bubble: { series: [], i: [] },
      bar: { series: [], i: [] },
      candlestick: { series: [], i: [] },
      boxPlot: { series: [], i: [] },
      rangeBar: { series: [], i: [] },
      rangeArea: { series: [], seriesRangeEnd: [], i: [] }
    };
    const chartType = cnf.chart.type || "line";
    let nonComboType = null;
    let comboCount = 0;
    this.w.seriesData.series.forEach((serie, st) => {
      var _a, _b;
      const seriesType = ((_a = ser[st]) == null ? void 0 : _a.type) === "column" ? "bar" : ((_b = ser[st]) == null ? void 0 : _b.type) || (chartType === "column" ? "bar" : chartType);
      if (
        /** @type {Record<string,any>} */
        seriesTypes[seriesType]
      ) {
        if (seriesType === "rangeArea") {
          seriesTypes[seriesType].series.push(this.w.rangeData.seriesRangeStart[st]);
          seriesTypes[seriesType].seriesRangeEnd.push(this.w.rangeData.seriesRangeEnd[st]);
        } else {
          seriesTypes[seriesType].series.push(serie);
        }
        seriesTypes[seriesType].i.push(st);
        if (seriesType === "bar") w.globals.columnSeries = seriesTypes.bar;
      } else if ([
        "heatmap",
        "treemap",
        "pie",
        "donut",
        "polarArea",
        "radialBar",
        "radar"
      ].includes(seriesType)) {
        nonComboType = seriesType;
      } else {
        console.warn(
          `You have specified an unrecognized series type (${seriesType}).`
        );
      }
      if (chartType !== seriesType && seriesType !== "scatter") comboCount++;
    });
    if (comboCount > 0) {
      if (nonComboType) {
        console.warn(
          `Chart or series type ${nonComboType} cannot appear with other chart or series types.`
        );
      }
      if (seriesTypes.bar.series.length > 0 && cnf.plotOptions.bar.horizontal) {
        comboCount -= seriesTypes.bar.series.length;
        seriesTypes.bar = { series: [], i: [] };
        w.globals.columnSeries = { series: [], i: [] };
        console.warn(
          "Horizontal bars are not supported in a mixed/combo chart. Please turn off `plotOptions.bar.horizontal`"
        );
      }
    }
    gl.comboCharts || (gl.comboCharts = comboCount > 0);
    const needsLine = seriesTypes.line.series.length > 0 || seriesTypes.area.series.length > 0 || seriesTypes.scatter.series.length > 0 || seriesTypes.bubble.series.length > 0 || seriesTypes.rangeArea.series.length > 0 || !gl.comboCharts && ["line", "area", "scatter", "bubble", "rangeArea"].includes(
      cnf.chart.type
    );
    const line = needsLine ? new (getChartClass("line"))(ctx.w, ctx, xyRatios) : null;
    const needsCandlestick = seriesTypes.candlestick.series.length > 0 || seriesTypes.boxPlot.series.length > 0 || !gl.comboCharts && ["candlestick", "boxPlot"].includes(cnf.chart.type);
    const boxCandlestick = needsCandlestick ? new (getChartClass("candlestick"))(ctx.w, ctx, xyRatios) : null;
    const needsPie = !gl.comboCharts && ["pie", "donut", "polarArea"].includes(cnf.chart.type);
    ctx.pie = needsPie ? new (getChartClass("pie"))(ctx.w, ctx) : null;
    const needsRangeBar = seriesTypes.rangeBar.series.length > 0 || !gl.comboCharts && cnf.chart.type === "rangeBar";
    ctx.rangeBar = needsRangeBar ? new (getChartClass("rangeBar"))(ctx.w, ctx, xyRatios) : null;
    let elGraph = [];
    if (gl.comboCharts) {
      const coreUtils = new CoreUtils(this.w);
      if (seriesTypes.area.series.length > 0) {
        elGraph.push(
          ...coreUtils.drawSeriesByGroup(
            seriesTypes.area,
            gl.areaGroups,
            "area",
            line
          )
        );
      }
      if (seriesTypes.bar.series.length > 0) {
        if (cnf.chart.stacked) {
          const barStacked = new (getChartClass("barStacked"))(
            ctx.w,
            ctx,
            xyRatios
          );
          elGraph.push(
            barStacked.draw(seriesTypes.bar.series, seriesTypes.bar.i)
          );
        } else {
          ctx.bar = new (getChartClass("bar"))(ctx.w, ctx, xyRatios);
          elGraph.push(ctx.bar.draw(seriesTypes.bar.series, seriesTypes.bar.i));
        }
      }
      if (seriesTypes.rangeArea.series.length > 0) {
        elGraph.push(
          line.draw(
            seriesTypes.rangeArea.series,
            "rangeArea",
            seriesTypes.rangeArea.i,
            seriesTypes.rangeArea.seriesRangeEnd
          )
        );
      }
      if (seriesTypes.line.series.length > 0) {
        elGraph.push(
          ...coreUtils.drawSeriesByGroup(
            seriesTypes.line,
            gl.lineGroups,
            "line",
            line
          )
        );
      }
      if (seriesTypes.candlestick.series.length > 0) {
        elGraph.push(
          boxCandlestick.draw(
            seriesTypes.candlestick.series,
            "candlestick",
            seriesTypes.candlestick.i
          )
        );
      }
      if (seriesTypes.boxPlot.series.length > 0) {
        elGraph.push(
          boxCandlestick.draw(
            seriesTypes.boxPlot.series,
            "boxPlot",
            seriesTypes.boxPlot.i
          )
        );
      }
      if (seriesTypes.rangeBar.series.length > 0) {
        elGraph.push(
          ctx.rangeBar.draw(
            seriesTypes.rangeBar.series,
            seriesTypes.rangeBar.i
          )
        );
      }
      if (seriesTypes.scatter.series.length > 0) {
        const scatterLine = new (getChartClass("line"))(
          ctx.w,
          ctx,
          xyRatios,
          true
        );
        elGraph.push(
          scatterLine.draw(
            seriesTypes.scatter.series,
            "scatter",
            seriesTypes.scatter.i
          )
        );
      }
      if (seriesTypes.bubble.series.length > 0) {
        const bubbleLine = new (getChartClass("line"))(
          ctx.w,
          ctx,
          xyRatios,
          true
        );
        elGraph.push(
          bubbleLine.draw(
            seriesTypes.bubble.series,
            "bubble",
            seriesTypes.bubble.i
          )
        );
      }
    } else {
      const type = cnf.chart.type;
      switch (type) {
        case "line":
          elGraph = line.draw(this.w.seriesData.series, "line");
          break;
        case "area":
          elGraph = line.draw(this.w.seriesData.series, "area");
          break;
        case "bar":
          if (cnf.chart.stacked) {
            const barStacked = new (getChartClass("barStacked"))(
              ctx.w,
              ctx,
              xyRatios
            );
            elGraph = barStacked.draw(this.w.seriesData.series);
          } else {
            ctx.bar = new (getChartClass("bar"))(ctx.w, ctx, xyRatios);
            elGraph = ctx.bar.draw(this.w.seriesData.series);
          }
          break;
        case "candlestick":
          elGraph = boxCandlestick.draw(this.w.seriesData.series, "candlestick");
          break;
        case "boxPlot":
          elGraph = boxCandlestick.draw(this.w.seriesData.series, type);
          break;
        case "rangeBar":
          elGraph = ctx.rangeBar.draw(this.w.seriesData.series);
          break;
        case "rangeArea":
          elGraph = line.draw(
            this.w.rangeData.seriesRangeStart,
            "rangeArea",
            void 0,
            this.w.rangeData.seriesRangeEnd
          );
          break;
        case "heatmap": {
          const heatmap = new (getChartClass("heatmap"))(ctx.w, ctx, xyRatios);
          elGraph = heatmap.draw(this.w.seriesData.series);
          break;
        }
        case "treemap": {
          const treemap = new (getChartClass("treemap"))(ctx.w, ctx);
          elGraph = treemap.draw(this.w.seriesData.series);
          break;
        }
        case "pie":
        case "donut":
        case "polarArea":
          elGraph = ctx.pie.draw(this.w.seriesData.series);
          break;
        case "radialBar": {
          const radialBar = new (getChartClass("radialBar"))(ctx.w, ctx);
          elGraph = radialBar.draw(this.w.seriesData.series);
          break;
        }
        case "radar": {
          const radar = new (getChartClass("radar"))(ctx.w, ctx);
          elGraph = radar.draw(this.w.seriesData.series);
          break;
        }
        default:
          elGraph = line.draw(this.w.seriesData.series);
      }
    }
    return elGraph;
  }
  setSVGDimensions() {
    var _a;
    const { globals: gl, config: cnf } = this.w;
    cnf.chart.width = cnf.chart.width || "100%";
    cnf.chart.height = cnf.chart.height || "auto";
    const rawWidth = cnf.chart.width;
    const rawHeight = cnf.chart.height;
    gl.svgWidth = NaN;
    gl.svgHeight = NaN;
    let elDim = Utils$1.getDimensions(this.el);
    const widthUnit = rawWidth.toString().split(/[0-9]+/g).pop();
    if (widthUnit === "%") {
      if (Utils$1.isNumber(elDim[0])) {
        if (elDim[0].width === 0) {
          elDim = Utils$1.getDimensions(this.el.parentNode);
        }
        gl.svgWidth = elDim[0] * parseInt(rawWidth, 10) / 100;
      }
    } else if (widthUnit === "px" || widthUnit === "") {
      gl.svgWidth = parseInt(rawWidth, 10);
    }
    const heightUnit = String(rawHeight).toString().split(/[0-9]+/g).pop();
    if (rawHeight !== "auto" && rawHeight !== "") {
      if (heightUnit === "%") {
        const elParentDim = Utils$1.getDimensions(this.el.parentNode);
        gl.svgHeight = elParentDim[1] * parseInt(rawHeight, 10) / 100;
      } else {
        gl.svgHeight = parseInt(rawHeight, 10);
      }
    } else {
      gl.svgHeight = gl.axisCharts ? gl.svgWidth / 1.61 : gl.svgWidth / 1.2;
    }
    gl.svgWidth = Math.max(gl.svgWidth, 0);
    gl.svgHeight = Math.max(gl.svgHeight, 0);
    Graphics.setAttrs(this.w.dom.Paper.node, {
      width: gl.svgWidth,
      height: gl.svgHeight
    });
    if (heightUnit !== "%" && Environment.isBrowser()) {
      const offsetY = cnf.chart.sparkline.enabled ? 0 : gl.axisCharts ? cnf.chart.parentHeightOffset : 0;
      const paperNode = this.w.dom.Paper.node;
      if ((_a = paperNode.parentNode) == null ? void 0 : _a.parentNode) {
        paperNode.parentNode.parentNode.style.minHeight = `${gl.svgHeight + offsetY}px`;
      }
    }
    this.w.dom.elWrap.style.width = `${gl.svgWidth}px`;
    this.w.dom.elWrap.style.height = `${gl.svgHeight}px`;
  }
  shiftGraphPosition() {
    const { globals: gl } = this.w;
    const { translateY: tY, translateX: tX } = gl;
    Graphics.setAttrs(this.w.dom.elGraphical.node, {
      transform: `translate(${tX}, ${tY})`
    });
  }
  resizeNonAxisCharts() {
    var _a, _b;
    const { w } = this;
    let legendHeight = 0;
    let offY = w.config.chart.sparkline.enabled ? 1 : 15;
    offY += w.config.grid.padding.bottom;
    if (["top", "bottom"].includes(w.config.legend.position) && w.config.legend.show && !w.config.legend.floating) {
      legendHeight = ((_b = (_a = this.ctx.legend) == null ? void 0 : _a.legendHelpers.getLegendDimensions().clwh) != null ? _b : 0) + 7;
    }
    const el = w.dom.baseEl.querySelector(
      ".apexcharts-radialbar, .apexcharts-pie"
    );
    let chartInnerDimensions = w.globals.radialSize * 2.05;
    if (el && !w.config.chart.sparkline.enabled && w.config.plotOptions.radialBar.startAngle !== 0) {
      const elRadialRect = Utils$1.getBoundingClientRect(el);
      chartInnerDimensions = elRadialRect.bottom;
      const maxHeight = elRadialRect.bottom - elRadialRect.top;
      chartInnerDimensions = Math.max(w.globals.radialSize * 2.05, maxHeight);
    }
    const newHeight = Math.ceil(
      chartInnerDimensions + this.w.layout.translateY + legendHeight + offY
    );
    if (this.w.dom.elLegendForeign) {
      this.w.dom.elLegendForeign.setAttribute("height", String(newHeight));
    }
    if (w.config.chart.height && String(w.config.chart.height).includes("%"))
      return;
    this.w.dom.elWrap.style.height = `${newHeight}px`;
    Graphics.setAttrs(this.w.dom.Paper.node, { height: newHeight });
    if (Environment.isBrowser()) {
      this.w.dom.Paper.node.parentNode.parentNode.style.minHeight = `${newHeight}px`;
    }
  }
  coreCalculations() {
    new Range(this.w).init();
  }
  resetGlobals() {
    const resetxyValues = () => this.w.config.series.map(() => []);
    const globalObj = new Globals();
    const { globals: gl } = this.w;
    const parsingFlags = {
      dataWasParsed: this.w.axisFlags.dataWasParsed,
      originalSeries: gl.originalSeries
    };
    globalObj.initGlobalVars(gl);
    gl.seriesXvalues = resetxyValues();
    gl.seriesYvalues = resetxyValues();
    if (parsingFlags.dataWasParsed) {
      this.w.axisFlags.dataWasParsed = parsingFlags.dataWasParsed;
      gl.originalSeries = parsingFlags.originalSeries;
    }
  }
  isMultipleY() {
    if (Array.isArray(this.w.config.yaxis) && this.w.config.yaxis.length > 1) {
      this.w.globals.isMultipleYAxis = true;
      return true;
    }
    return false;
  }
  xySettings() {
    const { w } = this;
    let xyRatios = null;
    if (w.globals.axisCharts) {
      if (w.config.xaxis.crosshairs.position === "back") {
        new Crosshairs(this.w).drawXCrosshairs();
      }
      if (w.config.yaxis[0].crosshairs.position === "back") {
        new Crosshairs(this.w).drawYCrosshairs();
      }
      if (w.config.xaxis.type === "datetime" && w.config.xaxis.labels.formatter === void 0) {
        this.ctx.timeScale = new TimeScale(this.w, this.ctx);
        let formattedTimeScale = [];
        if (isFinite(w.globals.minX) && isFinite(w.globals.maxX) && !w.globals.isBarHorizontal) {
          formattedTimeScale = this.ctx.timeScale.calculateTimeScaleTicks(
            w.globals.minX,
            w.globals.maxX
          );
        } else if (w.globals.isBarHorizontal) {
          formattedTimeScale = this.ctx.timeScale.calculateTimeScaleTicks(
            w.globals.minY,
            w.globals.maxY
          );
        }
        this.ctx.timeScale.recalcDimensionsBasedOnFormat(formattedTimeScale);
      }
      const coreUtils = new CoreUtils(this.w);
      xyRatios = coreUtils.getCalculatedRatios();
    }
    return xyRatios;
  }
  /**
   * @param {any} targetChart
   */
  updateSourceChart(targetChart) {
    this.ctx.w.interact.selection = void 0;
    this.ctx.updateHelpers._updateOptions(
      {
        chart: {
          selection: {
            xaxis: {
              min: targetChart.w.globals.minX,
              max: targetChart.w.globals.maxX
            }
          }
        }
      },
      false,
      false
    );
  }
  setupBrushHandler() {
    const { ctx, w } = this;
    if (!w.config.chart.brush.enabled) return;
    if (typeof w.config.chart.events.selection !== "function") {
      const targets = Array.isArray(w.config.chart.brush.targets) ? w.config.chart.brush.targets : [w.config.chart.brush.target];
      targets.forEach((target) => {
        const targetChart = (
          /** @type {any} */
          ctx.constructor.getChartByID(
            target
          )
        );
        targetChart.w.globals.brushSource = this.ctx;
        if (typeof targetChart.w.config.chart.events.zoomed !== "function") {
          targetChart.w.config.chart.events.zoomed = () => this.updateSourceChart(targetChart);
        }
        if (typeof targetChart.w.config.chart.events.scrolled !== "function") {
          targetChart.w.config.chart.events.scrolled = () => (
            /**
             * @param {any} chart
             * @param {Event} e
             */
            this.updateSourceChart(targetChart)
          );
        }
      });
      w.config.chart.events.selection = (chart, e) => {
        targets.forEach((target) => {
          const targetChart = (
            /** @type {any} */
            ctx.constructor.getChartByID(
              target
            )
          );
          targetChart.ctx.updateHelpers._updateOptions(
            {
              xaxis: {
                min: e.xaxis.min,
                max: e.xaxis.max
              }
            },
            false,
            false,
            false,
            false
          );
        });
      };
    }
  }
  getAccessibleChartLabel() {
    const w = this.w;
    const cnf = w.config;
    if (cnf.chart.accessibility && cnf.chart.accessibility.description) {
      return cnf.chart.accessibility.description;
    }
    const chartType = cnf.chart.type;
    const parts = [];
    if (cnf.title.text) {
      parts.push(`${cnf.title.text}. ${chartType} chart`);
      if (cnf.subtitle.text) parts.push(cnf.subtitle.text);
    } else {
      const namedSeries = (() => {
        if (Array.isArray(w.seriesData.seriesNames) && w.seriesData.seriesNames.length) {
          return w.seriesData.seriesNames.filter(Boolean);
        }
        if (Array.isArray(cnf.series)) {
          return cnf.series.map((s) => typeof s === "object" && s !== null ? s.name : null).filter(Boolean);
        }
        return [];
      })();
      const seriesCount = w.seriesData.series.length || (cnf.series ? cnf.series.length : 0);
      if (namedSeries.length) {
        parts.push(
          `${chartType} chart with ${seriesCount} data series: ${namedSeries.join(", ")}`
        );
      } else {
        parts.push(`${chartType} chart with ${seriesCount} data series`);
      }
    }
    return parts.join(". ");
  }
}
class Data {
  /**
   * @param {import('../types/internal').ChartStateW} w
   */
  constructor(w, { resetGlobals = () => {
  }, isMultipleY = () => {
  } } = {}) {
    this.w = w;
    this.resetGlobals = resetGlobals;
    this.isMultipleY = isMultipleY;
    this.twoDSeries = [];
    this.threeDSeries = [];
    this.twoDSeriesX = [];
    this.seriesGoals = [];
    this.coreUtils = new CoreUtils(this.w);
    this.activeSeriesIndex = 0;
  }
  // Helper to get the first valid data point from the active series
  getFirstDataPoint() {
    const series = this.w.config.series;
    const sr = new Series(this.w);
    this.activeSeriesIndex = sr.getActiveConfigSeriesIndex();
    const activeItem = (
      /** @type {any} */
      series[this.activeSeriesIndex]
    );
    if (activeItem && activeItem.data && activeItem.data.length > 0 && activeItem.data[0] !== null && typeof activeItem.data[0] !== "undefined") {
      return activeItem.data[0];
    }
    return null;
  }
  isMultiFormat() {
    return this.isFormatXY() || this.isFormat2DArray();
  }
  // given format is [{x, y}, {x, y}]
  isFormatXY() {
    var _a;
    const firstDataPoint = this.getFirstDataPoint();
    if (!firstDataPoint || typeof firstDataPoint.x === "undefined") return false;
    const data = (
      /** @type {any} */
      (_a = this.w.config.series[this.activeSeriesIndex]) == null ? void 0 : _a.data
    );
    if (data) {
      const isXY = (pt) => pt && typeof pt.x !== "undefined";
      for (let k = 1; k < Math.min(3, data.length); k++) {
        if (isXY(data[k]) !== true) {
          console.warn(
            `ApexCharts: series data has mixed formats starting at index ${k}`
          );
          break;
        }
      }
    }
    return true;
  }
  // given format is [[x, y], [x, y]]
  isFormat2DArray() {
    const firstDataPoint = this.getFirstDataPoint();
    return firstDataPoint && Array.isArray(firstDataPoint);
  }
  /**
   * @param {any[]} ser
   * @param {number} i
   */
  handleFormat2DArray(ser, i) {
    const cnf = this.w.config;
    const data = ser[i].data;
    const isBoxPlot = cnf.chart.type === "boxPlot" || /** @type {any} */
    cnf.series[i].type === "boxPlot";
    for (let j = 0; j < data.length; j++) {
      const point = data[j];
      const x = point[0];
      const y = point[1];
      const z = point[2];
      if (typeof y !== "undefined") {
        if (Array.isArray(y) && y.length === 4 && !isBoxPlot) {
          this.twoDSeries.push(Utils$1.parseNumber(y[3]));
        } else if (point.length >= 5) {
          this.twoDSeries.push(Utils$1.parseNumber(point[4]));
        } else {
          this.twoDSeries.push(Utils$1.parseNumber(y));
        }
        this.w.axisFlags.dataFormatXNumeric = true;
      }
      if (cnf.xaxis.type === "datetime") {
        const ts = new Date(x).getTime();
        this.twoDSeriesX.push(ts);
      } else {
        this.twoDSeriesX.push(x);
      }
      if (typeof z !== "undefined") {
        this.threeDSeries.push(z);
        this.w.axisFlags.isDataXYZ = true;
      }
    }
  }
  /**
   * @param {any[]} ser
   * @param {number} i
   */
  handleFormatXY(ser, i) {
    const cnf = this.w.config;
    const gl = this.w.globals;
    const dt = new DateTime(this.w);
    const data = ser[i].data;
    let activeI = i;
    if (gl.collapsedSeriesIndices.indexOf(i) > -1) {
      activeI = this.activeSeriesIndex;
    }
    const activeData = ser[activeI].data;
    for (let j = 0; j < data.length; j++) {
      const point = data[j];
      if (typeof point.y !== "undefined") {
        const val = Array.isArray(point.y) ? Utils$1.parseNumber(point.y[point.y.length - 1]) : Utils$1.parseNumber(point.y);
        this.twoDSeries.push(val);
      }
      if (typeof this.seriesGoals[i] === "undefined") {
        this.seriesGoals[i] = [];
      }
      if (typeof point.goals !== "undefined" && Array.isArray(point.goals)) {
        this.seriesGoals[i].push(point.goals);
      } else {
        this.seriesGoals[i].push(null);
      }
      if (typeof point.z !== "undefined") {
        this.threeDSeries.push(point.z);
        this.w.axisFlags.isDataXYZ = true;
      }
    }
    for (let j = 0; j < activeData.length; j++) {
      const point = activeData[j];
      const x = point.x;
      const isXString = typeof x === "string";
      const isXArr = Array.isArray(x);
      const isXDate = !isXArr && !!dt.isValidDate(x);
      if (isXString || isXDate) {
        if (isXString || cnf.xaxis.convertedCatToNumeric) {
          const isRangeColumn = gl.isBarHorizontal && this.w.axisFlags.isRangeData;
          if (cnf.xaxis.type === "datetime" && !isRangeColumn) {
            this.twoDSeriesX.push(dt.parseDate(x));
          } else {
            this.fallbackToCategory = true;
            this.twoDSeriesX.push(x);
            if (!isNaN(x) && this.w.config.xaxis.type !== "category" && typeof x !== "string") {
              this.w.axisFlags.isXNumeric = true;
            }
          }
        } else {
          if (cnf.xaxis.type === "datetime") {
            this.twoDSeriesX.push(dt.parseDate(x.toString()));
          } else {
            this.w.axisFlags.dataFormatXNumeric = true;
            this.w.axisFlags.isXNumeric = true;
            this.twoDSeriesX.push(parseFloat(x));
          }
        }
      } else if (isXArr) {
        this.fallbackToCategory = true;
        this.twoDSeriesX.push(x);
      } else {
        this.w.axisFlags.isXNumeric = true;
        this.w.axisFlags.dataFormatXNumeric = true;
        this.twoDSeriesX.push(x);
      }
    }
  }
  /**
   * @param {any[]} ser
   * @param {number} i
   */
  handleRangeData(ser, i) {
    let range = { start: [], end: [], rangeUniques: [] };
    if (this.isFormat2DArray()) {
      range = this.handleRangeDataFormat("array", ser, i);
    } else if (this.isFormatXY()) {
      range = this.handleRangeDataFormat("xy", ser, i);
    }
    this.w.rangeData.seriesRangeStart[i] = range.start === void 0 ? [] : range.start;
    this.w.rangeData.seriesRangeEnd[i] = range.end === void 0 ? [] : range.end;
    this.w.rangeData.seriesRange[i] = range.rangeUniques;
    this.w.rangeData.seriesRange.forEach((sr) => {
      if (!sr) return;
      sr.forEach((sarr) => {
        const yItems = (
          /** @type {any} */
          sarr.y
        );
        const len = (
          /** @type {any[]} */
          yItems.length
        );
        if (len <= 1) return;
        for (let arri = 0; arri < len; arri++) {
          const arr = (
            /** @type {any} */
            yItems[arri]
          );
          const range1y1 = arr.y1;
          const range1y2 = arr.y2;
          for (let sri = arri + 1; sri < len; sri++) {
            const range2 = (
              /** @type {any} */
              yItems[sri]
            );
            const range2y1 = range2.y1;
            const range2y2 = range2.y2;
            if (range1y1 <= range2y2 && range2y1 <= range1y2) {
              const sarrAny = (
                /** @type {any} */
                sarr
              );
              sarrAny.overlaps.add(arr.rangeName);
              sarrAny.overlaps.add(range2.rangeName);
            }
          }
        }
      });
    });
    return range;
  }
  /**
   * @param {any[]} ser
   * @param {number} i
   */
  handleCandleStickBoxData(ser, i) {
    let ohlc = { o: [], h: [], m: [], l: [], c: [] };
    if (this.isFormat2DArray()) {
      ohlc = this.handleCandleStickBoxDataFormat("array", ser, i);
    } else if (this.isFormatXY()) {
      ohlc = this.handleCandleStickBoxDataFormat("xy", ser, i);
    }
    this.w.candleData.seriesCandleO[i] = ohlc.o;
    this.w.candleData.seriesCandleH[i] = ohlc.h;
    this.w.candleData.seriesCandleM[i] = ohlc.m;
    this.w.candleData.seriesCandleL[i] = ohlc.l;
    this.w.candleData.seriesCandleC[i] = ohlc.c;
    return ohlc;
  }
  /**
   * @param {string} format
   * @param {any[]} ser
   * @param {number} i
   */
  handleRangeDataFormat(format, ser, i) {
    const rangeStart = [];
    const rangeEnd = [];
    const uniqueKeysMap = /* @__PURE__ */ new Map();
    const uniqueKeys = [];
    ser[i].data.forEach((item) => {
      if (!uniqueKeysMap.has(item.x)) {
        const keyObj = {
          x: item.x,
          overlaps: /* @__PURE__ */ new Set(),
          y: []
        };
        uniqueKeysMap.set(item.x, keyObj);
        uniqueKeys.push(keyObj);
      }
    });
    if (format === "array") {
      for (let j = 0; j < ser[i].data.length; j++) {
        if (Array.isArray(ser[i].data[j])) {
          rangeStart.push(ser[i].data[j][1][0]);
          rangeEnd.push(ser[i].data[j][1][1]);
        } else {
          rangeStart.push(ser[i].data[j]);
          rangeEnd.push(ser[i].data[j]);
        }
      }
    } else if (format === "xy") {
      for (let j = 0; j < ser[i].data.length; j++) {
        const isDataPoint2D = Array.isArray(ser[i].data[j].y);
        const id = Utils$1.randomId();
        const x = ser[i].data[j].x;
        const y = {
          y1: isDataPoint2D ? ser[i].data[j].y[0] : ser[i].data[j].y,
          y2: isDataPoint2D ? ser[i].data[j].y[1] : ser[i].data[j].y,
          rangeName: id
        };
        ser[i].data[j].rangeName = id;
        const keyObj = uniqueKeysMap.get(x);
        if (keyObj) {
          keyObj.y.push(y);
        }
        rangeStart.push(y.y1);
        rangeEnd.push(y.y2);
      }
    }
    return {
      start: rangeStart,
      end: rangeEnd,
      rangeUniques: uniqueKeys
    };
  }
  /**
   * @param {string} format
   * @param {any[]} ser
   * @param {number} i
   */
  handleCandleStickBoxDataFormat(format, ser, i) {
    const w = this.w;
    const isBoxPlot = w.config.chart.type === "boxPlot" || /** @type {Record<string,any>} */
    w.config.series[i].type === "boxPlot";
    const serO = [];
    const serH = [];
    const serM = [];
    const serL = [];
    const serC = [];
    const data = ser[i].data;
    let getVals;
    if (format === "array") {
      const isFlat = isBoxPlot && data[0].length === 6 || !isBoxPlot && data[0].length === 5;
      if (isFlat) {
        getVals = (d) => d.slice(1);
      } else {
        getVals = (d) => Array.isArray(d[1]) ? d[1] : [];
      }
    } else {
      getVals = (d) => Array.isArray(d.y) ? d.y : [];
    }
    for (let j = 0; j < data.length; j++) {
      const vals = getVals(data[j]);
      if (vals && vals.length >= 2) {
        serO.push(vals[0]);
        serH.push(vals[1]);
        if (isBoxPlot) {
          serM.push(vals[2]);
          serL.push(vals[3]);
          serC.push(vals[4]);
        } else {
          serL.push(vals[2]);
          serC.push(vals[3]);
        }
      }
    }
    return {
      o: serO,
      h: serH,
      m: serM,
      l: serL,
      c: serC
    };
  }
  /**
   * @param {any[]} ser
   */
  parseDataAxisCharts(ser) {
    var _a, _b;
    const cnf = this.w.config;
    const gl = this.w.globals;
    const dt = new DateTime(this.w);
    const xlabels = cnf.labels.length > 0 ? cnf.labels.slice() : cnf.xaxis.categories.slice();
    this.w.axisFlags.isRangeBar = cnf.chart.type === "rangeBar" && gl.isBarHorizontal;
    this.w.labelData.hasXaxisGroups = cnf.xaxis.type === "category" && cnf.xaxis.group.groups.length > 0;
    if (this.w.labelData.hasXaxisGroups) {
      this.w.labelData.groups = cnf.xaxis.group.groups;
    }
    ser.forEach((s, i) => {
      if (s.name !== void 0) {
        this.w.seriesData.seriesNames.push(s.name);
      } else {
        this.w.seriesData.seriesNames.push(
          "series-" + parseInt(String(i + 1), 10)
        );
      }
    });
    this.coreUtils.setSeriesYAxisMappings();
    const buckets = [];
    const groups = [
      ...new Set(cnf.series.map((s) => s.group))
    ];
    cnf.series.forEach((s, i) => {
      const index = groups.indexOf(s.group);
      if (!buckets[index]) buckets[index] = [];
      buckets[index].push(this.w.seriesData.seriesNames[i]);
    });
    this.w.labelData.seriesGroups = buckets;
    const handleDates = () => {
      for (let j = 0; j < xlabels.length; j++) {
        if (typeof xlabels[j] === "string") {
          const isDate = dt.isValidDate(xlabels[j]);
          if (isDate) {
            this.twoDSeriesX.push(dt.parseDate(xlabels[j]));
          } else {
            throw new Error(
              "You have provided invalid Date format. Please provide a valid JavaScript Date"
            );
          }
        } else {
          this.twoDSeriesX.push(xlabels[j]);
        }
      }
    };
    for (let i = 0; i < ser.length; i++) {
      this.twoDSeries = [];
      this.twoDSeriesX = [];
      this.threeDSeries = [];
      if (typeof ser[i].data === "undefined") {
        console.error(
          "It is a possibility that you may have not included 'data' property in series."
        );
        return;
      }
      const dr = cnf.chart.dataReducer;
      if ((dr == null ? void 0 : dr.enabled) && this.isMultiFormat() && ser[i].data.length > ((_a = dr.threshold) != null ? _a : 500)) {
        ser[i] = __spreadProps(__spreadValues({}, ser[i]), {
          data: Data.lttbDownsample(ser[i].data, (_b = dr.targetPoints) != null ? _b : 250)
        });
      }
      if (cnf.chart.type === "rangeBar" || cnf.chart.type === "rangeArea" || ser[i].type === "rangeBar" || ser[i].type === "rangeArea") {
        this.w.axisFlags.isRangeData = true;
        this.handleRangeData(ser, i);
      }
      if (this.isMultiFormat()) {
        if (this.isFormat2DArray()) {
          this.handleFormat2DArray(ser, i);
        } else if (this.isFormatXY()) {
          this.handleFormatXY(ser, i);
        }
        if (cnf.chart.type === "candlestick" || ser[i].type === "candlestick" || cnf.chart.type === "boxPlot" || ser[i].type === "boxPlot") {
          this.handleCandleStickBoxData(ser, i);
        }
        this.w.seriesData.series.push(this.twoDSeries);
        this.w.labelData.labels.push(this.twoDSeriesX);
        this.w.seriesData.seriesX.push(this.twoDSeriesX);
        this.w.seriesData.seriesGoals = this.seriesGoals;
        if (i === this.activeSeriesIndex && !this.fallbackToCategory) {
          this.w.axisFlags.isXNumeric = true;
        }
      } else {
        if (cnf.xaxis.type === "datetime") {
          this.w.axisFlags.isXNumeric = true;
          handleDates();
          this.w.seriesData.seriesX.push(this.twoDSeriesX);
        } else if (cnf.xaxis.type === "numeric") {
          this.w.axisFlags.isXNumeric = true;
          if (xlabels.length > 0) {
            this.twoDSeriesX = xlabels;
            this.w.seriesData.seriesX.push(this.twoDSeriesX);
          }
        }
        this.w.labelData.labels.push(this.twoDSeriesX);
        const singleArray = ser[i].data.map(
          (d) => Utils$1.parseNumber(d)
        );
        this.w.seriesData.series.push(singleArray);
      }
      this.w.seriesData.seriesZ.push(this.threeDSeries);
      if (ser[i].color !== void 0) {
        this.w.seriesData.seriesColors.push(ser[i].color);
      } else {
        this.w.seriesData.seriesColors.push(
          /** @type {any} */
          void 0
        );
      }
    }
    return this.w;
  }
  /**
   * @param {any[]} ser
   */
  parseDataNonAxisCharts(ser) {
    const cnf = this.w.config;
    const hasOldFormat = Array.isArray(ser) && ser.every((s) => typeof s === "number") && cnf.labels.length > 0;
    const hasNewFormat = Array.isArray(ser) && ser.some(
      (s) => s && typeof s === "object" && s.data || s && typeof s === "object" && s.parsing
    );
    if (hasOldFormat && hasNewFormat) {
      console.warn(
        "ApexCharts: Both old format (numeric series + labels) and new format (series objects with data/parsing) detected. Using old format for backward compatibility."
      );
    }
    if (hasOldFormat) {
      this.w.seriesData.series = /** @type {any} */
      ser.slice();
      this.w.seriesData.seriesNames = cnf.labels.slice();
      for (let i = 0; i < this.w.seriesData.series.length; i++) {
        if (this.w.seriesData.seriesNames[i] === void 0) {
          this.w.seriesData.seriesNames.push("series-" + (i + 1));
        }
      }
      return this.w;
    }
    if (Array.isArray(ser) && ser.every((s) => typeof s === "number")) {
      this.w.seriesData.series = /** @type {any} */
      ser.slice();
      this.w.seriesData.seriesNames = [];
      for (let i = 0; i < this.w.seriesData.series.length; i++) {
        this.w.seriesData.seriesNames.push(cnf.labels[i] || `series-${i + 1}`);
      }
      return this.w;
    }
    const processedData = this.extractPieDataFromSeries(ser);
    this.w.seriesData.series = processedData.values;
    this.w.seriesData.seriesNames = processedData.labels;
    if (cnf.chart.type === "radialBar") {
      this.w.seriesData.series = this.w.seriesData.series.map((val) => {
        const numVal = Utils$1.parseNumber(val);
        if (numVal > 100) {
          console.warn(
            `ApexCharts: RadialBar value ${numVal} > 100, consider using percentage values (0-100)`
          );
        }
        return numVal;
      });
    }
    for (let i = 0; i < this.w.seriesData.series.length; i++) {
      if (this.w.seriesData.seriesNames[i] === void 0) {
        this.w.seriesData.seriesNames.push("series-" + (i + 1));
      }
    }
    return this.w;
  }
  /**
   * Reset parsing flags to allow re-parsing of data during updates
   */
  resetParsingFlags() {
    const w = this.w;
    w.axisFlags.dataWasParsed = false;
    w.globals.originalSeries = null;
    if (w.config.series) {
      w.config.series.forEach((serie) => {
        if (
          /** @type {any} */
          serie.__apexParsed
        ) {
          delete /** @type {any} */
          serie.__apexParsed;
        }
      });
    }
  }
  /**
   * @param {any[]} ser
   */
  extractPieDataFromSeries(ser) {
    const values = [];
    const labels = [];
    if (!Array.isArray(ser)) {
      console.warn("ApexCharts: Expected array for series data");
      return { values: [], labels: [] };
    }
    if (ser.length === 0) {
      console.warn("ApexCharts: Empty series array");
      return { values: [], labels: [] };
    }
    const firstItem = ser[0];
    if (typeof firstItem === "object" && firstItem !== null && firstItem.data) {
      this.extractPieDataFromSeriesObjects(ser, values, labels);
    } else {
      console.warn(
        "ApexCharts: Unsupported series format for pie/donut/radialBar. Expected series objects with data property."
      );
      return { values: [], labels: [] };
    }
    return { values, labels };
  }
  // Extract data from series objects: [{ data: [...], parsing: {...} }]
  /**
   * @param {any[]} seriesArray
   * @param {any[]} values
   * @param {any[]} labels
   */
  extractPieDataFromSeriesObjects(seriesArray, values, labels) {
    seriesArray.forEach((serie, serieIndex) => {
      if (!serie.data || !Array.isArray(serie.data)) {
        console.warn(`ApexCharts: Series ${serieIndex} has no valid data array`);
        return;
      }
      serie.data.forEach((dataPoint) => {
        if (typeof dataPoint === "object" && dataPoint !== null) {
          if (dataPoint.x !== void 0 && dataPoint.y !== void 0) {
            labels.push(String(dataPoint.x));
            values.push(Utils$1.parseNumber(dataPoint.y));
          } else {
            console.warn(
              "ApexCharts: Invalid data point format for pie chart. Expected {x, y} format:",
              dataPoint
            );
          }
        } else {
          console.warn(
            "ApexCharts: Expected object data point, got:",
            typeof dataPoint
          );
        }
      });
    });
  }
  /** User possibly set string categories in xaxis.categories or labels prop
   * Or didn't set xaxis labels at all - in which case we manually do it.
   * If user passed series data as [[3, 2], [4, 5]] or [{ x: 3, y: 55 }],
   * this shouldn't be called
   * @param {any[]} ser - the series which user passed to the config
   */
  handleExternalLabelsData(ser) {
    const cnf = this.w.config;
    if (cnf.xaxis.categories.length > 0) {
      this.w.labelData.labels = cnf.xaxis.categories;
    } else if (cnf.labels.length > 0) {
      this.w.labelData.labels = cnf.labels.slice();
    } else if (this.fallbackToCategory) {
      this.w.labelData.labels = /** @type {string[]} */
      /** @type {unknown} */
      this.w.labelData.labels[0];
      if (this.w.rangeData.seriesRange.length) {
        this.w.rangeData.seriesRange.map((srt) => {
          srt.forEach((sr) => {
            if (this.w.labelData.labels.indexOf(sr.x) < 0 && sr.x) {
              this.w.labelData.labels.push(sr.x);
            }
          });
        });
        const _labels = this.w.labelData.labels;
        if (_labels.length > 0 && (typeof _labels[0] === "number" || typeof _labels[0] === "string")) {
          this.w.labelData.labels = [...new Set(_labels)];
        } else {
          const _seen = /* @__PURE__ */ new Map();
          for (const _label of _labels) {
            const _key = JSON.stringify(_label);
            if (!_seen.has(_key)) _seen.set(_key, _label);
          }
          this.w.labelData.labels = Array.from(_seen.values());
        }
      }
      if (cnf.xaxis.convertedCatToNumeric) {
        const defaults = new Defaults(cnf);
        defaults.convertCatToNumericXaxis(cnf, this.w.seriesData.seriesX[0]);
        this._generateExternalLabels(ser);
      }
    } else {
      this._generateExternalLabels(ser);
    }
  }
  /**
   * @param {any[]} ser
   */
  _generateExternalLabels(ser) {
    const gl = this.w.globals;
    const cnf = this.w.config;
    let labelArr = [];
    if (gl.axisCharts) {
      if (this.w.seriesData.series.length > 0) {
        if (this.isFormatXY()) {
          const seriesDataFiltered = cnf.series.map(
            (serie) => {
              const seen = /* @__PURE__ */ new Map();
              for (const point of serie.data) {
                if (!seen.has(point.x)) seen.set(point.x, point);
              }
              return Array.from(seen.values());
            }
          );
          const len = seriesDataFiltered.reduce(
            (p, c, i, a) => a[p].length > c.length ? p : i,
            0
          );
          for (let i = 0; i < seriesDataFiltered[len].length; i++) {
            labelArr.push(i + 1);
          }
        } else {
          for (let i = 0; i < this.w.seriesData.series[gl.maxValsInArrayIndex].length; i++) {
            labelArr.push(i + 1);
          }
        }
      }
      this.w.seriesData.seriesX = [];
      for (let i = 0; i < ser.length; i++) {
        this.w.seriesData.seriesX.push(labelArr);
      }
      if (!this.w.globals.isBarHorizontal) {
        this.w.axisFlags.isXNumeric = true;
      }
    }
    if (labelArr.length === 0) {
      labelArr = gl.axisCharts ? [] : (
        /**
         * @param {Record<string, any>} gls
         * @param {number} glsi
         */
        this.w.seriesData.series.map((gls, glsi) => {
          return glsi + 1;
        })
      );
      for (let i = 0; i < ser.length; i++) {
        this.w.seriesData.seriesX.push(labelArr);
      }
    }
    this.w.labelData.labels = /** @type {string[]} */
    /** @type {unknown} */
    labelArr;
    if (cnf.xaxis.convertedCatToNumeric) {
      this.w.labelData.categoryLabels = labelArr.map((l) => {
        return cnf.xaxis.labels.formatter(l);
      });
    }
    this.w.axisFlags.noLabelsProvided = true;
  }
  /**
   * @param {any[]} series
   */
  parseRawDataIfNeeded(series) {
    const cnf = this.w.config;
    const gl = this.w.globals;
    const globalParsing = cnf.parsing;
    if (this.w.axisFlags.dataWasParsed) {
      return series;
    }
    if (!globalParsing && !series.some((s) => s.parsing)) {
      return series;
    }
    const processedSeries = series.map((serie, index) => {
      var _a, _b, _c;
      if (!serie.data || !Array.isArray(serie.data) || serie.data.length === 0) {
        return serie;
      }
      const effectiveParsing = {
        x: ((_a = serie.parsing) == null ? void 0 : _a.x) || (globalParsing == null ? void 0 : globalParsing.x),
        y: ((_b = serie.parsing) == null ? void 0 : _b.y) || (globalParsing == null ? void 0 : globalParsing.y),
        z: ((_c = serie.parsing) == null ? void 0 : _c.z) || (globalParsing == null ? void 0 : globalParsing.z)
      };
      if (!effectiveParsing.x && !effectiveParsing.y) {
        return serie;
      }
      const firstDataPoint = serie.data[0];
      if (typeof firstDataPoint === "object" && firstDataPoint !== null && (Object.prototype.hasOwnProperty.call(firstDataPoint, "x") || Object.prototype.hasOwnProperty.call(firstDataPoint, "y")) || Array.isArray(firstDataPoint)) {
        return serie;
      }
      if (!effectiveParsing.x || !effectiveParsing.y || Array.isArray(effectiveParsing.y) && effectiveParsing.y.length === 0) {
        console.warn(
          `ApexCharts: Series ${index} has parsing config but missing x or y field specification`
        );
        return serie;
      }
      const transformedData = serie.data.map(
        (item, itemIndex) => {
          if (typeof item !== "object" || item === null) {
            console.warn(
              `ApexCharts: Series ${index}, data point ${itemIndex} is not an object, skipping parsing`
            );
            return item;
          }
          const x = this.getNestedValue(item, effectiveParsing.x);
          let y;
          let z = void 0;
          if (Array.isArray(effectiveParsing.y)) {
            const yValues = effectiveParsing.y.map(
              (fieldName) => this.getNestedValue(item, fieldName)
            );
            if (this.w.config.chart.type === "bubble") {
              if (yValues.length < 2) {
                console.warn(
                  `ApexCharts: series[${index}] bubble chart requires parseData.y to have at least 2 fields (y and z). Got: ${JSON.stringify(effectiveParsing.y)}`
                );
              }
              y = yValues[0];
            } else {
              y = yValues;
            }
          } else {
            y = this.getNestedValue(item, effectiveParsing.y);
          }
          if (effectiveParsing.z) {
            z = this.getNestedValue(item, effectiveParsing.z);
          }
          if (x === void 0) {
            console.warn(
              `ApexCharts: Series ${index}, data point ${itemIndex} missing field '${effectiveParsing.x}'`
            );
          }
          if (y === void 0) {
            console.warn(
              `ApexCharts: Series ${index}, data point ${itemIndex} missing field '${effectiveParsing.y}'`
            );
          }
          const result = { x, y, z: void 0 };
          if (this.w.config.chart.type === "bubble" && Array.isArray(effectiveParsing.y) && effectiveParsing.y.length === 2) {
            const zValue = this.getNestedValue(item, effectiveParsing.y[1]);
            if (zValue !== void 0) {
              result.z = zValue;
            }
          }
          if (z !== void 0) {
            result.z = z;
          }
          return result;
        }
      );
      return __spreadProps(__spreadValues({}, serie), {
        data: transformedData,
        __apexParsed: true
      });
    });
    this.w.axisFlags.dataWasParsed = true;
    if (!gl.originalSeries) {
      gl.originalSeries = Utils$1.clone(series);
    }
    return processedSeries;
  }
  /**
   * Get nested object value using dot notation path
   * @param {Object} obj - The object to search in
   * @param {string} path - Dot notation path (e.g., 'user.profile.name')
   * @returns {*} The value at the path, or undefined if not found
   */
  getNestedValue(obj, path) {
    if (!obj || typeof obj !== "object" || !path) {
      return void 0;
    }
    if (path.indexOf(".") === -1) {
      return (
        /** @type {any} */
        obj[path]
      );
    }
    const keys = path.split(".");
    let current = obj;
    for (let i = 0; i < keys.length; i++) {
      if (current === null || current === void 0 || typeof current !== "object") {
        return void 0;
      }
      current = /** @type {any} */
      current[keys[i]];
    }
    return current;
  }
  // Segregate user provided data into appropriate vars
  /**
   * @param {any[]} ser
   */
  parseData(ser) {
    const w = this.w;
    const cnf = w.config;
    const gl = w.globals;
    ser = this.parseRawDataIfNeeded(ser);
    cnf.series = ser;
    gl.initialSeries = Utils$1.clone(ser);
    this.excludeCollapsedSeriesInYAxis();
    this.fallbackToCategory = false;
    this.resetGlobals();
    this.isMultipleY();
    if (gl.axisCharts) {
      this.parseDataAxisCharts(ser);
      this.coreUtils.getLargestSeries();
    } else {
      this.parseDataNonAxisCharts(ser);
    }
    if (cnf.chart.stacked) {
      const series = new Series(this.w);
      this.w.seriesData.series = series.setNullSeriesToZeroValues(
        this.w.seriesData.series
      );
    }
    this.coreUtils.getSeriesTotals();
    if (gl.axisCharts) {
      this.w.seriesData.stackedSeriesTotals = this.coreUtils.getStackedSeriesTotals();
      this.w.seriesData.stackedSeriesTotalsByGroups = this.coreUtils.getStackedSeriesTotalsByGroups();
    }
    this.coreUtils.getPercentSeries();
    if (!this.w.axisFlags.dataFormatXNumeric && (!this.w.axisFlags.isXNumeric || cnf.xaxis.type === "numeric" && cnf.labels.length === 0 && cnf.xaxis.categories.length === 0)) {
      this.handleExternalLabelsData(ser);
    }
    const catLabels = this.coreUtils.getCategoryLabels(this.w.labelData.labels);
    for (let l = 0; l < catLabels.length; l++) {
      if (Array.isArray(catLabels[l])) {
        this.w.axisFlags.isMultiLineX = true;
        break;
      }
    }
    return {
      // w.seriesData (future slice)
      seriesData: {
        series: this.w.seriesData.series,
        seriesNames: this.w.seriesData.seriesNames,
        seriesX: this.w.seriesData.seriesX,
        seriesZ: this.w.seriesData.seriesZ,
        seriesColors: this.w.seriesData.seriesColors,
        seriesGoals: this.w.seriesData.seriesGoals,
        initialSeries: gl.initialSeries,
        originalSeries: gl.originalSeries,
        stackedSeriesTotals: this.w.seriesData.stackedSeriesTotals,
        stackedSeriesTotalsByGroups: this.w.seriesData.stackedSeriesTotalsByGroups,
        noLabelsProvided: this.w.axisFlags.noLabelsProvided
      },
      // w.rangeData (future slice)
      rangeData: {
        seriesRangeStart: this.w.rangeData.seriesRangeStart,
        seriesRangeEnd: this.w.rangeData.seriesRangeEnd,
        seriesRange: this.w.rangeData.seriesRange
      },
      // w.candleData (future slice)
      candleData: {
        seriesCandleO: this.w.candleData.seriesCandleO,
        seriesCandleH: this.w.candleData.seriesCandleH,
        seriesCandleM: this.w.candleData.seriesCandleM,
        seriesCandleL: this.w.candleData.seriesCandleL,
        seriesCandleC: this.w.candleData.seriesCandleC
      },
      // w.labelData (future slice)
      labelData: {
        labels: this.w.labelData.labels,
        categoryLabels: this.w.labelData.categoryLabels
      },
      // w.axisFlags (future slice)
      axisFlags: {
        isXNumeric: this.w.axisFlags.isXNumeric,
        dataFormatXNumeric: this.w.axisFlags.dataFormatXNumeric,
        isDataXYZ: this.w.axisFlags.isDataXYZ,
        isRangeData: this.w.axisFlags.isRangeData,
        isRangeBar: this.w.axisFlags.isRangeBar,
        isMultiLineX: this.w.axisFlags.isMultiLineX,
        dataWasParsed: this.w.axisFlags.dataWasParsed,
        hasXaxisGroups: this.w.labelData.hasXaxisGroups,
        groups: this.w.labelData.groups,
        seriesGroups: this.w.labelData.seriesGroups
      }
    };
  }
  /**
   * Largest-Triangle-Three-Bucket (LTTB) downsampling.
   *
   * Reduces `data` to `targetPoints` points while preserving the visual shape
   * of the series as perceived by the human eye.
   *
   * @param {any[]} data   - Raw series data in [{x,y}] or [[x,y]] format.
   * @param {number} targetPoints - Desired output length (>= 3).
   * @returns {any[]} Downsampled array in the same format as the input.
   */
  static lttbDownsample(data, targetPoints) {
    const len = data.length;
    if (targetPoints >= len || targetPoints < 3) return data;
    const isXY = !Array.isArray(data[0]);
    const getX = isXY ? (p) => p.x : (p) => p[0];
    const getY = isXY ? (p) => p.y : (p) => p[1];
    const sampled = [];
    sampled.push(data[0]);
    const bucketSize = (len - 2) / (targetPoints - 2);
    let a = 0;
    for (let i = 0; i < targetPoints - 2; i++) {
      const avgRangeStart = Math.floor((i + 1) * bucketSize) + 1;
      const avgRangeEnd = Math.min(Math.floor((i + 2) * bucketSize) + 1, len);
      let avgX = 0;
      let avgY = 0;
      const avgRangeLen = avgRangeEnd - avgRangeStart;
      for (let j = avgRangeStart; j < avgRangeEnd; j++) {
        avgX += getX(data[j]);
        avgY += getY(data[j]);
      }
      avgX /= avgRangeLen;
      avgY /= avgRangeLen;
      const rangeStart = Math.floor(i * bucketSize) + 1;
      const rangeEnd = Math.min(Math.floor((i + 1) * bucketSize) + 1, len);
      const pointAX = getX(data[a]);
      const pointAY = getY(data[a]);
      let maxArea = -1;
      let maxAreaIdx = rangeStart;
      for (let j = rangeStart; j < rangeEnd; j++) {
        const area = Math.abs(
          (pointAX - avgX) * (getY(data[j]) - pointAY) - (pointAX - getX(data[j])) * (avgY - pointAY)
        ) * 0.5;
        if (area > maxArea) {
          maxArea = area;
          maxAreaIdx = j;
        }
      }
      sampled.push(data[maxAreaIdx]);
      a = maxAreaIdx;
    }
    sampled.push(data[len - 1]);
    return sampled;
  }
  excludeCollapsedSeriesInYAxis() {
    const w = this.w;
    const yAxisIndexes = [];
    w.globals.seriesYAxisMap.forEach((yAxisArr, yi) => {
      let collapsedCount = 0;
      yAxisArr.forEach((seriesIndex) => {
        if (w.globals.collapsedSeriesIndices.indexOf(seriesIndex) !== -1) {
          collapsedCount++;
        }
      });
      if (collapsedCount > 0 && collapsedCount == yAxisArr.length) {
        yAxisIndexes.push(yi);
      }
    });
    w.globals.ignoreYAxisIndexes = yAxisIndexes.map((x) => x);
  }
}
class UpdateHelpers {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   * @param {import('../../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
  }
  /**
   * private method to update Options.
   *
   * @param {Record<string, any>} options - A new config object can be passed which will be merged with the existing config object
   * @param {boolean} redraw - should redraw from beginning or should use existing paths and redraw from there
   * @param {boolean} animate - should animate or not on updating Options
   * @param {boolean} overwriteInitialConfig - should update the initial config or not
   */
  _updateOptions(options2, redraw = false, animate = true, updateSyncedCharts = true, overwriteInitialConfig = false) {
    return new Promise((resolve) => {
      let charts = [this.ctx];
      if (updateSyncedCharts) {
        charts = this.ctx.getSyncedCharts();
      }
      if (this.w.globals.isExecCalled) {
        charts = [this.ctx];
        this.w.globals.isExecCalled = false;
      }
      charts.forEach((ch, chartIndex) => {
        const w = ch.w;
        w.globals.shouldAnimate = animate;
        if (!redraw) {
          w.globals.resized = true;
          w.globals.dataChanged = true;
          if (animate) {
            ch.series.getPreviousPaths();
          }
        }
        if (options2 && typeof options2 === "object") {
          ch.config = new Config(options2);
          options2 = CoreUtils.extendArrayProps(ch.config, options2, w);
          if (ch.w.globals.chartID !== this.w.globals.chartID) {
            delete options2.series;
          }
          w.config = Utils$1.extend(w.config, options2);
          if (overwriteInitialConfig) {
            w.globals.lastXAxis = options2.xaxis ? Utils$1.clone(options2.xaxis) : [];
            w.globals.lastYAxis = options2.yaxis ? Utils$1.clone(options2.yaxis) : [];
            w.globals.initialConfig = Utils$1.extend({}, w.config);
            w.globals.initialSeries = Utils$1.clone(w.config.series);
            if (options2.series) {
              for (let i = 0; i < w.globals.collapsedSeriesIndices.length; i++) {
                const series = w.config.series[w.globals.collapsedSeriesIndices[i]];
                w.globals.collapsedSeries[i].data = w.globals.axisCharts ? (
                  /** @type {any} */
                  series.data.slice()
                ) : series;
              }
              for (let i = 0; i < w.globals.ancillaryCollapsedSeriesIndices.length; i++) {
                const series = w.config.series[w.globals.ancillaryCollapsedSeriesIndices[i]];
                w.globals.ancillaryCollapsedSeries[i].data = w.globals.axisCharts ? (
                  /** @type {any} */
                  series.data.slice()
                ) : series;
              }
              ch.series.emptyCollapsedSeries(w.config.series);
            }
          }
        }
        return ch.update(options2).then(() => {
          if (chartIndex === charts.length - 1) {
            resolve(ch);
          }
        });
      });
    });
  }
  /**
   * Private method to update Series.
   *
   * @param {any[]} newSeries - New series which will override the existing
   * @param {boolean} animate
   */
  _updateSeries(newSeries, animate, overwriteInitialSeries = false) {
    return new Promise((resolve) => {
      const w = this.w;
      w.globals.shouldAnimate = animate;
      w.globals.dataChanged = true;
      PerformanceCache.invalidateSelectors(w);
      if (animate) {
        this.ctx.series.getPreviousPaths();
      }
      const prevSeriesCount = w.config.series.length;
      this.ctx.data.resetParsingFlags();
      const parsedState = this.ctx.data.parseData(newSeries);
      this.ctx._writeParsedSeriesData(parsedState.seriesData);
      this.ctx._writeParsedRangeData(parsedState.rangeData);
      this.ctx._writeParsedCandleData(parsedState.candleData);
      this.ctx._writeParsedLabelData(parsedState.labelData);
      this.ctx._writeParsedAxisFlags(parsedState.axisFlags);
      if (overwriteInitialSeries) {
        if (w.globals.initialConfig) {
          w.globals.initialConfig.series = Utils$1.clone(w.config.series);
        }
        w.globals.initialSeries = Utils$1.clone(w.config.series);
      }
      if (this._canUseFastPath(newSeries, prevSeriesCount, w)) {
        return this.ctx.fastUpdate(animate).then(() => {
          resolve(this.ctx);
        });
      }
      return this.ctx.update().then(() => {
        resolve(this.ctx);
      });
    });
  }
  /**
   * Returns true if the data-only fast path can be used for this update.
   * Fast path skips rebuilding grid, axes, legend, annotations, and tooltip DOM.
   *
   * Requirements:
   * - Chart has been fully rendered (DOM exists)
   * - Axis chart (non-axis charts like pie always need full rebuild due to radial layout)
   * - Series count unchanged (grid column/row counts depend on it)
   * - No series currently collapsing (collapsed series changes visible data range)
   * - Not a combo chart (combo charts mix types and need coordinated axis recalc)
   * - Not currently zoomed (zoomed charts have altered x-labels that need recalculation)
   * @param {any[]} newSeries
   * @param {number} prevSeriesCount
   * @param {import('../../types/internal').ChartStateW} w
   */
  _canUseFastPath(newSeries, prevSeriesCount, w) {
    if (!w.dom.elGraphical) return false;
    if (!w.globals.axisCharts) return false;
    if (newSeries.length !== prevSeriesCount) return false;
    if (w.globals.collapsedSeries.length > 0) return false;
    if (w.globals.ancillaryCollapsedSeries.length > 0) return false;
    if (w.globals.risingSeries.length > 0) return false;
    if (w.globals.comboCharts) return false;
    if (w.interact.zoomed) return false;
    return true;
  }
  /**
   * @param {any} s
   * @param {number} i
   */
  _extendSeries(s, i) {
    const w = this.w;
    const ser = w.config.series[i];
    return __spreadProps(__spreadValues(
      {},
      /** @type {Record<string,any>} */
      w.config.series[i]
    ), {
      name: s.name ? s.name : (
        /** @type {any} */
        ser == null ? void 0 : ser.name
      ),
      color: s.color ? s.color : (
        /** @type {any} */
        ser == null ? void 0 : ser.color
      ),
      type: s.type ? s.type : (
        /** @type {any} */
        ser == null ? void 0 : ser.type
      ),
      group: s.group ? s.group : (
        /** @type {any} */
        ser == null ? void 0 : ser.group
      ),
      hidden: typeof s.hidden !== "undefined" ? s.hidden : (
        /** @type {any} */
        ser == null ? void 0 : ser.hidden
      ),
      data: s.data ? s.data : (
        /** @type {any} */
        ser == null ? void 0 : ser.data
      ),
      zIndex: typeof s.zIndex !== "undefined" ? s.zIndex : i
    });
  }
  /**
   * @param {number} seriesIndex
   * @param {number} dataPointIndex
   */
  toggleDataPointSelection(seriesIndex, dataPointIndex) {
    const w = this.w;
    let elPath = null;
    const parent = `.apexcharts-series[data\\:realIndex='${seriesIndex}']`;
    if (w.globals.axisCharts) {
      elPath = w.dom.Paper.findOne(
        `${parent} path[j='${dataPointIndex}'], ${parent} circle[j='${dataPointIndex}'], ${parent} rect[j='${dataPointIndex}']`
      );
    } else {
      if (typeof dataPointIndex === "undefined") {
        elPath = w.dom.Paper.findOne(`${parent} path[j='${seriesIndex}']`);
        if (w.config.chart.type === "pie" || w.config.chart.type === "polarArea" || w.config.chart.type === "donut") {
          this.ctx.pie.pieClicked(seriesIndex);
        }
      }
    }
    if (elPath) {
      const graphics = new Graphics(this.w);
      graphics.pathMouseDown(
        elPath,
        /** @type {any} */
        null
      );
    } else {
      console.warn("toggleDataPointSelection: Element not found");
      return null;
    }
    return elPath.node ? elPath.node : null;
  }
  /**
   * @param {Record<string, any>} options
   */
  forceXAxisUpdate(options2) {
    const w = this.w;
    const minmax = ["min", "max"];
    minmax.forEach((a) => {
      if (typeof options2.xaxis[a] !== "undefined") {
        w.config.xaxis[a] = options2.xaxis[a];
        w.globals.lastXAxis[a] = options2.xaxis[a];
      }
    });
    if (options2.xaxis.categories && options2.xaxis.categories.length) {
      w.config.xaxis.categories = options2.xaxis.categories;
    }
    if (w.config.xaxis.convertedCatToNumeric) {
      const defaults = new Defaults(options2);
      options2 = defaults.convertCatToNumericXaxis(options2, this.ctx);
    }
    return options2;
  }
  /**
   * @param {Record<string, any>} options
   */
  forceYAxisUpdate(options2) {
    if (options2.chart && options2.chart.stacked && options2.chart.stackType === "100%") {
      if (Array.isArray(options2.yaxis)) {
        options2.yaxis.forEach(
          (yaxe, index) => {
            options2.yaxis[index].min = 0;
            options2.yaxis[index].max = 100;
          }
        );
      } else {
        options2.yaxis.min = 0;
        options2.yaxis.max = 100;
      }
    }
    return options2;
  }
  /**
   * This function reverts the yaxis and xaxis min/max values to what it was when the chart was defined.
   * This function fixes an important bug where a user might load a new series after zooming in/out of previous series which resulted in wrong min/max
   * Also, this should never be called internally on zoom/pan - the reset should only happen when user calls the updateSeries() function externally
   * The function also accepts an object {xaxis, yaxis} which when present is set as the new xaxis/yaxis
   * @param {Record<string, any>} opts
   */
  revertDefaultAxisMinMax(opts) {
    const w = this.w;
    let xaxis = w.globals.lastXAxis;
    let yaxis = w.globals.lastYAxis;
    if (opts && opts.xaxis) {
      xaxis = opts.xaxis;
    }
    if (opts && opts.yaxis) {
      yaxis = opts.yaxis;
    }
    const _xaxis = (
      /** @type {any} */
      xaxis
    );
    w.config.xaxis.min = _xaxis.min;
    w.config.xaxis.max = _xaxis.max;
    const getLastYAxis = (index) => {
      if (typeof yaxis[index] !== "undefined") {
        const _y = (
          /** @type {any} */
          yaxis[index]
        );
        w.config.yaxis[index].min = _y.min;
        w.config.yaxis[index].max = _y.max;
      }
    };
    w.config.yaxis.map((yaxe, index) => {
      if (w.interact.zoomed) {
        getLastYAxis(index);
      } else {
        if (typeof yaxis[index] !== "undefined") {
          getLastYAxis(index);
        } else {
          if (typeof this.ctx.opts.yaxis[index] !== "undefined") {
            yaxe.min = this.ctx.opts.yaxis[index].min;
            yaxe.max = this.ctx.opts.yaxis[index].max;
          }
        }
      }
    });
  }
}
class Utils2 {
  /**
   * @param {import('./Tooltip').default} tooltipContext
   */
  constructor(tooltipContext) {
    this.w = tooltipContext.w;
    this.ttCtx = tooltipContext;
  }
  /**
   ** When hovering over series, you need to capture which series is being hovered on.
   ** This function will return both capturedseries index as well as inner index of that series
   * @memberof Utils
   * @param {{ hoverArea: any, elGrid: any, clientX: any, clientY: any, context?: any }} opts
   */
  getNearestValues({ hoverArea, elGrid, clientX, clientY }) {
    var _a, _b;
    const w = this.w;
    const seriesBound = elGrid.getBoundingClientRect();
    const hoverWidth = seriesBound.width;
    const hoverHeight = seriesBound.height;
    let xDivisor = hoverWidth / (w.globals.dataPoints - 1);
    const yDivisor = hoverHeight / w.globals.dataPoints;
    const hasBars = this.hasBars();
    if ((w.globals.comboCharts || hasBars) && !w.config.xaxis.convertedCatToNumeric) {
      xDivisor = hoverWidth / w.globals.dataPoints;
    }
    const hoverX = clientX - seriesBound.left - w.globals.barPadForNumericAxis;
    const hoverY = clientY - seriesBound.top;
    const notInRect = hoverX < 0 || hoverY < 0 || hoverX > hoverWidth || hoverY > hoverHeight;
    if (notInRect) {
      hoverArea.classList.remove("hovering-zoom");
      hoverArea.classList.remove("hovering-pan");
    } else {
      if (w.interact.zoomEnabled) {
        hoverArea.classList.remove("hovering-pan");
        hoverArea.classList.add("hovering-zoom");
      } else if (w.interact.panEnabled) {
        hoverArea.classList.remove("hovering-zoom");
        hoverArea.classList.add("hovering-pan");
      }
    }
    let j = Math.round(hoverX / xDivisor);
    const jHorz = Math.floor(hoverY / yDivisor);
    if (hasBars && !w.config.xaxis.convertedCatToNumeric) {
      j = Math.ceil(hoverX / xDivisor);
      j = j - 1;
    }
    let capturedSeries = null;
    let closest = null;
    let seriesXValArr = w.globals.seriesXvalues.map(
      (seriesXVal) => {
        return seriesXVal.filter(
          (s) => Utils$1.isNumber(s)
        );
      }
    );
    const seriesYValArr = w.globals.seriesYvalues.map(
      (seriesYVal) => {
        return seriesYVal.filter(
          (s) => Utils$1.isNumber(s)
        );
      }
    );
    if (w.axisFlags.isXNumeric) {
      const chartGridEl = this.ttCtx.getElGrid();
      if (!chartGridEl) return { hoverX, hoverY };
      const chartGridElBoundingRect = chartGridEl.getBoundingClientRect();
      const transformedHoverX = hoverX * (chartGridElBoundingRect.width / hoverWidth);
      const transformedHoverY = hoverY * (chartGridElBoundingRect.height / hoverHeight);
      closest = this.closestInMultiArray(
        transformedHoverX,
        transformedHoverY,
        seriesXValArr,
        seriesYValArr
      );
      capturedSeries = closest.index;
      j = (_a = closest.j) != null ? _a : 0;
      if (capturedSeries !== null && w.globals.hasNullValues) {
        seriesXValArr = w.globals.seriesXvalues[capturedSeries];
        closest = this.closestInArray(transformedHoverX, seriesXValArr);
        j = (_b = closest.j) != null ? _b : 0;
      }
    }
    w.interact.capturedSeriesIndex = capturedSeries === null ? -1 : capturedSeries;
    if (!j || j < 1) j = 0;
    if (w.globals.isBarHorizontal) {
      w.interact.capturedDataPointIndex = jHorz;
    } else {
      w.interact.capturedDataPointIndex = j;
    }
    return {
      capturedSeries,
      j: w.globals.isBarHorizontal ? jHorz : j,
      hoverX,
      hoverY
    };
  }
  /**
   * @param {any[]} Xarrays
   */
  getFirstActiveXArray(Xarrays) {
    const w = this.w;
    let activeIndex = 0;
    const firstActiveSeriesIndex = Xarrays.map(
      (xarr, index) => {
        return xarr.length > 0 ? index : -1;
      }
    );
    for (let a = 0; a < firstActiveSeriesIndex.length; a++) {
      if (firstActiveSeriesIndex[a] !== -1 && w.globals.collapsedSeriesIndices.indexOf(a) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(a) === -1) {
        activeIndex = firstActiveSeriesIndex[a];
        break;
      }
    }
    return activeIndex;
  }
  /**
   * @param {number} hoverX
   * @param {number} hoverY
   * @param {any[]} Xarrays
   * @param {any[]} Yarrays
   */
  closestInMultiArray(hoverX, hoverY, Xarrays, Yarrays) {
    const w = this.w;
    const isActiveSeries = (seriesIndex) => {
      return w.globals.collapsedSeriesIndices.indexOf(seriesIndex) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(seriesIndex) === -1;
    };
    const chartType = w.config.chart.type;
    const useSegmentDistance = !w.globals.comboCharts && (chartType === "line" || chartType === "area");
    let closestDist = Infinity;
    let closestSeriesIndex = null;
    let closestPointIndex = null;
    const ignoreY = w.config.tooltip.shared && w.globals.allSeriesHasEqualX && this.hasBars();
    for (let i = 0; i < Xarrays.length; i++) {
      if (!isActiveSeries(i)) {
        continue;
      }
      const xArr = Xarrays[i];
      const yArr = Yarrays[i];
      const len = Math.min(xArr.length, yArr.length);
      if (useSegmentDistance && len >= 2) {
        for (let j = 0; j < len - 1; j++) {
          const seg = this._distanceToSegment(
            hoverX,
            hoverY,
            xArr[j],
            yArr[j],
            xArr[j + 1],
            yArr[j + 1]
          );
          if (seg.dist < closestDist) {
            closestDist = seg.dist;
            closestSeriesIndex = i;
            closestPointIndex = seg.t < 0.5 ? j : j + 1;
          }
        }
        continue;
      }
      for (let j = 0; j < len; j++) {
        const xVal = xArr[j];
        const distX = hoverX - xVal;
        let dist = Math.sqrt(distX * distX);
        if (!ignoreY) {
          const yVal = yArr[j];
          const distY = hoverY - yVal;
          dist = Math.sqrt(distX * distX + distY * distY);
        }
        if (dist < closestDist) {
          closestDist = dist;
          closestSeriesIndex = i;
          closestPointIndex = j;
        }
      }
    }
    return {
      index: closestSeriesIndex,
      j: closestPointIndex
    };
  }
  /**
   * Perpendicular distance from point (px, py) to the line segment
   * (ax, ay) → (bx, by). Returns the distance plus the projection
   * parameter t (0 = at A, 1 = at B, clamped) so callers know which
   * endpoint the projection landed nearest.
   * @param {number} px
   * @param {number} py
   * @param {number} ax
   * @param {number} ay
   * @param {number} bx
   * @param {number} by
   * @returns {{ dist: number, t: number }}
   */
  _distanceToSegment(px, py, ax, ay, bx, by) {
    const dx = bx - ax;
    const dy = by - ay;
    const lenSq = dx * dx + dy * dy;
    let t = lenSq === 0 ? 0 : ((px - ax) * dx + (py - ay) * dy) / lenSq;
    if (t < 0) t = 0;
    else if (t > 1) t = 1;
    const cx = ax + t * dx;
    const cy = ay + t * dy;
    const ex = px - cx;
    const ey = py - cy;
    return { dist: Math.sqrt(ex * ex + ey * ey), t };
  }
  /**
   * @param {number} val
   * @param {any[]} arr
   */
  closestInArray(val, arr) {
    const curr = arr[0];
    let currIndex = null;
    let diff = Math.abs(val - curr);
    for (let i = 0; i < arr.length; i++) {
      const newdiff = Math.abs(val - arr[i]);
      if (newdiff < diff) {
        diff = newdiff;
        currIndex = i;
      }
    }
    return {
      j: currIndex
    };
  }
  /**
   * When there are multiple series, it is possible to have different x values for each series.
   * But it may be possible in those multiple series, that there is same x value for 2 or more
   * series.
   * @memberof Utils
   * @param {number} j - the inner index of series (series[i][j])
   * @return {boolean}
   */
  isXoverlap(j) {
    const w = this.w;
    const xSameForAllSeriesJArr = [];
    const seriesX = w.seriesData.seriesX.filter(
      (s) => typeof s[0] !== "undefined"
    );
    if (seriesX.length > 0) {
      for (let i = 0; i < seriesX.length - 1; i++) {
        if (typeof seriesX[i][j] !== "undefined" && typeof seriesX[i + 1][j] !== "undefined") {
          if (seriesX[i][j] !== seriesX[i + 1][j]) {
            xSameForAllSeriesJArr.push("unEqual");
          }
        }
      }
    }
    if (xSameForAllSeriesJArr.length === 0) {
      return true;
    }
    return false;
  }
  isInitialSeriesSameLen() {
    var _a, _b, _c;
    let sameLen = true;
    const initialSeries = (
      /** @type {any[]} */
      ((_a = this.w.globals.initialSeries) == null ? void 0 : _a.filter(
        /**
         * @param {Record<string, any>} s
         * @param {number} i
         */
        (s, i) => {
          var _a2;
          return !((_a2 = this.w.globals.collapsedSeriesIndices) == null ? void 0 : _a2.includes(i));
        }
      )) || []
    );
    for (let i = 0; i < initialSeries.length - 1; i++) {
      if (!((_b = initialSeries[i]) == null ? void 0 : _b.data) || !((_c = initialSeries[i + 1]) == null ? void 0 : _c.data)) return true;
      if (initialSeries[i].data.length !== initialSeries[i + 1].data.length) {
        sameLen = false;
        break;
      }
    }
    return sameLen;
  }
  /**
   * @param {any[]} allbars
   */
  getBarsHeight(allbars) {
    const bars = [...allbars];
    const totalHeight = bars.reduce((acc, bar) => acc + bar.getBBox().height, 0);
    return totalHeight;
  }
  /**
   * @param {number} capturedSeries
   */
  getElMarkers(capturedSeries) {
    if (typeof capturedSeries == "number") {
      return this.w.dom.baseEl.querySelectorAll(
        `.apexcharts-series[data\\:realIndex='${capturedSeries}'] .apexcharts-series-markers-wrap > *`
      );
    }
    return this.w.dom.baseEl.querySelectorAll(
      ".apexcharts-series-markers-wrap > *"
    );
  }
  getAllMarkers(filterCollapsed = false) {
    let markersWraps = (
      /** @type {any[]} */
      [
        ...this.w.dom.baseEl.querySelectorAll(".apexcharts-series-markers-wrap")
      ]
    );
    if (filterCollapsed) {
      markersWraps = markersWraps.filter((m) => {
        const realIndex = Number(m.getAttribute("data:realIndex"));
        return this.w.globals.collapsedSeriesIndices.indexOf(realIndex) === -1;
      });
    }
    markersWraps.sort((a, b) => {
      var indexA = Number(a.getAttribute("data:realIndex"));
      var indexB = Number(b.getAttribute("data:realIndex"));
      return indexB < indexA ? 1 : indexB > indexA ? -1 : 0;
    });
    const markers = [];
    markersWraps.forEach((m) => {
      markers.push(m.querySelector(".apexcharts-marker"));
    });
    return markers;
  }
  /**
   * @param {number} capturedSeries
   */
  hasMarkers(capturedSeries) {
    const markers = this.getElMarkers(capturedSeries);
    return markers.length > 0;
  }
  /**
   * @param {any} point
   * @param {number} size
   */
  getPathFromPoint(point, size) {
    const cx = Number(point.getAttribute("cx"));
    const cy = Number(point.getAttribute("cy"));
    const shape = point.getAttribute("shape");
    return new Graphics(this.w).getMarkerPath(cx, cy, shape, size);
  }
  getElBars() {
    return this.w.dom.baseEl.querySelectorAll(
      ".apexcharts-bar-series,  .apexcharts-candlestick-series, .apexcharts-boxPlot-series, .apexcharts-rangebar-series"
    );
  }
  hasBars() {
    const bars = this.getElBars();
    return bars.length > 0;
  }
  /**
   * @param {number} index
   */
  getHoverMarkerSize(index) {
    const w = this.w;
    let hoverSize = w.config.markers.hover.size;
    if (hoverSize === void 0) {
      hoverSize = w.globals.markers.size[index] + w.config.markers.hover.sizeOffset;
    }
    return hoverSize;
  }
  /**
   * @param {string} state
   */
  toggleAllTooltipSeriesGroups(state) {
    const w = this.w;
    const ttCtx = this.ttCtx;
    if (ttCtx.allTooltipSeriesGroups.length === 0) {
      ttCtx.allTooltipSeriesGroups = w.dom.baseEl.querySelectorAll(
        ".apexcharts-tooltip-series-group"
      );
    }
    const allTooltipSeriesGroups = ttCtx.allTooltipSeriesGroups;
    for (let i = 0; i < allTooltipSeriesGroups.length; i++) {
      if (state === "enable") {
        allTooltipSeriesGroups[i].classList.add("apexcharts-active");
        allTooltipSeriesGroups[i].style.display = w.config.tooltip.items.display;
      } else {
        allTooltipSeriesGroups[i].classList.remove("apexcharts-active");
        allTooltipSeriesGroups[i].style.display = "none";
      }
    }
  }
}
class Labels {
  /**
   * @param {import('./Tooltip').default} tooltipContext
   */
  constructor(tooltipContext) {
    this.w = tooltipContext.w;
    this.ttCtx = tooltipContext;
    this.tooltipUtil = new Utils2(tooltipContext);
  }
  /** @param {{ shared?: boolean, ttItems?: any, i?: number, j?: any, y1?: any, y2?: any, e?: any }} opts */
  drawSeriesTexts({ shared = true, ttItems, i = 0, j = null, y1, y2, e }) {
    const w = this.w;
    if (w.config.tooltip.custom !== void 0) {
      this.handleCustomTooltip({ i, j, y1, y2, w });
    } else {
      this.toggleActiveInactiveSeries(shared, i);
    }
    const values = this.getValuesToPrint({
      i,
      j
    });
    this.printLabels({
      i,
      j,
      values,
      ttItems,
      shared,
      e
    });
    const tooltipEl = this.ttCtx.getElTooltip();
    if (tooltipEl) {
      this.ttCtx.tooltipRect.ttWidth = tooltipEl.getBoundingClientRect().width;
      this.ttCtx.tooltipRect.ttHeight = tooltipEl.getBoundingClientRect().height;
    }
  }
  /** @param {{i: any, j: any, values: any, ttItems: any, shared: any, e: any}} opts */
  printLabels({ i, j, values, ttItems, shared, e }) {
    var _a;
    const w = this.w;
    let val;
    let goalVals = (
      /** @type {any[]} */
      []
    );
    const hasGoalValues = (gi) => {
      return w.seriesData.seriesGoals[gi] && w.seriesData.seriesGoals[gi][j] && Array.isArray(w.seriesData.seriesGoals[gi][j]);
    };
    const { xVal, zVal, xAxisTTVal } = values;
    let seriesName = "";
    let pColor = w.globals.colors[i];
    if (j !== null && w.config.plotOptions.bar.distributed) {
      pColor = w.globals.colors[j];
    }
    for (let t = 0, inverset = w.seriesData.series.length - 1; t < w.seriesData.series.length; t++, inverset--) {
      let f = this.getFormatters(i);
      seriesName = this.getSeriesName({
        fn: f.yLbTitleFormatter,
        index: i,
        seriesIndex: i,
        j
      });
      if (w.config.chart.type === "treemap") {
        seriesName = f.yLbTitleFormatter(
          String(
            /** @type {any} */
            w.config.series[i].data[j].x
          ),
          {
            series: w.seriesData.series,
            seriesIndex: i,
            dataPointIndex: j,
            w
          }
        );
      }
      const tIndex = w.config.tooltip.inverseOrder ? inverset : t;
      if (w.globals.axisCharts) {
        const getValBySeriesIndex = (index) => {
          var _a2, _b, _c, _d;
          if (w.axisFlags.isRangeData) {
            return f.yLbFormatter((_b = (_a2 = w.rangeData.seriesRangeStart) == null ? void 0 : _a2[index]) == null ? void 0 : _b[j], {
              series: w.rangeData.seriesRangeStart,
              seriesIndex: index,
              dataPointIndex: j,
              w
            }) + " - " + f.yLbFormatter((_d = (_c = w.rangeData.seriesRangeEnd) == null ? void 0 : _c[index]) == null ? void 0 : _d[j], {
              series: w.rangeData.seriesRangeEnd,
              seriesIndex: index,
              dataPointIndex: j,
              w
            });
          }
          return f.yLbFormatter(w.seriesData.series[index][j], {
            series: w.seriesData.series,
            seriesIndex: index,
            dataPointIndex: j,
            w
          });
        };
        if (shared) {
          f = this.getFormatters(tIndex);
          seriesName = this.getSeriesName({
            fn: f.yLbTitleFormatter,
            index: tIndex,
            seriesIndex: i,
            j
          });
          pColor = w.globals.colors[tIndex];
          val = getValBySeriesIndex(tIndex);
          if (hasGoalValues(tIndex)) {
            goalVals = w.seriesData.seriesGoals[tIndex][j].map(
              (goal) => {
                return {
                  attrs: goal,
                  val: f.yLbFormatter(goal.value, {
                    seriesIndex: tIndex,
                    dataPointIndex: j,
                    w
                  })
                };
              }
            );
          }
        } else {
          const targetFill = (_a = e == null ? void 0 : e.target) == null ? void 0 : _a.getAttribute("fill");
          if (targetFill) {
            if (targetFill.indexOf("url") !== -1) {
              if (targetFill.indexOf("Pattern") !== -1) {
                pColor = w.dom.baseEl.querySelector(targetFill.substr(4).slice(0, -1)).childNodes[0].getAttribute("stroke");
              }
            } else {
              pColor = targetFill;
            }
          }
          val = getValBySeriesIndex(i);
          if (hasGoalValues(i) && Array.isArray(w.seriesData.seriesGoals[i][j])) {
            goalVals = w.seriesData.seriesGoals[i][j].map(
              (goal) => {
                return {
                  attrs: goal,
                  val: f.yLbFormatter(goal.value, {
                    seriesIndex: i,
                    dataPointIndex: j,
                    w
                  })
                };
              }
            );
          }
        }
      }
      if (j === null) {
        val = f.yLbFormatter(w.seriesData.series[i], __spreadProps(__spreadValues({}, w), {
          seriesIndex: i,
          dataPointIndex: i
        }));
      }
      this.DOMHandling({
        i,
        t: tIndex,
        j,
        ttItems,
        values: {
          val,
          goalVals,
          xVal,
          xAxisTTVal,
          zVal
        },
        seriesName,
        shared,
        pColor
      });
    }
  }
  /**
   * @param {number} i
   */
  getFormatters(i) {
    const w = this.w;
    let yLbFormatter = w.formatters.yLabelFormatters[i];
    let yLbTitleFormatter;
    if (w.formatters.ttVal !== void 0) {
      if (Array.isArray(w.formatters.ttVal)) {
        yLbFormatter = /** @type {any} */
        w.formatters.ttVal[i] && /** @type {any} */
        w.formatters.ttVal[i].formatter;
        yLbTitleFormatter = /** @type {any} */
        w.formatters.ttVal[i] && /** @type {any} */
        w.formatters.ttVal[i].title && /** @type {any} */
        w.formatters.ttVal[i].title.formatter;
      } else {
        yLbFormatter = /** @type {any} */
        w.formatters.ttVal.formatter;
        if (typeof /** @type {any} */
        w.formatters.ttVal.title.formatter === "function") {
          yLbTitleFormatter = /** @type {any} */
          w.formatters.ttVal.title.formatter;
        }
      }
    } else {
      yLbTitleFormatter = w.config.tooltip.y.title.formatter;
    }
    if (typeof yLbFormatter !== "function") {
      if (w.formatters.yLabelFormatters[0]) {
        yLbFormatter = w.formatters.yLabelFormatters[0];
      } else {
        yLbFormatter = function(label) {
          return label;
        };
      }
    }
    if (typeof yLbTitleFormatter !== "function") {
      yLbTitleFormatter = function(label) {
        return label ? label + ": " : "";
      };
    }
    return {
      yLbFormatter,
      yLbTitleFormatter
    };
  }
  /** @param {{fn: any, index: any, seriesIndex: any, j: any}} opts */
  getSeriesName({ fn, index, seriesIndex, j }) {
    const w = this.w;
    return fn(String(w.seriesData.seriesNames[index]), {
      series: w.seriesData.series,
      seriesIndex,
      dataPointIndex: j,
      w
    });
  }
  /** @param {{ t?: any, j?: any, i?: any, ttItems?: any, values?: any, seriesName?: any, shared?: any, pColor?: any }} opts */
  DOMHandling({ t, j, ttItems, values, seriesName, shared, pColor }) {
    const w = this.w;
    const ttCtx = this.ttCtx;
    const { val, goalVals, xVal, xAxisTTVal, zVal } = values;
    let ttItemsChildren = null;
    ttItemsChildren = ttItems[t].children;
    if (w.config.tooltip.fillSeriesColor) {
      ttItems[t].style.backgroundColor = pColor;
      ttItemsChildren[0].style.display = "none";
    }
    if (ttCtx.showTooltipTitle) {
      if (ttCtx.tooltipTitle === null) {
        ttCtx.tooltipTitle = w.dom.baseEl.querySelector(
          ".apexcharts-tooltip-title"
        );
      }
      if (ttCtx.tooltipTitle) {
        ttCtx.tooltipTitle.innerHTML = xVal;
      }
    }
    if (ttCtx.isXAxisTooltipEnabled) {
      if (ttCtx.xaxisTooltipText) {
        ttCtx.xaxisTooltipText.innerHTML = xAxisTTVal !== "" ? xAxisTTVal : xVal;
      }
    }
    const ttYLabel = ttItems[t].querySelector(
      ".apexcharts-tooltip-text-y-label"
    );
    if (ttYLabel) {
      ttYLabel.innerHTML = seriesName ? seriesName : "";
    }
    const ttYVal = ttItems[t].querySelector(".apexcharts-tooltip-text-y-value");
    if (ttYVal) {
      ttYVal.innerHTML = typeof val !== "undefined" ? val : "";
    }
    if (ttItemsChildren[0] && ttItemsChildren[0].classList.contains("apexcharts-tooltip-marker")) {
      if (w.config.tooltip.marker.fillColors && Array.isArray(w.config.tooltip.marker.fillColors)) {
        pColor = w.config.tooltip.marker.fillColors[t];
      }
      if (w.config.tooltip.fillSeriesColor) {
        ttItemsChildren[0].style.backgroundColor = pColor;
      } else {
        ttItemsChildren[0].style.color = pColor;
      }
    }
    if (!w.config.tooltip.marker.show) {
      ttItemsChildren[0].style.display = "none";
    }
    const ttGLabel = ttItems[t].querySelector(
      ".apexcharts-tooltip-text-goals-label"
    );
    const ttGVal = ttItems[t].querySelector(
      ".apexcharts-tooltip-text-goals-value"
    );
    if (goalVals.length && w.seriesData.seriesGoals[t]) {
      const createGoalsHtml = () => {
        let gLabels = "<div>";
        let gVals = "<div>";
        goalVals.forEach((goal) => {
          gLabels += ` <div style="display: flex"><span class="apexcharts-tooltip-marker" style="background-color: ${goal.attrs.strokeColor}; height: 3px; border-radius: 0; top: 5px;"></span> ${goal.attrs.name}</div>`;
          gVals += `<div>${goal.val}</div>`;
        });
        ttGLabel.innerHTML = gLabels + `</div>`;
        ttGVal.innerHTML = gVals + `</div>`;
      };
      if (shared) {
        if (w.seriesData.seriesGoals[t][j] && Array.isArray(w.seriesData.seriesGoals[t][j])) {
          createGoalsHtml();
        } else {
          ttGLabel.innerHTML = "";
          ttGVal.innerHTML = "";
        }
      } else {
        createGoalsHtml();
      }
    } else {
      ttGLabel.innerHTML = "";
      ttGVal.innerHTML = "";
    }
    if (zVal !== null) {
      const ttZLabel = ttItems[t].querySelector(
        ".apexcharts-tooltip-text-z-label"
      );
      ttZLabel.innerHTML = w.config.tooltip.z.title;
      const ttZVal = ttItems[t].querySelector(
        ".apexcharts-tooltip-text-z-value"
      );
      ttZVal.innerHTML = typeof zVal !== "undefined" ? zVal : "";
    }
    if (shared && ttItemsChildren[0]) {
      if (w.config.tooltip.hideEmptySeries) {
        const ttItemMarker = ttItems[t].querySelector(
          ".apexcharts-tooltip-marker"
        );
        const ttItemText = ttItems[t].querySelector(".apexcharts-tooltip-text");
        if (parseFloat(val) == 0) {
          ttItemMarker.style.display = "none";
          ttItemText.style.display = "none";
        } else {
          ttItemMarker.style.display = "block";
          ttItemText.style.display = "block";
        }
      }
      if (typeof val === "undefined" || val === null || w.globals.ancillaryCollapsedSeriesIndices.indexOf(t) > -1 || w.globals.collapsedSeriesIndices.indexOf(t) > -1 || Array.isArray(ttCtx.tConfig.enabledOnSeries) && ttCtx.tConfig.enabledOnSeries.indexOf(t) === -1) {
        ttItemsChildren[0].parentNode.style.display = "none";
      } else {
        ttItemsChildren[0].parentNode.style.display = w.config.tooltip.items.display;
      }
    } else {
      if (Array.isArray(ttCtx.tConfig.enabledOnSeries) && ttCtx.tConfig.enabledOnSeries.indexOf(t) === -1) {
        ttItemsChildren[0].parentNode.style.display = "none";
      }
    }
  }
  /**
   * @param {boolean} shared
   * @param {number} i
   */
  toggleActiveInactiveSeries(shared, i) {
    const w = this.w;
    if (shared) {
      this.tooltipUtil.toggleAllTooltipSeriesGroups("enable");
    } else {
      this.tooltipUtil.toggleAllTooltipSeriesGroups("disable");
      const firstTooltipSeriesGroup = w.dom.baseEl.querySelector(
        `.apexcharts-tooltip-series-group-${i}`
      );
      if (firstTooltipSeriesGroup) {
        const ftsGroup = (
          /** @type {HTMLElement} */
          firstTooltipSeriesGroup
        );
        ftsGroup.classList.add("apexcharts-active");
        ftsGroup.style.display = w.config.tooltip.items.display;
      }
    }
  }
  /** @param {{i: any, j: any}} opts */
  getValuesToPrint({ i, j }) {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const w = this.w;
    const filteredSeriesX = w.seriesData.seriesX.map(
      (ser) => ser.length > 0 ? ser : []
    );
    let xVal = "";
    let xAxisTTVal = "";
    let zVal = null;
    let val = null;
    const customFormatterOpts = {
      series: w.seriesData.series,
      seriesIndex: i,
      dataPointIndex: j,
      w
    };
    const zFormatter = w.formatters.ttZFormatter;
    if (j === null) {
      val = w.seriesData.series[i];
    } else {
      if (w.axisFlags.isXNumeric && w.config.chart.type !== "treemap") {
        xVal = filteredSeriesX[i][j];
        if (filteredSeriesX[i].length === 0) {
          const firstActiveSeriesIndex = this.tooltipUtil.getFirstActiveXArray(filteredSeriesX);
          xVal = filteredSeriesX[firstActiveSeriesIndex][j];
        }
      } else {
        const dataFormat = new Data(this.w);
        if (dataFormat.isFormatXY()) {
          xVal = typeof /** @type {any} */
          w.config.series[i].data[j] !== "undefined" ? (
            /** @type {any} */
            w.config.series[i].data[j].x
          ) : "";
        } else {
          xVal = typeof w.labelData.labels[j] !== "undefined" ? w.labelData.labels[j] : "";
        }
      }
    }
    const bufferXVal = xVal;
    if (w.axisFlags.isXNumeric && w.config.xaxis.type === "datetime") {
      const xFormat = new Formatters(this.w);
      xVal = xFormat.xLabelFormat(
        /** @type {Function} */
        w.formatters.ttKeyFormatter,
        bufferXVal,
        bufferXVal,
        {
          i: void 0,
          dateFormatter: new DateTime(this.w).formatDate,
          w: this.w
        }
      );
    } else {
      if (w.globals.isBarHorizontal) {
        xVal = w.formatters.yLabelFormatters[0](bufferXVal, customFormatterOpts);
      } else {
        xVal = (_c = (_b = (_a = w.formatters).xLabelFormatter) == null ? void 0 : _b.call(_a, bufferXVal, customFormatterOpts)) != null ? _c : bufferXVal;
      }
    }
    if (w.config.tooltip.x.formatter !== void 0) {
      xVal = (_f = (_e = (_d = w.formatters).ttKeyFormatter) == null ? void 0 : _e.call(_d, bufferXVal, customFormatterOpts)) != null ? _f : bufferXVal;
    }
    if (w.seriesData.seriesZ.length > 0 && w.seriesData.seriesZ[i].length > 0) {
      zVal = zFormatter == null ? void 0 : zFormatter(w.seriesData.seriesZ[i][j], w);
    }
    if (typeof w.config.xaxis.tooltip.formatter === "function") {
      xAxisTTVal = (_h = (_g = w.formatters).xaxisTooltipFormatter) == null ? void 0 : _h.call(
        _g,
        bufferXVal,
        customFormatterOpts
      );
    } else {
      xAxisTTVal = xVal;
    }
    return {
      val: Array.isArray(val) ? val.join(" ") : val,
      xVal: Array.isArray(xVal) ? xVal.join(" ") : xVal,
      xAxisTTVal: Array.isArray(xAxisTTVal) ? xAxisTTVal.join(" ") : xAxisTTVal,
      zVal
    };
  }
  /** @param {{i: any, j: any, y1: any, y2: any, w: any}} opts */
  handleCustomTooltip({ i, j, y1, y2, w }) {
    const tooltipEl = this.ttCtx.getElTooltip();
    let fn = w.config.tooltip.custom;
    if (Array.isArray(fn) && fn[i]) {
      fn = fn[i];
    }
    const customTooltip = fn({
      series: w.seriesData.series,
      seriesIndex: i,
      dataPointIndex: j,
      y1,
      y2,
      w
    });
    if (tooltipEl) {
      if (typeof customTooltip === "string" || typeof customTooltip === "number") {
        tooltipEl.innerHTML = String(customTooltip);
      } else if (customTooltip instanceof Element || typeof customTooltip.nodeName === "string") {
        tooltipEl.innerHTML = "";
        tooltipEl.appendChild(customTooltip.cloneNode(true));
      }
    }
  }
}
class Position {
  /**
   * @param {import('./Tooltip').default} tooltipContext
   */
  constructor(tooltipContext) {
    this.ttCtx = tooltipContext;
    this.w = tooltipContext.w;
  }
  /**
   * This will move the crosshair (the vertical/horz line that moves along with mouse)
   * Along with this, this function also calls the xaxisMove function
   * @memberof Position
   * @param {number} cx - point's x position, wherever point's x is, you need to move crosshair
   * @param {number | null} [j]
   */
  moveXCrosshairs(cx, j = null) {
    const ttCtx = this.ttCtx;
    const w = this.w;
    const xcrosshairs = ttCtx.getElXCrosshairs();
    let x = cx - ttCtx.xcrosshairsWidth / 2;
    const tickAmount = w.labelData.labels.slice().length;
    if (j !== null) {
      x = w.layout.gridWidth / tickAmount * j;
    }
    if (xcrosshairs !== null && !w.globals.isBarHorizontal) {
      xcrosshairs.setAttribute("x", String(x));
      xcrosshairs.setAttribute("x1", String(x));
      xcrosshairs.setAttribute("x2", String(x));
      xcrosshairs.setAttribute("y2", String(w.layout.gridHeight));
      xcrosshairs.classList.add("apexcharts-active");
    }
    if (x < 0) {
      x = 0;
    }
    if (x > w.layout.gridWidth) {
      x = w.layout.gridWidth;
    }
    if (ttCtx.isXAxisTooltipEnabled) {
      let tx = x;
      if (w.config.xaxis.crosshairs.width === "tickWidth" || w.config.xaxis.crosshairs.width === "barWidth") {
        tx = x + ttCtx.xcrosshairsWidth / 2;
      }
      this.moveXAxisTooltip(tx);
    }
  }
  /**
   * This will move the crosshair (the vertical/horz line that moves along with mouse)
   * Along with this, this function also calls the xaxisMove function
   * @memberof Position
   * @param {number} cy - point's y position, wherever point's y is, you need to move crosshair
   */
  moveYCrosshairs(cy) {
    const ttCtx = this.ttCtx;
    if (ttCtx.ycrosshairs !== null) {
      Graphics.setAttrs(ttCtx.ycrosshairs, {
        y1: cy,
        y2: cy
      });
    }
    if (ttCtx.ycrosshairsHidden !== null) {
      Graphics.setAttrs(ttCtx.ycrosshairsHidden, {
        y1: cy,
        y2: cy
      });
    }
  }
  /**
   ** AxisTooltip is the small rectangle which appears on x axis with x value, when user moves
   * @memberof Position
   * @param {number} cx - point's x position, wherever point's x is, you need to move
   */
  moveXAxisTooltip(cx) {
    var _a, _b;
    const w = this.w;
    const ttCtx = this.ttCtx;
    if (ttCtx.xaxisTooltip !== null && ttCtx.xcrosshairsWidth !== 0) {
      ttCtx.xaxisTooltip.classList.add("apexcharts-active");
      const cy = ttCtx.xaxisOffY + w.config.xaxis.tooltip.offsetY + w.layout.translateY + 1 + w.config.xaxis.offsetY;
      const xaxisTTText = ttCtx.xaxisTooltip.getBoundingClientRect();
      const xaxisTTTextWidth = xaxisTTText.width;
      cx = cx - xaxisTTTextWidth / 2;
      if (!isNaN(cx)) {
        cx = cx + w.layout.translateX;
        const graphics = new Graphics(this.w);
        const textRect = graphics.getTextRects(
          (_b = (_a = ttCtx.xaxisTooltipText) == null ? void 0 : _a.innerHTML) != null ? _b : "",
          w.config.xaxis.labels.style.fontSize
        );
        if (ttCtx.xaxisTooltipText) {
          ttCtx.xaxisTooltipText.style.minWidth = textRect.width + "px";
        }
        ttCtx.xaxisTooltip.style.left = cx + "px";
        ttCtx.xaxisTooltip.style.top = cy + "px";
      }
    }
  }
  /**
   * @param {number} index
   */
  moveYAxisTooltip(index) {
    var _a, _b;
    const w = this.w;
    const ttCtx = this.ttCtx;
    if (ttCtx.yaxisTTEls === null) {
      ttCtx.yaxisTTEls = /** @type {any[]} */
      [
        ...w.dom.baseEl.querySelectorAll(".apexcharts-yaxistooltip")
      ];
    }
    const ycrosshairsHiddenRectY1 = parseInt(
      (_b = (_a = ttCtx.ycrosshairsHidden) == null ? void 0 : _a.getAttribute("y1")) != null ? _b : "0",
      10
    );
    let cy = w.layout.translateY + ycrosshairsHiddenRectY1;
    if (ttCtx.yaxisTTEls) {
      const yAxisTTRect = ttCtx.yaxisTTEls[index].getBoundingClientRect();
      const yAxisTTHeight = yAxisTTRect.height;
      let cx = w.globals.translateYAxisX[index] - 2;
      if (w.config.yaxis[index].opposite) {
        cx = cx - yAxisTTRect.width;
      }
      cy = cy - yAxisTTHeight / 2;
      if (w.globals.ignoreYAxisIndexes.indexOf(index) === -1 && cy > 0 && cy < w.layout.gridHeight) {
        ttCtx.yaxisTTEls[index].classList.add("apexcharts-active");
        ttCtx.yaxisTTEls[index].style.top = cy + "px";
        ttCtx.yaxisTTEls[index].style.left = cx + w.config.yaxis[index].tooltip.offsetX + "px";
      } else {
        ttCtx.yaxisTTEls[index].classList.remove("apexcharts-active");
      }
    }
  }
  /**
   ** moves the whole tooltip by changing x, y attrs
   * @memberof Position
   * @param {number} cx - point's x position, wherever point's x is, you need to move tooltip
   * @param {number} cy - point's y position, wherever point's y is, you need to move tooltip
   * @param {number | null} [markerSize] - point's size
   */
  moveTooltip(cx, cy, markerSize = null) {
    var _a, _b, _c, _d, _e, _f, _g;
    const w = this.w;
    const ttCtx = this.ttCtx;
    const tooltipEl = ttCtx.getElTooltip();
    const tooltipRect = ttCtx.tooltipRect;
    const pointSize = markerSize !== null ? parseFloat(String(markerSize)) : 1;
    let x = parseFloat(String(cx)) + pointSize + 5;
    let y = parseFloat(String(cy)) + pointSize / 2;
    if (x > w.layout.gridWidth / 2) {
      x = x - tooltipRect.ttWidth - pointSize - 10;
    }
    if (x > w.layout.gridWidth - tooltipRect.ttWidth - 10) {
      x = w.layout.gridWidth - tooltipRect.ttWidth;
    }
    if (x < -20) {
      x = -20;
    }
    if (w.config.tooltip.followCursor) {
      const elGrid = ttCtx.getElGrid();
      if (!elGrid) return;
      const seriesBound = elGrid.getBoundingClientRect();
      x = ttCtx.e.clientX - seriesBound.left;
      if (x > w.layout.gridWidth / 2) {
        x = x - ttCtx.tooltipRect.ttWidth;
      }
      y = ttCtx.e.clientY + w.layout.translateY - seriesBound.top;
      if (y > w.layout.gridHeight / 2) {
        y = y - ttCtx.tooltipRect.ttHeight;
      }
    } else {
      if (!w.globals.isBarHorizontal) {
        if (tooltipRect.ttHeight / 2 + y > w.layout.gridHeight) {
          y = w.layout.gridHeight - tooltipRect.ttHeight + w.layout.translateY;
        }
      }
    }
    if (!isNaN(x)) {
      x = x + w.layout.translateX;
      const a11y = (_b = (_a = w.config) == null ? void 0 : _a.chart) == null ? void 0 : _b.accessibility;
      if ((a11y == null ? void 0 : a11y.enabled) && ((_d = (_c = a11y == null ? void 0 : a11y.keyboard) == null ? void 0 : _c.navigation) == null ? void 0 : _d.enabled) && ((_g = (_f = (_e = w.dom) == null ? void 0 : _e.baseEl) == null ? void 0 : _f.querySelector) == null ? void 0 : _g.call(_f, ".apexcharts-keyboard-focused"))) {
        const cyNum = parseFloat(String(cy));
        const ttH = tooltipRect.ttHeight || 0;
        const margin = (pointSize || 1) + 12;
        const tooltipTop = y;
        const tooltipBottom = y + ttH;
        if (!isNaN(cyNum) && ttH > 0 && tooltipTop < cyNum + margin && tooltipBottom > cyNum - margin) {
          y = cyNum - ttH - margin;
          if (y < 0) {
            y = cyNum + margin;
          }
        }
      }
      if (tooltipEl) {
        tooltipEl.style.left = x + "px";
        tooltipEl.style.top = y + "px";
      }
    }
  }
  /**
   * @param {number} i
   * @param {number} j
   */
  moveMarkers(i, j) {
    var _a;
    const w = this.w;
    const ttCtx = this.ttCtx;
    if (w.globals.markers.size[i] > 0) {
      const allPoints = w.dom.baseEl.querySelectorAll(
        ` .apexcharts-series[data\\:realIndex='${i}'] .apexcharts-marker`
      );
      for (let p = 0; p < allPoints.length; p++) {
        if (parseInt((_a = allPoints[p].getAttribute("rel")) != null ? _a : "0", 10) === j) {
          ttCtx.marker.resetPointsSize();
          ttCtx.marker.enlargeCurrentPoint(j, allPoints[p]);
        }
      }
    } else {
      ttCtx.marker.resetPointsSize();
      this.moveDynamicPointOnHover(j, i);
    }
  }
  // This function is used when you need to show markers/points only on hover -
  // DIFFERENT X VALUES in multiple series
  /**
   * @param {number} j
   * @param {number} capturedSeries
   */
  moveDynamicPointOnHover(j, capturedSeries) {
    var _a, _b, _c, _d, _e;
    const w = this.w;
    const ttCtx = this.ttCtx;
    let cx = 0;
    let cy = 0;
    const graphics = new Graphics(this.w);
    const pointsArr = w.globals.pointsArray;
    const hoverSize = ttCtx.tooltipUtil.getHoverMarkerSize(capturedSeries);
    const serType = (
      /** @type {any} */
      w.config.series[capturedSeries].type
    );
    if (serType && (serType === "column" || serType === "candlestick" || serType === "boxPlot")) {
      return;
    }
    cx = (_b = (_a = pointsArr[capturedSeries]) == null ? void 0 : _a[j]) == null ? void 0 : _b[0];
    cy = ((_d = (_c = pointsArr[capturedSeries]) == null ? void 0 : _c[j]) == null ? void 0 : _d[1]) || 0;
    const point = w.dom.baseEl.querySelector(
      `.apexcharts-series[data\\:realIndex='${capturedSeries}'] .apexcharts-series-markers path`
    );
    if (point && cy < w.layout.gridHeight && cy > 0) {
      const shape = (_e = point.getAttribute("shape")) != null ? _e : "circle";
      const path = graphics.getMarkerPath(cx, cy, shape, hoverSize * 1.5);
      point.setAttribute("d", path);
    }
    this.moveXCrosshairs(cx);
    if (!ttCtx.fixedTooltip) {
      this.moveTooltip(cx, cy, hoverSize);
    }
  }
  // This function is used when you need to show markers/points only on hover -
  // SAME X VALUES in multiple series
  /**
   * @param {number} j
   */
  moveDynamicPointsOnHover(j) {
    var _a, _b;
    const ttCtx = this.ttCtx;
    const w = ttCtx.w;
    let cx = 0;
    let cy = 0;
    let activeSeries = 0;
    const pointsArr = w.globals.pointsArray;
    const series = new Series(this.w);
    const graphics = new Graphics(this.w);
    activeSeries = series.getActiveConfigSeriesIndex("asc", [
      "line",
      "area",
      "scatter",
      "bubble"
    ]);
    const hoverSize = ttCtx.tooltipUtil.getHoverMarkerSize(activeSeries);
    if ((_a = pointsArr[activeSeries]) == null ? void 0 : _a[j]) {
      cx = pointsArr[activeSeries][j][0];
      cy = pointsArr[activeSeries][j][1];
    }
    if (isNaN(cx)) {
      return;
    }
    const points = ttCtx.tooltipUtil.getAllMarkers();
    if (points.length) {
      for (let p = 0; p < w.seriesData.series.length; p++) {
        const pointArr = pointsArr[p];
        if (w.globals.comboCharts) {
          if (typeof pointArr === "undefined") {
            points.splice(p, 0, null);
          }
        }
        if (pointArr && pointArr.length) {
          let pcy = pointsArr[p][j][1];
          let pcy2;
          points[p].setAttribute("cx", cx);
          const shape = (_b = points[p].getAttribute("shape")) != null ? _b : "circle";
          if (w.config.chart.type === "rangeArea" && !w.globals.comboCharts) {
            const rangeStartIndex = j + w.seriesData.series[p].length;
            pcy2 = pointsArr[p][rangeStartIndex][1];
            const pcyDiff = Math.abs(pcy - pcy2) / 2;
            pcy = pcy - pcyDiff;
          }
          if (pcy !== null && !isNaN(pcy) && pcy < w.layout.gridHeight + hoverSize && pcy + hoverSize > 0) {
            const path = graphics.getMarkerPath(cx, pcy, shape, hoverSize);
            points[p].setAttribute("d", path);
          } else {
            points[p].setAttribute("d", "");
          }
        }
      }
    }
    this.moveXCrosshairs(cx);
    if (!ttCtx.fixedTooltip) {
      this.moveTooltip(cx, cy || w.layout.gridHeight, hoverSize);
    }
  }
  /**
   * @param {number} j
   * @param {number} capturedSeries
   */
  moveStickyTooltipOverBars(j, capturedSeries) {
    var _a, _b, _c;
    const w = this.w;
    const ttCtx = this.ttCtx;
    let barLen = w.globals.columnSeries ? (
      /** @type {any} */
      w.globals.columnSeries.length
    ) : w.seriesData.series.length;
    if (w.config.chart.stacked) {
      barLen = w.globals.barGroups.length;
    }
    let i = barLen >= 2 && barLen % 2 === 0 ? Math.floor(barLen / 2) : Math.floor(barLen / 2) + 1;
    if (w.globals.isBarHorizontal) {
      const series = new Series(this.w);
      i = series.getActiveConfigSeriesIndex("desc") + 1;
    }
    let jBar = w.dom.baseEl.querySelector(
      `.apexcharts-bar-series .apexcharts-series[rel='${i}'] path[j='${j}'], .apexcharts-candlestick-series .apexcharts-series[rel='${i}'] path[j='${j}'], .apexcharts-boxPlot-series .apexcharts-series[rel='${i}'] path[j='${j}'], .apexcharts-rangebar-series .apexcharts-series[rel='${i}'] path[j='${j}']`
    );
    if (!jBar && typeof capturedSeries === "number") {
      jBar = w.dom.baseEl.querySelector(
        `.apexcharts-bar-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}'],
        .apexcharts-candlestick-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}'],
        .apexcharts-boxPlot-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}'],
        .apexcharts-rangebar-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}']`
      );
    }
    let bcx = jBar ? parseFloat((_a = jBar.getAttribute("cx")) != null ? _a : "0") : 0;
    let bcy = jBar ? parseFloat((_b = jBar.getAttribute("cy")) != null ? _b : "0") : 0;
    const bw = jBar ? parseFloat((_c = jBar.getAttribute("barWidth")) != null ? _c : "0") : 0;
    const elGrid = ttCtx.getElGrid();
    if (!elGrid) return;
    const seriesBound = elGrid.getBoundingClientRect();
    const isBoxOrCandle = jBar && (jBar.classList.contains("apexcharts-candlestick-area") || jBar.classList.contains("apexcharts-boxPlot-area"));
    if (w.axisFlags.isXNumeric) {
      if (jBar && !isBoxOrCandle) {
        bcx = bcx - (barLen % 2 !== 0 ? bw / 2 : 0);
      }
      if (jBar && // fixes apexcharts.js#2354
      isBoxOrCandle) {
        bcx = bcx - bw / 2;
      }
    } else {
      if (!w.globals.isBarHorizontal) {
        bcx = ttCtx.xAxisTicksPositions[j - 1] + ttCtx.dataPointsDividedWidth / 2;
        if (isNaN(bcx)) {
          bcx = ttCtx.xAxisTicksPositions[j] - ttCtx.dataPointsDividedWidth / 2;
        }
      }
    }
    if (!w.globals.isBarHorizontal) {
      if (w.config.tooltip.followCursor) {
        bcy = ttCtx.e.clientY - seriesBound.top - ttCtx.tooltipRect.ttHeight / 2;
      } else {
        if (bcy + ttCtx.tooltipRect.ttHeight + 15 > w.layout.gridHeight) {
          bcy = w.layout.gridHeight;
        }
      }
    } else {
      bcy = bcy - ttCtx.tooltipRect.ttHeight;
    }
    if (!w.globals.isBarHorizontal) {
      this.moveXCrosshairs(bcx);
    }
    if (!ttCtx.fixedTooltip) {
      this.moveTooltip(bcx, bcy || w.layout.gridHeight);
    }
  }
}
class Marker {
  /**
   * @param {import('./Tooltip').default} tooltipContext
   */
  constructor(tooltipContext) {
    this.w = tooltipContext.w;
    this.ttCtx = tooltipContext;
    this.ctx = tooltipContext.ctx;
    this.tooltipPosition = new Position(tooltipContext);
  }
  drawDynamicPoints() {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const marker = new Markers(this.w, this.ctx);
    const elsSeries = (
      /** @type {any[]} */
      [
        ...w.dom.baseEl.querySelectorAll(".apexcharts-series")
      ]
    );
    if (w.config.chart.stacked) {
      elsSeries.sort((a, b) => {
        return parseFloat(a.getAttribute("data:realIndex")) - parseFloat(b.getAttribute("data:realIndex"));
      });
    }
    for (let i = 0; i < elsSeries.length; i++) {
      const pointsMain = elsSeries[i].querySelector(
        `.apexcharts-series-markers-wrap`
      );
      if (pointsMain !== null) {
        let PointClasses = `apexcharts-marker w${(Math.random() + 1).toString(36).substring(4)}`;
        if ((w.config.chart.type === "line" || w.config.chart.type === "area") && !w.globals.comboCharts && !w.config.tooltip.intersect) {
          PointClasses += " no-pointer-events";
        }
        const elPointOptions = marker.getMarkerConfig({
          cssClass: PointClasses,
          seriesIndex: Number(pointsMain.getAttribute("data:realIndex"))
          // fixes apexcharts/apexcharts.js #1427
        });
        const point = graphics.drawMarker(0, 0, elPointOptions);
        point.node.setAttribute("default-marker-size", 0);
        const elPointsG = BrowserAPIs.createElementNS(SVGNS, "g");
        elPointsG.classList.add("apexcharts-series-markers");
        elPointsG.appendChild(point.node);
        pointsMain.appendChild(elPointsG);
      }
    }
  }
  /**
   * @param {any} rel
   * @param {any} point
   * @param {number | null} [x]
   * @param {number | null} [y]
   */
  enlargeCurrentPoint(rel, point, x = null, y = null) {
    const w = this.w;
    if (w.config.chart.type !== "bubble") {
      this.newPointSize(rel, point);
    }
    let cx = point.getAttribute("cx");
    let cy = point.getAttribute("cy");
    if (x !== null && y !== null) {
      cx = x;
      cy = y;
    }
    this.tooltipPosition.moveXCrosshairs(cx);
    if (!this.fixedTooltip) {
      if (w.config.chart.type === "radar") {
        const elGrid = this.ttCtx.getElGrid();
        if (!elGrid) return;
        const seriesBound = elGrid.getBoundingClientRect();
        cx = this.ttCtx.e.clientX - seriesBound.left;
      }
      this.tooltipPosition.moveTooltip(cx, cy, w.config.markers.hover.size);
    }
  }
  /**
   * @param {number} j
   */
  enlargePoints(j) {
    var _a, _b;
    const w = this.w;
    const me = this;
    const ttCtx = this.ttCtx;
    const col = j;
    const points = w.dom.baseEl.querySelectorAll(
      ".apexcharts-series:not(.apexcharts-series-collapsed) .apexcharts-marker"
    );
    let newSize = w.config.markers.hover.size;
    for (let p = 0; p < points.length; p++) {
      const rel = points[p].getAttribute("rel");
      const index = points[p].getAttribute("index");
      if (newSize === void 0) {
        newSize = w.globals.markers.size[
          /** @type {any} */
          index
        ] + w.config.markers.hover.sizeOffset;
      }
      if (col === parseInt(rel != null ? rel : "0", 10)) {
        me.newPointSize(col, points[p]);
        const cx = (_a = points[p].getAttribute("cx")) != null ? _a : "0";
        const cy = (_b = points[p].getAttribute("cy")) != null ? _b : "0";
        me.tooltipPosition.moveXCrosshairs(parseFloat(cx));
        if (!ttCtx.fixedTooltip) {
          me.tooltipPosition.moveTooltip(
            parseFloat(cx),
            parseFloat(cy),
            newSize
          );
        }
      } else {
        me.oldPointSize(points[p]);
      }
    }
  }
  /**
   * @param {any} rel
   * @param {any} point
   */
  newPointSize(rel, point) {
    const w = this.w;
    let newSize = w.config.markers.hover.size;
    const elPoint = rel === 0 ? point.parentNode.firstChild : point.parentNode.lastChild;
    if (elPoint.getAttribute("default-marker-size") !== "0") {
      const index = parseInt(elPoint.getAttribute("index"), 10);
      if (newSize === void 0) {
        newSize = w.globals.markers.size[index] + w.config.markers.hover.sizeOffset;
      }
      if (newSize < 0) {
        newSize = 0;
      }
      const path = this.ttCtx.tooltipUtil.getPathFromPoint(point, newSize);
      point.setAttribute("d", path);
    }
  }
  /**
   * @param {any} point
   */
  oldPointSize(point) {
    const size = parseFloat(point.getAttribute("default-marker-size"));
    const path = this.ttCtx.tooltipUtil.getPathFromPoint(point, size);
    point.setAttribute("d", path);
  }
  resetPointsSize() {
    var _a;
    const w = this.w;
    const points = w.dom.baseEl.querySelectorAll(
      ".apexcharts-series:not(.apexcharts-series-collapsed) .apexcharts-marker"
    );
    for (let p = 0; p < points.length; p++) {
      const size = parseFloat(
        (_a = points[p].getAttribute("default-marker-size")) != null ? _a : "0"
      );
      if (Utils$1.isNumber(size) && size > 0) {
        const path = this.ttCtx.tooltipUtil.getPathFromPoint(points[p], size);
        points[p].setAttribute("d", path);
      } else {
        points[p].setAttribute("d", "M0,0");
      }
    }
  }
}
class Intersect {
  /**
   * @param {import('./Tooltip').default} tooltipContext
   */
  constructor(tooltipContext) {
    this.w = tooltipContext.w;
    const w = this.w;
    this.ttCtx = tooltipContext;
    this.isVerticalGroupedRangeBar = !w.globals.isBarHorizontal && w.config.chart.type === "rangeBar" && w.config.plotOptions.bar.rangeBarGroupRows;
  }
  // a helper function to get an element's attribute value
  /**
   * @param {Event} e
   * @param {string} attr
   */
  getAttr(e, attr) {
    var _a;
    return parseFloat(
      /** @type {Element} */
      (_a = e.target.getAttribute(attr)) != null ? _a : ""
    );
  }
  // handle tooltip for heatmaps and treemaps
  /** @param {{e: any, opt: any, x: any, y: any, type: any}} opts */
  handleHeatTreeTooltip({ e, opt, x, y, type }) {
    var _a, _b;
    const ttCtx = this.ttCtx;
    const w = this.w;
    if (e.target.classList.contains(`apexcharts-${type}-rect`)) {
      const i = this.getAttr(e, "i");
      const j = this.getAttr(e, "j");
      const cx = this.getAttr(e, "cx");
      const cy = this.getAttr(e, "cy");
      const width = this.getAttr(e, "width");
      const height = this.getAttr(e, "height");
      ttCtx.tooltipLabels.drawSeriesTexts({
        ttItems: opt.ttItems,
        i,
        j,
        shared: false,
        e
      });
      w.interact.capturedSeriesIndex = i;
      w.interact.capturedDataPointIndex = j;
      x = cx + ttCtx.tooltipRect.ttWidth / 2 + width;
      y = cy + ttCtx.tooltipRect.ttHeight / 2 - height / 2;
      ttCtx.tooltipPosition.moveXCrosshairs(cx + width / 2);
      if (x > w.layout.gridWidth / 2) {
        x = cx - ttCtx.tooltipRect.ttWidth / 2 + width;
      }
      if (ttCtx.w.config.tooltip.followCursor) {
        const seriesBound = w.dom.elWrap.getBoundingClientRect();
        x = ((_a = w.interact.clientX) != null ? _a : 0) - seriesBound.left - (x > w.layout.gridWidth / 2 ? ttCtx.tooltipRect.ttWidth : 0);
        y = ((_b = w.interact.clientY) != null ? _b : 0) - seriesBound.top - (y > w.layout.gridHeight / 2 ? ttCtx.tooltipRect.ttHeight : 0);
      }
    }
    return {
      x,
      y
    };
  }
  /**
   * handle tooltips for line/area/scatter charts where tooltip.intersect is true
   * when user hovers over the marker directly, this function is executed
   */
  /** @param {{e: any, opt: any, x: any, y: any}} opts */
  handleMarkerTooltip({ e, opt, x, y }) {
    const w = this.w;
    const ttCtx = this.ttCtx;
    let i;
    let j;
    if (e.target.classList.contains("apexcharts-marker")) {
      const cx = parseInt(opt.paths.getAttribute("cx"), 10);
      const cy = parseInt(opt.paths.getAttribute("cy"), 10);
      const val = parseFloat(opt.paths.getAttribute("val"));
      j = parseInt(opt.paths.getAttribute("rel"), 10);
      i = parseInt(
        opt.paths.parentNode.parentNode.parentNode.getAttribute("rel"),
        10
      ) - 1;
      if (ttCtx.intersect) {
        const el = Utils$1.findAncestor(opt.paths, "apexcharts-series");
        if (el) {
          i = parseInt(el.getAttribute("data:realIndex"), 10);
        }
      }
      ttCtx.tooltipLabels.drawSeriesTexts({
        ttItems: opt.ttItems,
        i,
        j,
        shared: ttCtx.showOnIntersect ? false : w.config.tooltip.shared,
        e
      });
      if (e.type === "mouseup") {
        ttCtx.markerClick(e, i, j);
      }
      w.interact.capturedSeriesIndex = i;
      w.interact.capturedDataPointIndex = j;
      x = cx;
      y = cy + w.layout.translateY - ttCtx.tooltipRect.ttHeight * 1.4;
      if (ttCtx.w.config.tooltip.followCursor) {
        const elGrid = ttCtx.getElGrid();
        if (!elGrid) return { x, y };
        const seriesBound = elGrid.getBoundingClientRect();
        y = ttCtx.e.clientY + w.layout.translateY - seriesBound.top;
      }
      if (val < 0) {
        y = cy;
      }
      ttCtx.marker.enlargeCurrentPoint(j, opt.paths, x, y);
    }
    return {
      x,
      y
    };
  }
  /**
   * handle tooltips for bar/column charts
   */
  /** @param {{e: any, opt: any}} opts */
  handleBarTooltip({ e, opt }) {
    const w = this.w;
    const ttCtx = this.ttCtx;
    const tooltipEl = ttCtx.getElTooltip();
    let bx = 0;
    let x = 0;
    let y = 0;
    let i = 0;
    let strokeWidth;
    const barXY = this.getBarTooltipXY({
      e,
      opt
    });
    if (barXY.j === null && barXY.barHeight === 0 && barXY.barWidth === 0) {
      return;
    }
    i = barXY.i;
    const j = barXY.j;
    w.interact.capturedSeriesIndex = i;
    w.interact.capturedDataPointIndex = j !== null ? j : w.interact.capturedDataPointIndex;
    if (w.globals.isBarHorizontal && ttCtx.tooltipUtil.hasBars() || !w.config.tooltip.shared) {
      x = barXY.x;
      y = barXY.y;
      strokeWidth = Array.isArray(w.config.stroke.width) ? w.config.stroke.width[i] : w.config.stroke.width;
      bx = x;
    } else {
      if (!w.globals.comboCharts && !w.config.tooltip.shared) {
        bx = bx / 2;
      }
    }
    if (isNaN(y)) {
      y = w.globals.svgHeight - ttCtx.tooltipRect.ttHeight;
    }
    if (x + ttCtx.tooltipRect.ttWidth > w.layout.gridWidth) {
      x = x - ttCtx.tooltipRect.ttWidth;
    } else if (x < 0) {
      x = 0;
    }
    if (ttCtx.w.config.tooltip.followCursor) {
      const elGrid = ttCtx.getElGrid();
      if (!elGrid) return;
    }
    if (ttCtx.tooltip === null) {
      ttCtx.tooltip = w.dom.baseEl.querySelector(".apexcharts-tooltip");
    }
    if (!w.config.tooltip.shared) {
      if (w.globals.comboBarCount > 0) {
        ttCtx.tooltipPosition.moveXCrosshairs(bx + strokeWidth / 2);
      } else {
        ttCtx.tooltipPosition.moveXCrosshairs(bx);
      }
    }
    if (!ttCtx.fixedTooltip && (!w.config.tooltip.shared || w.globals.isBarHorizontal && ttCtx.tooltipUtil.hasBars())) {
      y = y + w.layout.translateY - ttCtx.tooltipRect.ttHeight / 2;
      if (tooltipEl) {
        tooltipEl.style.left = x + w.layout.translateX + "px";
        tooltipEl.style.top = y + "px";
      }
    }
  }
  /** @param {{e: any, opt: any}} opts */
  getBarTooltipXY({ e, opt }) {
    const w = this.w;
    let j = null;
    const ttCtx = this.ttCtx;
    let i = 0;
    let x = 0;
    let y = 0;
    let barWidth = 0;
    let barHeight = 0;
    const cl = e.target.classList;
    if (cl.contains("apexcharts-bar-area") || cl.contains("apexcharts-candlestick-area") || cl.contains("apexcharts-boxPlot-area") || cl.contains("apexcharts-rangebar-area")) {
      const bar = e.target;
      const barRect = bar.getBoundingClientRect();
      const seriesBound = opt.elGrid.getBoundingClientRect();
      const bh = barRect.height;
      barHeight = barRect.height;
      const bw = barRect.width;
      const cx = parseInt(bar.getAttribute("cx"), 10);
      const cy = parseInt(bar.getAttribute("cy"), 10);
      barWidth = parseFloat(bar.getAttribute("barWidth"));
      const clientX = e.type === "touchmove" ? e.touches[0].clientX : e.clientX;
      j = parseInt(bar.getAttribute("j"), 10);
      i = parseInt(bar.parentNode.getAttribute("rel"), 10) - 1;
      const y1 = bar.getAttribute("data-range-y1");
      const y2 = bar.getAttribute("data-range-y2");
      if (w.globals.comboCharts) {
        i = parseInt(bar.parentNode.getAttribute("data:realIndex"), 10);
      }
      const handleXForColumns = (x2) => {
        if (w.axisFlags.isXNumeric) {
          x2 = cx - bw / 2;
        } else {
          if (this.isVerticalGroupedRangeBar) {
            x2 = cx + bw / 2;
          } else {
            x2 = cx - ttCtx.dataPointsDividedWidth + bw / 2;
          }
        }
        return x2;
      };
      const handleYForBars = () => {
        return cy - ttCtx.dataPointsDividedHeight + bh / 2 - ttCtx.tooltipRect.ttHeight / 2;
      };
      ttCtx.tooltipLabels.drawSeriesTexts({
        ttItems: opt.ttItems,
        i,
        j,
        y1: y1 ? parseInt(y1, 10) : null,
        y2: y2 ? parseInt(y2, 10) : null,
        shared: ttCtx.showOnIntersect ? false : w.config.tooltip.shared,
        e
      });
      if (w.config.tooltip.followCursor) {
        if (w.globals.isBarHorizontal) {
          x = clientX - seriesBound.left + 15;
          y = handleYForBars();
        } else {
          x = handleXForColumns(x);
          y = e.clientY - seriesBound.top - ttCtx.tooltipRect.ttHeight / 2 - 15;
        }
      } else {
        if (w.globals.isBarHorizontal) {
          x = cx;
          if (ttCtx.xyRatios && x < ttCtx.xyRatios.baseLineInvertedY) {
            x = cx - ttCtx.tooltipRect.ttWidth;
          }
          y = handleYForBars();
        } else {
          x = handleXForColumns(x);
          y = cy;
        }
      }
    }
    return {
      x,
      y,
      barHeight,
      barWidth,
      i,
      j
    };
  }
}
class AxesTooltip {
  /**
   * @param {import('./Tooltip').default} tooltipContext
   */
  constructor(tooltipContext) {
    this.w = tooltipContext.w;
    this.ttCtx = tooltipContext;
  }
  /**
   * This method adds the secondary tooltip which appears below x axis
   * @memberof Tooltip
   **/
  drawXaxisTooltip() {
    const w = this.w;
    const ttCtx = this.ttCtx;
    const isBottom = w.config.xaxis.position === "bottom";
    ttCtx.xaxisOffY = isBottom ? w.layout.gridHeight + 1 : -w.layout.xAxisHeight - w.config.xaxis.axisTicks.height + 3;
    const tooltipCssClass = isBottom ? "apexcharts-xaxistooltip apexcharts-xaxistooltip-bottom" : "apexcharts-xaxistooltip apexcharts-xaxistooltip-top";
    const renderTo = w.dom.elWrap;
    if (ttCtx.isXAxisTooltipEnabled) {
      const xaxisTooltip = w.dom.baseEl.querySelector(
        ".apexcharts-xaxistooltip"
      );
      if (xaxisTooltip === null) {
        ttCtx.xaxisTooltip = BrowserAPIs.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "div"
        );
        ttCtx.xaxisTooltip.setAttribute(
          "class",
          tooltipCssClass + " apexcharts-theme-" + w.config.tooltip.theme
        );
        renderTo.appendChild(ttCtx.xaxisTooltip);
        ttCtx.xaxisTooltipText = BrowserAPIs.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "div"
        );
        ttCtx.xaxisTooltipText.classList.add("apexcharts-xaxistooltip-text");
        ttCtx.xaxisTooltipText.style.fontFamily = w.config.xaxis.tooltip.style.fontFamily || w.config.chart.fontFamily;
        ttCtx.xaxisTooltipText.style.fontSize = w.config.xaxis.tooltip.style.fontSize;
        ttCtx.xaxisTooltip.appendChild(ttCtx.xaxisTooltipText);
      }
    }
  }
  /**
   * This method adds the secondary tooltip which appears below x axis
   * @memberof Tooltip
   **/
  drawYaxisTooltip() {
    const w = this.w;
    const ttCtx = this.ttCtx;
    for (let i = 0; i < w.config.yaxis.length; i++) {
      const isRight = w.config.yaxis[i].opposite || w.config.yaxis[i].crosshairs.opposite;
      ttCtx.yaxisOffX = isRight ? w.layout.gridWidth + 1 : 1;
      const tooltipCssClass = isRight ? `apexcharts-yaxistooltip apexcharts-yaxistooltip-${i} apexcharts-yaxistooltip-right` : `apexcharts-yaxistooltip apexcharts-yaxistooltip-${i} apexcharts-yaxistooltip-left`;
      const renderTo = w.dom.elWrap;
      const yaxisTooltip = w.dom.baseEl.querySelector(
        `.apexcharts-yaxistooltip apexcharts-yaxistooltip-${i}`
      );
      if (yaxisTooltip === null) {
        ttCtx.yaxisTooltip = BrowserAPIs.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "div"
        );
        ttCtx.yaxisTooltip.setAttribute(
          "class",
          tooltipCssClass + " apexcharts-theme-" + w.config.tooltip.theme
        );
        renderTo.appendChild(ttCtx.yaxisTooltip);
        if (i === 0) ttCtx.yaxisTooltipText = [];
        ttCtx.yaxisTooltipText[i] = BrowserAPIs.createElementNS("http://www.w3.org/1999/xhtml", "div");
        ttCtx.yaxisTooltipText[i].classList.add(
          "apexcharts-yaxistooltip-text"
        );
        ttCtx.yaxisTooltip.appendChild(
          /** @type {any} */
          ttCtx.yaxisTooltipText[i]
        );
      }
    }
  }
  /**
   * @memberof Tooltip
   **/
  setXCrosshairWidth() {
    var _a, _b;
    const w = this.w;
    const ttCtx = this.ttCtx;
    const xcrosshairs = ttCtx.getElXCrosshairs();
    ttCtx.xcrosshairsWidth = parseInt(w.config.xaxis.crosshairs.width, 10);
    if (!w.globals.comboCharts) {
      if (w.config.xaxis.crosshairs.width === "tickWidth") {
        const count = w.labelData.labels.length;
        ttCtx.xcrosshairsWidth = w.layout.gridWidth / count;
      } else if (w.config.xaxis.crosshairs.width === "barWidth") {
        const bar = w.dom.baseEl.querySelector(".apexcharts-bar-area");
        if (bar !== null) {
          const barWidth = parseFloat((_a = bar.getAttribute("barWidth")) != null ? _a : "0");
          ttCtx.xcrosshairsWidth = barWidth;
        } else {
          ttCtx.xcrosshairsWidth = 1;
        }
      }
    } else {
      const bar = w.dom.baseEl.querySelector(".apexcharts-bar-area");
      if (bar !== null && w.config.xaxis.crosshairs.width === "barWidth") {
        const barWidth = parseFloat((_b = bar.getAttribute("barWidth")) != null ? _b : "0");
        ttCtx.xcrosshairsWidth = barWidth;
      } else {
        if (w.config.xaxis.crosshairs.width === "tickWidth") {
          const count = w.labelData.labels.length;
          ttCtx.xcrosshairsWidth = w.layout.gridWidth / count;
        }
      }
    }
    if (w.globals.isBarHorizontal) {
      ttCtx.xcrosshairsWidth = 0;
    }
    if (xcrosshairs !== null && ttCtx.xcrosshairsWidth > 0) {
      xcrosshairs.setAttribute("width", String(ttCtx.xcrosshairsWidth));
    }
  }
  handleYCrosshair() {
    const w = this.w;
    const ttCtx = this.ttCtx;
    ttCtx.ycrosshairs = w.dom.baseEl.querySelector(".apexcharts-ycrosshairs");
    ttCtx.ycrosshairsHidden = w.dom.baseEl.querySelector(
      ".apexcharts-ycrosshairs-hidden"
    );
  }
  /**
   * @param {number} index
   * @param {number} clientY
   * @param {import('../../types/internal').XYRatios} xyRatios
   */
  drawYaxisTooltipText(index, clientY, xyRatios) {
    const ttCtx = this.ttCtx;
    const w = this.w;
    const gl = w.globals;
    const yAxisSeriesArr = gl.seriesYAxisMap[index];
    if (ttCtx.yaxisTooltips[index] && yAxisSeriesArr.length > 0) {
      const lbFormatter = w.formatters.yLabelFormatters[index];
      const elGrid = ttCtx.getElGrid();
      if (!elGrid) return;
      const seriesBound = elGrid.getBoundingClientRect();
      const seriesIndex = yAxisSeriesArr[0];
      let translationsIndex = 0;
      if (xyRatios.yRatio.length > 1) {
        translationsIndex = seriesIndex;
      }
      const hoverY = (clientY - seriesBound.top) * xyRatios.yRatio[translationsIndex];
      const height = gl.maxYArr[seriesIndex] - gl.minYArr[seriesIndex];
      let val = gl.minYArr[seriesIndex] + (height - hoverY);
      if (w.config.yaxis[index].reversed) {
        val = gl.maxYArr[seriesIndex] - (height - hoverY);
      }
      ttCtx.tooltipPosition.moveYCrosshairs(clientY - seriesBound.top);
      ttCtx.yaxisTooltipText[index].innerHTML = lbFormatter(val);
      ttCtx.tooltipPosition.moveYAxisTooltip(index);
    }
  }
}
class Tooltip {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   * @param {import('../../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
    this.tConfig = w.config.tooltip;
    this.tooltipUtil = new Utils2(this);
    this.tooltipLabels = new Labels(this);
    this.tooltipPosition = new Position(this);
    this.marker = new Marker(this);
    this.intersect = new Intersect(this);
    this.axesTooltip = new AxesTooltip(this);
    this.showOnIntersect = this.tConfig.intersect;
    this.showTooltipTitle = this.tConfig.x.show;
    this.fixedTooltip = this.tConfig.fixed.enabled;
    this.xaxisTooltip = null;
    this.xaxisTooltipText = null;
    this.yaxisTooltip = null;
    this.yaxisTooltipText = null;
    this.yaxisTTEls = null;
    this.xaxisOffY = 0;
    this.yaxisOffX = 0;
    this.xcrosshairsWidth = 0;
    this.ycrosshairs = null;
    this.ycrosshairsHidden = null;
    this.tooltip = null;
    this.e = null;
    this.isBarShared = !w.globals.isBarHorizontal && this.tConfig.shared;
    this.lastHoverTime = Date.now();
    this.dimensionUpdateScheduled = false;
    this.xyRatios = null;
    this.isXAxisTooltipEnabled = false;
    this.yaxisTooltips = [];
    this.allTooltipSeriesGroups = [];
    this.xAxisTicksPositions = null;
    this.dataPointsDividedHeight = 0;
    this.dataPointsDividedWidth = 0;
    this.tooltipTitle = null;
    this.legendLabels = null;
    this.ttItems = null;
    this.seriesBound = null;
    this.seriesHoverTimeout = void 0;
    this.clientX = 0;
    this.clientY = 0;
    this.barSeriesHeight = 0;
    this.tooltipRect = { x: 0, y: 0, ttWidth: 0, ttHeight: 0 };
  }
  setupDimensionCache() {
    const w = this.w;
    const tooltipEl = this.getElTooltip();
    if (!tooltipEl) return;
    this.updateDimensionCache();
    if (typeof ResizeObserver !== "undefined" && !w.globals.resizeObserver) {
      w.globals.resizeObserver = new ResizeObserver(() => {
        if (!this.dimensionUpdateScheduled) {
          this.dimensionUpdateScheduled = true;
          requestAnimationFrame(() => {
            this.updateDimensionCache();
            this.dimensionUpdateScheduled = false;
          });
        }
      });
      w.globals.resizeObserver.observe(tooltipEl);
    }
  }
  updateDimensionCache() {
    const w = this.w;
    const tooltipEl = this.getElTooltip();
    if (!tooltipEl) return;
    const rect = tooltipEl.getBoundingClientRect();
    w.globals.dimensionCache.tooltip = /** @type {any} */
    {
      width: rect.width,
      height: rect.height,
      lastUpdate: Date.now()
    };
  }
  getCachedDimensions() {
    const w = this.w;
    if (w.globals.dimensionCache.tooltip) {
      const cache2 = (
        /** @type {Record<string,any>} */
        w.globals.dimensionCache.tooltip
      );
      const age = Date.now() - cache2.lastUpdate;
      if (age < 1e3) {
        return {
          ttWidth: cache2.width,
          ttHeight: cache2.height
        };
      }
    }
    this.updateDimensionCache();
    const cache = (
      /** @type {Record<string,any>} */
      w.globals.dimensionCache.tooltip
    );
    return cache ? {
      ttWidth: cache.width,
      ttHeight: cache.height
    } : { ttWidth: 0, ttHeight: 0 };
  }
  /**
   * @param {{ w: import('../../types/internal').ChartStateW }} [ctx]
   * @returns {HTMLElement | null}
   */
  getElTooltip(ctx) {
    if (!ctx) ctx = this;
    if (!ctx.w.dom.baseEl) return null;
    return (
      /** @type {HTMLElement | null} */
      ctx.w.dom.baseEl.querySelector(".apexcharts-tooltip")
    );
  }
  getElXCrosshairs() {
    return this.w.dom.baseEl.querySelector(".apexcharts-xcrosshairs");
  }
  getElGrid() {
    return this.w.dom.baseEl.querySelector(".apexcharts-grid");
  }
  /**
   * @param {import('../../types/internal').XYRatios} xyRatios
   */
  drawTooltip(xyRatios) {
    const w = this.w;
    this.xyRatios = xyRatios;
    this.isXAxisTooltipEnabled = w.config.xaxis.tooltip.enabled && w.globals.axisCharts;
    this.yaxisTooltips = w.config.yaxis.map((y) => {
      return y.show && y.tooltip.enabled && w.globals.axisCharts ? true : false;
    });
    this.allTooltipSeriesGroups = [];
    if (!w.globals.axisCharts) {
      this.showTooltipTitle = false;
    }
    const existingTooltip = this.getElTooltip();
    if (existingTooltip == null ? void 0 : existingTooltip.parentNode) {
      existingTooltip.parentNode.removeChild(existingTooltip);
    }
    this.tooltipTitle = null;
    const tooltipEl = BrowserAPIs.createElementNS(
      "http://www.w3.org/1999/xhtml",
      "div"
    );
    tooltipEl.classList.add("apexcharts-tooltip");
    if (w.config.tooltip.cssClass) {
      tooltipEl.classList.add(w.config.tooltip.cssClass);
    }
    tooltipEl.classList.add(`apexcharts-theme-${this.tConfig.theme || "light"}`);
    if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
      tooltipEl.setAttribute("role", "tooltip");
      tooltipEl.setAttribute("aria-live", "polite");
      tooltipEl.setAttribute("aria-atomic", "true");
      tooltipEl.setAttribute("aria-hidden", "true");
    }
    w.dom.elWrap.appendChild(tooltipEl);
    if (w.globals.axisCharts) {
      this.axesTooltip.drawXaxisTooltip();
      this.axesTooltip.drawYaxisTooltip();
      this.axesTooltip.setXCrosshairWidth();
      this.axesTooltip.handleYCrosshair();
      const xAxis = new XAxis(this.w, this.ctx, void 0);
      this.xAxisTicksPositions = xAxis.getXAxisTicksPositions();
    }
    if ((w.globals.comboCharts || this.tConfig.intersect || w.config.chart.type === "rangeBar") && !this.tConfig.shared) {
      this.showOnIntersect = true;
    }
    if (w.config.markers.size === 0 || w.globals.markers.largestSize === 0) {
      this.marker.drawDynamicPoints();
    }
    if (w.globals.collapsedSeries.length === w.seriesData.series.length) return;
    this.dataPointsDividedHeight = w.layout.gridHeight / w.globals.dataPoints;
    this.dataPointsDividedWidth = w.layout.gridWidth / w.globals.dataPoints;
    if (this.showTooltipTitle) {
      this.tooltipTitle = BrowserAPIs.createElementNS(
        "http://www.w3.org/1999/xhtml",
        "div"
      );
      this.tooltipTitle.classList.add("apexcharts-tooltip-title");
      this.tooltipTitle.style.fontFamily = this.tConfig.style.fontFamily || w.config.chart.fontFamily;
      this.tooltipTitle.style.fontSize = this.tConfig.style.fontSize;
      tooltipEl.appendChild(this.tooltipTitle);
    }
    let ttItemsCnt = w.seriesData.series.length;
    if ((w.globals.xyCharts || w.globals.comboCharts) && this.tConfig.shared) {
      if (!this.showOnIntersect) {
        ttItemsCnt = w.seriesData.series.length;
      } else {
        ttItemsCnt = 1;
      }
    }
    this.legendLabels = w.dom.baseEl.querySelectorAll(".apexcharts-legend-text");
    this.ttItems = this.createTTElements(ttItemsCnt);
    this.addSVGEvents();
    this.setupDimensionCache();
  }
  /**
   * @param {number} ttItemsCnt
   */
  createTTElements(ttItemsCnt) {
    const w = this.w;
    const ttItems = [];
    const tooltipEl = this.getElTooltip();
    if (!tooltipEl) return ttItems;
    for (let i = 0; i < ttItemsCnt; i++) {
      const gTxt = BrowserAPIs.createElementNS(
        "http://www.w3.org/1999/xhtml",
        "div"
      );
      gTxt.classList.add(
        "apexcharts-tooltip-series-group",
        `apexcharts-tooltip-series-group-${i}`
      );
      gTxt.style.order = String(
        w.config.tooltip.inverseOrder ? ttItemsCnt - i : i + 1
      );
      const point = BrowserAPIs.createElementNS(
        "http://www.w3.org/1999/xhtml",
        "span"
      );
      point.classList.add("apexcharts-tooltip-marker");
      if (w.config.tooltip.fillSeriesColor) {
        point.style.backgroundColor = w.globals.colors[i];
      } else {
        point.style.color = w.globals.colors[i];
      }
      const mShape = w.config.markers.shape;
      let shape = mShape;
      if (Array.isArray(mShape)) {
        shape = mShape[i];
      }
      point.setAttribute("shape", shape);
      gTxt.appendChild(point);
      const gYZ = BrowserAPIs.createElementNS(
        "http://www.w3.org/1999/xhtml",
        "div"
      );
      gYZ.classList.add("apexcharts-tooltip-text");
      gYZ.style.fontFamily = this.tConfig.style.fontFamily || w.config.chart.fontFamily;
      gYZ.style.fontSize = this.tConfig.style.fontSize;
      ["y", "goals", "z"].forEach((g) => {
        const gValText = BrowserAPIs.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "div"
        );
        gValText.classList.add(`apexcharts-tooltip-${g}-group`);
        const txtLabel = BrowserAPIs.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "span"
        );
        txtLabel.classList.add(`apexcharts-tooltip-text-${g}-label`);
        gValText.appendChild(txtLabel);
        const txtValue = BrowserAPIs.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "span"
        );
        txtValue.classList.add(`apexcharts-tooltip-text-${g}-value`);
        gValText.appendChild(txtValue);
        gYZ.appendChild(gValText);
      });
      gTxt.appendChild(gYZ);
      tooltipEl.appendChild(gTxt);
      ttItems.push(gTxt);
    }
    return ttItems;
  }
  addSVGEvents() {
    const w = this.w;
    const type = w.config.chart.type;
    const tooltipEl = this.getElTooltip();
    if (!tooltipEl) return;
    const commonBar = !!(type === "bar" || type === "candlestick" || type === "boxPlot" || type === "rangeBar");
    const chartWithmarkers = type === "area" || type === "line" || type === "scatter" || type === "bubble" || type === "radar";
    const hoverArea = w.dom.Paper.node;
    const elGrid = this.getElGrid();
    if (elGrid) {
      this.seriesBound = elGrid.getBoundingClientRect();
    }
    const tooltipY = [];
    const tooltipX = [];
    const seriesHoverParams = {
      hoverArea,
      elGrid,
      tooltipEl,
      tooltipY,
      tooltipX,
      ttItems: this.ttItems
    };
    let points;
    if (w.globals.axisCharts) {
      if (chartWithmarkers) {
        points = w.dom.baseEl.querySelectorAll(
          ".apexcharts-series[data\\:longestSeries='true'] .apexcharts-marker"
        );
      } else if (commonBar) {
        points = w.dom.baseEl.querySelectorAll(
          ".apexcharts-series .apexcharts-bar-area, .apexcharts-series .apexcharts-candlestick-area, .apexcharts-series .apexcharts-boxPlot-area, .apexcharts-series .apexcharts-rangebar-area"
        );
      } else if (type === "heatmap" || type === "treemap") {
        points = w.dom.baseEl.querySelectorAll(
          ".apexcharts-series .apexcharts-heatmap, .apexcharts-series .apexcharts-treemap"
        );
      }
      if (points && points.length) {
        for (let p = 0; p < points.length; p++) {
          tooltipY.push(points[p].getAttribute("cy"));
          tooltipX.push(points[p].getAttribute("cx"));
        }
      }
    }
    const validSharedChartTypes = w.globals.xyCharts && !this.showOnIntersect || w.globals.comboCharts && !this.showOnIntersect || commonBar && this.tooltipUtil.hasBars() && this.tConfig.shared;
    if (validSharedChartTypes) {
      this.addPathsEventListeners([hoverArea], seriesHoverParams);
    } else if (commonBar && !w.globals.comboCharts || chartWithmarkers && this.showOnIntersect) {
      this.addDatapointEventsListeners(seriesHoverParams);
    } else if (!w.globals.axisCharts || type === "heatmap" || type === "treemap") {
      const seriesAll = w.dom.baseEl.querySelectorAll(".apexcharts-series");
      this.addPathsEventListeners(seriesAll, seriesHoverParams);
    }
    if (this.showOnIntersect) {
      const lineAreaPoints = w.dom.baseEl.querySelectorAll(
        ".apexcharts-line-series .apexcharts-marker, .apexcharts-area-series .apexcharts-marker"
      );
      if (lineAreaPoints.length > 0) {
        this.addPathsEventListeners(lineAreaPoints, seriesHoverParams);
      }
      if (this.tooltipUtil.hasBars() && !this.tConfig.shared) {
        this.addDatapointEventsListeners(seriesHoverParams);
      }
    }
  }
  drawFixedTooltipRect() {
    const w = this.w;
    const tooltipEl = this.getElTooltip();
    if (!tooltipEl) return { x: 0, y: 0, ttWidth: 0, ttHeight: 0 };
    const tooltipRect = tooltipEl.getBoundingClientRect();
    const ttWidth = tooltipRect.width + 10;
    const ttHeight = tooltipRect.height + 10;
    let x = this.tConfig.fixed.offsetX;
    let y = this.tConfig.fixed.offsetY;
    const fixed = this.tConfig.fixed.position.toLowerCase();
    if (fixed.indexOf("right") > -1) {
      x = x + w.globals.svgWidth - ttWidth + 10;
    }
    if (fixed.indexOf("bottom") > -1) {
      y = y + w.globals.svgHeight - ttHeight - 10;
    }
    tooltipEl.style.left = x + "px";
    tooltipEl.style.top = y + "px";
    return {
      x,
      y,
      ttWidth,
      ttHeight
    };
  }
  /**
   * @param {Record<string, any>} seriesHoverParams
   */
  addDatapointEventsListeners(seriesHoverParams) {
    const w = this.w;
    const points = w.dom.baseEl.querySelectorAll(
      ".apexcharts-series-markers .apexcharts-marker, .apexcharts-bar-area, .apexcharts-candlestick-area, .apexcharts-boxPlot-area, .apexcharts-rangebar-area"
    );
    this.addPathsEventListeners(points, seriesHoverParams);
  }
  /**
   * @param {any} paths
   * @param {Record<string, any>} opts
   */
  addPathsEventListeners(paths, opts) {
    const self = this;
    for (let p = 0; p < paths.length; p++) {
      const extendedOpts = {
        paths: paths[p],
        tooltipEl: opts.tooltipEl,
        tooltipY: opts.tooltipY,
        tooltipX: opts.tooltipX,
        elGrid: opts.elGrid,
        hoverArea: opts.hoverArea,
        ttItems: opts.ttItems
      };
      const events = [
        "mousemove",
        "mouseup",
        "touchmove",
        "mouseout",
        "touchend"
      ];
      events.map((ev) => {
        return paths[p].addEventListener(
          ev,
          self.onSeriesHover.bind(self, extendedOpts),
          { capture: false, passive: true }
        );
      });
    }
  }
  /*
   ** Check to see if the tooltips should be updated based on a mouse / touch event
   * @param {Record<string, any>} opt
   * @param {Event} e
   */
  /** @param {Record<string, any>} opt @param {any} e */
  onSeriesHover(opt, e) {
    const targetDelay = 20;
    const timeSinceLastUpdate = Date.now() - this.lastHoverTime;
    if (timeSinceLastUpdate >= targetDelay) {
      this.seriesHover(opt, e);
    } else {
      clearTimeout(this.seriesHoverTimeout);
      this.seriesHoverTimeout = setTimeout(() => {
        this.seriesHover(opt, e);
      }, targetDelay - timeSinceLastUpdate);
    }
  }
  /*
   ** The actual series hover function
   * @param {Record<string, any>} opt
   * @param {Event} e
   */
  /** @param {Record<string, any>} opt @param {any} e */
  seriesHover(opt, e) {
    this.lastHoverTime = Date.now();
    let chartGroups = [];
    const w = this.w;
    if (w.config.chart.group) {
      chartGroups = this.ctx.getGroupedCharts();
    }
    if (w.globals.axisCharts && (w.globals.minX === -Infinity && w.globals.maxX === Infinity || w.globals.dataPoints === 0)) {
      return;
    }
    if (chartGroups.length) {
      chartGroups.forEach((ch) => {
        const tooltipEl = this.getElTooltip(ch);
        const newOpts = {
          paths: opt.paths,
          tooltipEl,
          tooltipY: opt.tooltipY,
          tooltipX: opt.tooltipX,
          elGrid: opt.elGrid,
          hoverArea: opt.hoverArea,
          ttItems: ch.w.globals.tooltip.ttItems
        };
        if (ch.w.globals.minX === this.w.globals.minX && ch.w.globals.maxX === this.w.globals.maxX) {
          ch.w.globals.tooltip.seriesHoverByContext({
            chartCtx: ch,
            ttCtx: ch.w.globals.tooltip,
            opt: newOpts,
            e
          });
        }
      });
    } else {
      this.seriesHoverByContext({
        chartCtx: this.ctx,
        ttCtx: this.w.globals.tooltip,
        opt,
        e
      });
    }
  }
  /** @param {{chartCtx: any, ttCtx: any, opt: any, e: any}} opts */
  seriesHoverByContext({ chartCtx, ttCtx, opt, e }) {
    const w = chartCtx.w;
    const tooltipEl = this.getElTooltip(chartCtx);
    if (!tooltipEl) return;
    const cachedDims = ttCtx.getCachedDimensions();
    ttCtx.tooltipRect = {
      x: 0,
      y: 0,
      ttWidth: cachedDims.ttWidth,
      ttHeight: cachedDims.ttHeight
    };
    ttCtx.e = e;
    if (ttCtx.tooltipUtil.hasBars() && !w.globals.comboCharts && !ttCtx.isBarShared) {
      if (this.tConfig.onDatasetHover.highlightDataSeries) {
        const series = new Series(chartCtx.w);
        series.toggleSeriesOnHover(e, e.target.parentNode);
      }
    }
    if (w.globals.axisCharts) {
      ttCtx.axisChartsTooltips({
        e,
        opt,
        tooltipRect: ttCtx.tooltipRect
      });
    } else {
      ttCtx.nonAxisChartsTooltips({
        e,
        opt,
        tooltipRect: ttCtx.tooltipRect
      });
    }
    if (ttCtx.fixedTooltip) {
      ttCtx.drawFixedTooltipRect();
    }
  }
  // tooltip handling for line/area/bar/columns/scatter
  /** @param {{e: any, opt: any}} opts */
  axisChartsTooltips({ e, opt }) {
    var _a;
    const w = this.w;
    let x, y;
    const seriesBound = opt.elGrid.getBoundingClientRect();
    const clientX = e.type === "touchmove" ? e.touches[0].clientX : e.clientX;
    const clientY = e.type === "touchmove" ? e.touches[0].clientY : e.clientY;
    this.clientY = clientY;
    this.clientX = clientX;
    w.interact.capturedSeriesIndex = -1;
    w.interact.capturedDataPointIndex = -1;
    if (clientY < seriesBound.top || clientY > seriesBound.top + seriesBound.height) {
      this.handleMouseOut(opt);
      return;
    }
    if (Array.isArray(this.tConfig.enabledOnSeries) && !w.config.tooltip.shared) {
      const index = parseInt(opt.paths.getAttribute("index"), 10);
      if (this.tConfig.enabledOnSeries.indexOf(index) < 0) {
        this.handleMouseOut(opt);
        return;
      }
    }
    const tooltipEl = this.getElTooltip();
    if (!tooltipEl) return;
    const xcrosshairs = this.getElXCrosshairs();
    let syncedCharts = [];
    if (w.config.chart.group) {
      syncedCharts = this.ctx.getSyncedCharts();
    }
    const isStickyTooltip = w.globals.xyCharts || w.config.chart.type === "bar" && !w.globals.isBarHorizontal && this.tooltipUtil.hasBars() && this.tConfig.shared || w.globals.comboCharts && this.tooltipUtil.hasBars();
    if (e.type === "mousemove" || e.type === "touchmove" || e.type === "mouseup") {
      if (w.globals.collapsedSeries.length + w.globals.ancillaryCollapsedSeries.length === w.seriesData.series.length) {
        return;
      }
      if (xcrosshairs !== null) {
        xcrosshairs.classList.add("apexcharts-active");
      }
      const hasYAxisTooltip = (_a = this.yaxisTooltips) == null ? void 0 : _a.filter(
        (b) => {
          return b === true;
        }
      );
      const _yc = (
        /** @type {any} */
        this.ycrosshairs
      );
      if (_yc !== null && (hasYAxisTooltip == null ? void 0 : hasYAxisTooltip.length)) {
        _yc.classList.add("apexcharts-active");
      }
      if (isStickyTooltip && !this.showOnIntersect || syncedCharts.length > 1) {
        this.handleStickyTooltip(e, clientX, clientY, opt);
      } else {
        if (w.config.chart.type === "heatmap" || w.config.chart.type === "treemap") {
          const markerXY = this.intersect.handleHeatTreeTooltip({
            e,
            opt,
            x,
            y,
            type: w.config.chart.type
          });
          x = markerXY.x;
          y = markerXY.y;
          tooltipEl.style.left = x + "px";
          tooltipEl.style.top = y + "px";
        } else {
          if (this.tooltipUtil.hasBars()) {
            this.intersect.handleBarTooltip({
              e,
              opt
            });
          }
          if (this.tooltipUtil.hasMarkers(0)) {
            this.intersect.handleMarkerTooltip({
              e,
              opt,
              x,
              y
            });
          }
        }
      }
      if (this.yaxisTooltips && this.yaxisTooltips.length) {
        for (let yt = 0; yt < w.config.yaxis.length; yt++) {
          this.axesTooltip.drawYaxisTooltipText(
            yt,
            clientY,
            /** @type {import('../../types/internal').XYRatios} */
            this.xyRatios
          );
        }
      }
      w.dom.baseEl.classList.add("apexcharts-tooltip-active");
      opt.tooltipEl.classList.add("apexcharts-active");
      if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
        opt.tooltipEl.removeAttribute("aria-hidden");
      }
    } else if (e.type === "mouseout" || e.type === "touchend") {
      this.handleMouseOut(opt);
    }
  }
  // tooltip handling for pie/donuts
  /** @param {{e: any, opt: any, tooltipRect: any}} opts */
  nonAxisChartsTooltips({ e, opt, tooltipRect }) {
    var _a, _b, _c, _d;
    const w = this.w;
    const rel = opt.paths.getAttribute("rel");
    const tooltipEl = this.getElTooltip();
    if (!tooltipEl) return;
    const seriesBound = w.dom.elWrap.getBoundingClientRect();
    if (e.type === "mousemove" || e.type === "touchmove") {
      w.dom.baseEl.classList.add("apexcharts-tooltip-active");
      tooltipEl.classList.add("apexcharts-active");
      if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
        tooltipEl.removeAttribute("aria-hidden");
      }
      this.tooltipLabels.drawSeriesTexts({
        ttItems: opt.ttItems,
        i: parseInt(rel, 10) - 1,
        shared: false
      });
      let x, y;
      const arcPath = opt.paths.querySelector("path[data\\:cx]") || opt.paths;
      if (w.config.tooltip.intersect && arcPath.hasAttribute("data:cx") && arcPath.hasAttribute("data:cy")) {
        const svgBound = w.dom.Paper.node.getBoundingClientRect();
        x = svgBound.left - seriesBound.left + parseFloat(arcPath.getAttribute("data:cx")) - tooltipRect.ttWidth / 2;
        y = svgBound.top - seriesBound.top + parseFloat(arcPath.getAttribute("data:cy")) - tooltipRect.ttHeight - 10;
      } else {
        x = ((_a = w.interact.clientX) != null ? _a : 0) - seriesBound.left - tooltipRect.ttWidth / 2;
        y = ((_b = w.interact.clientY) != null ? _b : 0) - seriesBound.top - tooltipRect.ttHeight - 10;
      }
      tooltipEl.style.left = x + "px";
      tooltipEl.style.top = y + "px";
      if (w.config.legend.tooltipHoverFormatter) {
        const legendFormatter = w.config.legend.tooltipHoverFormatter;
        const i = rel - 1;
        const legendEl = (
          /** @type {HTMLElement | undefined} */
          (_c = this.legendLabels) == null ? void 0 : _c[i]
        );
        if (!legendEl) return;
        const legendName = legendEl.getAttribute("data:default-text");
        const text = legendFormatter(legendName, {
          seriesIndex: i,
          dataPointIndex: i,
          w
        });
        legendEl.innerHTML = text;
      }
    } else if (e.type === "mouseout" || e.type === "touchend") {
      tooltipEl.classList.remove("apexcharts-active");
      w.dom.baseEl.classList.remove("apexcharts-tooltip-active");
      if (w.config.legend.tooltipHoverFormatter) {
        (_d = this.legendLabels) == null ? void 0 : _d.forEach((l) => {
          const defaultText = l.getAttribute("data:default-text");
          l.innerHTML = decodeURIComponent(
            defaultText != null ? defaultText : ""
          );
        });
      }
    }
  }
  /**
   * @param {Event} e
   * @param {number} clientX
   * @param {number} clientY
   * @param {Record<string, any>} opt
   */
  handleStickyTooltip(e, clientX, clientY, opt) {
    const w = this.w;
    const capj = this.tooltipUtil.getNearestValues({
      context: this,
      hoverArea: opt.hoverArea,
      elGrid: opt.elGrid,
      clientX,
      clientY
    });
    const j = capj.j;
    let capturedSeries = capj.capturedSeries;
    if (capturedSeries !== null && w.globals.collapsedSeriesIndices.includes(capturedSeries != null ? capturedSeries : -1))
      capturedSeries = null;
    const bounds = opt.elGrid.getBoundingClientRect();
    if (capj.hoverX < 0 || capj.hoverX > bounds.width) {
      this.handleMouseOut(opt);
      return;
    }
    if (capturedSeries !== null) {
      this.handleStickyCapturedSeries(e, capturedSeries != null ? capturedSeries : -1, opt, j != null ? j : 0);
    } else {
      if (this.tooltipUtil.isXoverlap(j != null ? j : 0) || w.globals.isBarHorizontal) {
        const firstVisibleSeries = w.seriesData.series.findIndex(
          /**
           * @param {any} s
           * @param {number} i
           */
          (s, i) => !w.globals.collapsedSeriesIndices.includes(i)
        );
        this.create(e, this, firstVisibleSeries, j != null ? j : 0, opt.ttItems);
      }
    }
  }
  /**
   * @param {Event} e
   * @param {number} capturedSeries
   * @param {Record<string, any>} opt
   * @param {number} j
   */
  handleStickyCapturedSeries(e, capturedSeries, opt, j) {
    const w = this.w;
    if (!this.tConfig.shared) {
      const ignoreNull = w.seriesData.series[capturedSeries][j] === null;
      if (ignoreNull) {
        this.handleMouseOut(opt);
        return;
      }
    }
    if (typeof w.seriesData.series[capturedSeries][j] !== "undefined") {
      if (this.tConfig.shared && this.tooltipUtil.isXoverlap(j) && this.tooltipUtil.isInitialSeriesSameLen()) {
        this.create(e, this, capturedSeries, j, opt.ttItems);
      } else {
        this.create(e, this, capturedSeries, j, opt.ttItems, false);
      }
    } else {
      if (this.tooltipUtil.isXoverlap(j)) {
        const firstVisibleSeries = w.seriesData.series.findIndex(
          /**
           * @param {any} s
           * @param {number} i
           */
          (s, i) => !w.globals.collapsedSeriesIndices.includes(i)
        );
        this.create(e, this, firstVisibleSeries, j, opt.ttItems);
      }
    }
  }
  deactivateHoverFilter() {
    const w = this.w;
    const graphics = new Graphics(this.w, this.ctx);
    const allPaths = w.dom.Paper.find(`.apexcharts-bar-area`);
    for (let b = 0; b < allPaths.length; b++) {
      graphics.pathMouseLeave(
        /** @type {any} */
        allPaths[b],
        /** @type {any} */
        void 0
      );
    }
  }
  /**
   * @param {Record<string, any>} opt
   */
  handleMouseOut(opt) {
    var _a, _b;
    const w = this.w;
    const xcrosshairs = this.getElXCrosshairs();
    w.dom.baseEl.classList.remove("apexcharts-tooltip-active");
    opt.tooltipEl.classList.remove("apexcharts-active");
    if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
      opt.tooltipEl.setAttribute("aria-hidden", "true");
    }
    this.deactivateHoverFilter();
    if (w.config.chart.type !== "bubble") {
      this.marker.resetPointsSize();
    }
    if (xcrosshairs !== null) {
      xcrosshairs.classList.remove("apexcharts-active");
    }
    const _yc2 = (
      /** @type {any} */
      this.ycrosshairs
    );
    if (_yc2 !== null) {
      _yc2.classList.remove("apexcharts-active");
    }
    if (this.isXAxisTooltipEnabled) {
      (_a = this.xaxisTooltip) == null ? void 0 : _a.classList.remove("apexcharts-active");
    }
    if (this.yaxisTooltips && this.yaxisTooltips.length) {
      if (this.yaxisTTEls === null) {
        this.yaxisTTEls = /** @type {HTMLElement[]} */
        [
          ...w.dom.baseEl.querySelectorAll(".apexcharts-yaxistooltip")
        ];
      }
      for (let i = 0; i < this.yaxisTTEls.length; i++) {
        this.yaxisTTEls[i].classList.remove("apexcharts-active");
      }
    }
    if (w.config.legend.tooltipHoverFormatter) {
      (_b = this.legendLabels) == null ? void 0 : _b.forEach((l) => {
        const defaultText = l.getAttribute("data:default-text");
        l.innerHTML = decodeURIComponent(
          defaultText != null ? defaultText : ""
        );
      });
    }
  }
  /**
   * @param {Event} e
   * @param {number} seriesIndex
   * @param {number} dataPointIndex
   */
  markerClick(e, seriesIndex, dataPointIndex) {
    const w = this.w;
    if (typeof w.config.chart.events.markerClick === "function") {
      w.config.chart.events.markerClick(e, this.ctx, {
        seriesIndex,
        dataPointIndex,
        w
      });
    }
    this.ctx.events.fireEvent("markerClick", [
      e,
      this.ctx,
      { seriesIndex, dataPointIndex, w }
    ]);
  }
  /**
   * @param {Event} e
   * @param {any} context
   * @param {number} capturedSeries
   * @param {number} j
   * @param {any} ttItems
   * @param {boolean | null} shared
   */
  create(e, context, capturedSeries, j, ttItems, shared = null) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
    const w = this.w;
    const ttCtx = context;
    if (e.type === "mouseup") {
      this.markerClick(e, capturedSeries, j);
    }
    if (shared === null) shared = this.tConfig.shared;
    const hasMarkers = this.tooltipUtil.hasMarkers(capturedSeries);
    const bars = this.tooltipUtil.getElBars();
    const handlePoints = () => {
      if (w.globals.markers.largestSize > 0) {
        ttCtx.marker.enlargePoints(j);
      } else {
        ttCtx.tooltipPosition.moveDynamicPointsOnHover(j);
      }
    };
    if (w.config.legend.tooltipHoverFormatter) {
      const legendFormatter = w.config.legend.tooltipHoverFormatter;
      const els = (
        /** @type {HTMLElement[]} */
        Array.from((_a = this.legendLabels) != null ? _a : [])
      );
      els.forEach((l) => {
        const legendName = l.getAttribute("data:default-text");
        l.innerHTML = decodeURIComponent(legendName != null ? legendName : "");
      });
      for (let i = 0; i < els.length; i++) {
        const l = els[i];
        const lsIndex = parseInt((_b = l.getAttribute("i")) != null ? _b : "", 10);
        const legendName = decodeURIComponent(
          (_c = l.getAttribute("data:default-text")) != null ? _c : ""
        );
        const text = legendFormatter(legendName, {
          seriesIndex: shared ? lsIndex : capturedSeries,
          dataPointIndex: j,
          w
        });
        if (!shared) {
          l.innerHTML = lsIndex === capturedSeries ? text : legendName;
          if (capturedSeries === lsIndex) {
            break;
          }
        } else {
          l.innerHTML = w.globals.collapsedSeriesIndices.indexOf(lsIndex) < 0 ? text : legendName;
        }
      }
    }
    const _rangeData = (
      /** @type {any} */
      w.rangeData
    );
    const commonSeriesTextsParams = __spreadValues(__spreadValues({
      ttItems,
      i: capturedSeries,
      j
    }, ((_g = (_f = (_e = (_d = _rangeData.seriesRange) == null ? void 0 : _d[capturedSeries]) == null ? void 0 : _e[j]) == null ? void 0 : _f.y[0]) == null ? void 0 : _g.y1) !== void 0 && {
      y1: (_k = (_j = (_i = (_h = _rangeData.seriesRange) == null ? void 0 : _h[capturedSeries]) == null ? void 0 : _i[j]) == null ? void 0 : _j.y[0]) == null ? void 0 : _k.y1
    }), ((_o = (_n = (_m = (_l = _rangeData.seriesRange) == null ? void 0 : _l[capturedSeries]) == null ? void 0 : _m[j]) == null ? void 0 : _n.y[0]) == null ? void 0 : _o.y2) !== void 0 && {
      y2: (_s = (_r = (_q = (_p = _rangeData.seriesRange) == null ? void 0 : _p[capturedSeries]) == null ? void 0 : _q[j]) == null ? void 0 : _r.y[0]) == null ? void 0 : _s.y2
    });
    if (shared) {
      ttCtx.tooltipLabels.drawSeriesTexts(__spreadProps(__spreadValues({}, commonSeriesTextsParams), {
        shared: this.showOnIntersect ? false : this.tConfig.shared
      }));
      if (hasMarkers) {
        handlePoints();
      } else if (this.tooltipUtil.hasBars()) {
        this.barSeriesHeight = this.tooltipUtil.getBarsHeight(
          /** @type {any[]} */
          [...bars]
        );
        if (this.barSeriesHeight > 0) {
          const graphics = new Graphics(this.w, this.ctx);
          const paths = w.dom.Paper.find(`.apexcharts-bar-area[j='${j}']`);
          this.deactivateHoverFilter();
          const points = ttCtx.tooltipUtil.getAllMarkers(true);
          if (points.length && !this.barSeriesHeight) {
            handlePoints();
          }
          ttCtx.tooltipPosition.moveStickyTooltipOverBars(j, capturedSeries);
          for (let b = 0; b < paths.length; b++) {
            graphics.pathMouseEnter(
              /** @type {any} */
              paths[b],
              /** @type {any} */
              void 0
            );
          }
        }
      }
    } else {
      ttCtx.tooltipLabels.drawSeriesTexts(__spreadValues({
        shared: false
      }, commonSeriesTextsParams));
      if (this.tooltipUtil.hasBars()) {
        ttCtx.tooltipPosition.moveStickyTooltipOverBars(j, capturedSeries);
      }
      if (hasMarkers) {
        ttCtx.tooltipPosition.moveMarkers(capturedSeries, j);
      }
    }
  }
}
let SVGElement$1 = class SVGElement2 {
  /**
   * @param {any} node
   */
  constructor(node) {
    this.node = node;
    if (node) {
      node.instance = this;
    }
    this._listeners = [];
    this._filter = null;
  }
  // ---- Attribute methods ----
  /**
   * @param {any} a
   * @param {any} [v]
   */
  attr(a, v) {
    if (typeof a === "string" && v === void 0) {
      return this.node.getAttribute(a);
    }
    const attrs = typeof a === "string" ? { [a]: v } : a;
    for (const key in attrs) {
      let val = attrs[key];
      if (val === null) {
        this.node.removeAttribute(key);
      } else if (val !== void 0) {
        if (typeof val === "number" && isNaN(val)) val = 0;
        this.node.setAttribute(key, val);
      }
    }
    if (this.node.nodeName === "text" && attrs.x != null) {
      const tspans = this.node.querySelectorAll("tspan[data-newline]");
      for (let i = 0; i < tspans.length; i++) {
        tspans[i].setAttribute("x", attrs.x);
      }
    }
    return this;
  }
  /**
   * @param {Record<string, string>} styles
   */
  css(styles) {
    for (const k in styles) {
      this.node.style[k] = styles[k];
    }
    return this;
  }
  /**
   * @param {any} v
   */
  fill(v) {
    if (typeof v === "object") {
      return this.attr(v);
    }
    return this.attr("fill", v);
  }
  /**
   * @param {any} v
   */
  stroke(v) {
    if (typeof v === "object") {
      if (v.color !== void 0) this.attr("stroke", v.color);
      if (v.width !== void 0) this.attr("stroke-width", v.width);
      if (v.dasharray !== void 0) this.attr("stroke-dasharray", v.dasharray);
      if (v.linecap !== void 0) this.attr("stroke-linecap", v.linecap);
      if (v.opacity !== void 0) this.attr("stroke-opacity", v.opacity);
      return this;
    }
    return this.attr("stroke", v);
  }
  /**
   * @param {number} w
   * @param {number} h
   */
  size(w, h) {
    return this.attr({ width: w, height: h });
  }
  /**
   * @param {number} x
   * @param {number} y
   */
  move(x, y) {
    return this.attr({ x, y });
  }
  /**
   * @param {number} cx
   * @param {number} cy
   */
  center(cx, cy) {
    if (this.node.nodeName === "g") {
      const box = this.bbox();
      const dx = cx - (box.x + box.width / 2);
      const dy = cy - (box.y + box.height / 2);
      return this.attr("transform", `translate(${dx}, ${dy})`);
    }
    return this.attr({ cx, cy });
  }
  // ---- Tree operations ----
  /**
   * @param {any} child
   */
  add(child) {
    this.node.appendChild(child.node || child);
    return this;
  }
  /**
   * @param {any} parent
   */
  addTo(parent) {
    const p = parent.node || parent;
    p.appendChild(this.node);
    return this;
  }
  remove() {
    if (this.node.parentNode) {
      this.node.parentNode.removeChild(this.node);
    }
    return this;
  }
  clear() {
    while (this.node.firstChild) {
      this.node.removeChild(this.node.firstChild);
    }
    return this;
  }
  // ---- Query ----
  /**
   * @param {string} selector
   */
  find(selector) {
    return Array.from(this.node.querySelectorAll(selector)).map(
      (n) => n.instance || new SVGElement2(n)
    );
  }
  /**
   * @param {string} selector
   */
  findOne(selector) {
    const n = this.node.querySelector(selector);
    return n ? n.instance || new SVGElement2(n) : null;
  }
  // ---- Events ----
  /**
   * @param {Event} event
   * @param {Function} handler
   */
  on(event, handler) {
    const eventType = (
      /** @type {string} */
      /** @type {any} */
      event.split(
        "."
      )[0]
    );
    this._listeners.push({ event, eventType, handler });
    this.node.addEventListener(eventType, handler);
    return this;
  }
  /**
   * @param {Event} event
   * @param {Function} handler
   */
  off(event, handler) {
    if (!event && !handler) {
      this._listeners.forEach((l) => {
        this.node.removeEventListener(l.eventType, l.handler);
      });
      this._listeners = [];
    } else if (event && !handler) {
      const eventType = (
        /** @type {string} */
        /** @type {any} */
        event.split(".")[0]
      );
      this._listeners = this._listeners.filter((l) => {
        if (l.eventType === eventType) {
          this.node.removeEventListener(l.eventType, l.handler);
          return false;
        }
        return true;
      });
    } else {
      const eventType = (
        /** @type {string} */
        /** @type {any} */
        event.split(".")[0]
      );
      this._listeners = this._listeners.filter((l) => {
        if (l.eventType === eventType && l.handler === handler) {
          this.node.removeEventListener(l.eventType, l.handler);
          return false;
        }
        return true;
      });
    }
    return this;
  }
  // ---- Iteration ----
  /**
   * @param {Function} fn
   * @param {boolean} deep
   */
  each(fn, deep) {
    const children = Array.from(this.node.children);
    children.forEach((child) => {
      const inst = child.instance || new SVGElement2(child);
      fn.call(inst);
      if (deep) inst.each(fn, deep);
    });
    return this;
  }
  // ---- CSS classes ----
  /**
   * @param {string} cls
   */
  removeClass(cls) {
    if (cls === "*") {
      this.node.removeAttribute("class");
    } else {
      this.node.classList.remove(cls);
    }
    return this;
  }
  // ---- Children ----
  children() {
    return Array.from(this.node.childNodes).filter((n) => n.nodeType === 1).map((n) => n.instance || new SVGElement2(n));
  }
  // ---- Visibility ----
  hide() {
    this.node.style.display = "none";
    return this;
  }
  show() {
    this.node.style.display = "";
    return this;
  }
  // ---- Measurement ----
  bbox() {
    if (typeof this.node.getBBox === "function") {
      try {
        return this.node.getBBox();
      } catch (e) {
      }
    }
    return { x: 0, y: 0, width: 0, height: 0 };
  }
  // ---- Text-specific ----
  /**
   * @param {string} text
   */
  tspan(text) {
    const tspan = BrowserAPIs.createElementNS(
      "http://www.w3.org/2000/svg",
      "tspan"
    );
    tspan.textContent = text;
    this.node.appendChild(tspan);
    return new SVGElement2(tspan);
  }
  // ---- Path-specific ----
  /**
   * @param {string} d
   */
  plot(d) {
    if (typeof d === "string") {
      this.attr("d", d);
    }
    return this;
  }
  // ---- Animation (overridden by SVGAnimation mixin) ----
  animate() {
    throw new Error("Animation module not loaded");
  }
  // ---- Filter methods (set up by SVGFilter module) ----
  filterWith() {
    throw new Error("Filter module not loaded");
  }
  /**
   * @param {boolean} all
   */
  unfilter(all) {
    if (this._filter) {
      this.node.removeAttribute("filter");
      if (all && this._filter.node && this._filter.node.parentNode) {
        this._filter.node.parentNode.removeChild(this._filter.node);
      }
      this._filter = null;
    }
    return this;
  }
  filterer() {
    return this._filter;
  }
};
let gradientCounter = 0;
class SVGGradient extends SVGElement$1 {
  /**
   * @param {any} container
   * @param {string} type
   * @param {object} builder
   */
  constructor(container, type, builder) {
    const tag = type === "radial" ? "radialGradient" : "linearGradient";
    const node = BrowserAPIs.createElementNS(SVGNS, tag);
    super(node);
    this._id = "SvgjsGradient" + ++gradientCounter;
    this.attr("id", this._id);
    if (typeof builder === "function") {
      builder(new StopBuilder(this));
    }
    let defs = container.node.querySelector("defs");
    if (!defs) {
      defs = BrowserAPIs.createElementNS(SVGNS, "defs");
      container.node.appendChild(defs);
    }
    defs.appendChild(this.node);
  }
  /**
   * @param {any} offset
   * @param {string} color
   * @param {number} opacity
   */
  stop(offset, color, opacity) {
    const s = BrowserAPIs.createElementNS(SVGNS, "stop");
    s.setAttribute("offset", offset);
    s.setAttribute("stop-color", color);
    if (opacity !== void 0) s.setAttribute("stop-opacity", String(opacity));
    this.node.appendChild(s);
    return this;
  }
  /**
   * @param {number} x
   * @param {number} y
   */
  from(x, y) {
    return this.attr({ x1: x, y1: y });
  }
  /**
   * @param {number} x
   * @param {number} y
   */
  to(x, y) {
    return this.attr({ x2: x, y2: y });
  }
  url() {
    return "url(#" + this._id + ")";
  }
  toString() {
    return this.url();
  }
  valueOf() {
    return this.url();
  }
  fill() {
    return this.url();
  }
}
class StopBuilder {
  /**
   * @param {any} gradient
   */
  constructor(gradient) {
    this.gradient = gradient;
  }
  /**
   * @param {any} offset
   * @param {string} color
   * @param {number} opacity
   */
  stop(offset, color, opacity) {
    this.gradient.stop(offset, color, opacity);
    return this;
  }
}
let patternCounter = 0;
class SVGPattern extends SVGElement$1 {
  /**
   * @param {any} container
   * @param {number} w
   * @param {number} h
   * @param {Function} builder
   */
  constructor(container, w, h, builder) {
    const node = BrowserAPIs.createElementNS(SVGNS, "pattern");
    super(node);
    this._id = "SvgjsPattern" + ++patternCounter;
    this.attr({
      id: this._id,
      width: w,
      height: h,
      patternUnits: "userSpaceOnUse"
    });
    if (typeof builder === "function") {
      const patternContainer = new SVGContainer(this.node);
      builder(patternContainer);
    }
    let defs = container.node.querySelector("defs");
    if (!defs) {
      defs = BrowserAPIs.createElementNS(SVGNS, "defs");
      container.node.appendChild(defs);
    }
    defs.appendChild(this.node);
  }
  url() {
    return "url(#" + this._id + ")";
  }
  toString() {
    return this.url();
  }
  valueOf() {
    return this.url();
  }
  fill() {
    return this.url();
  }
}
class SVGContainer extends SVGElement$1 {
  /**
   * @param {number} x1
   * @param {number} y1
   * @param {number} x2
   * @param {number} y2
   */
  line(x1, y1, x2, y2) {
    const el = this._make("line");
    if (x1 !== void 0) {
      el.attr({ x1, y1, x2, y2 });
    }
    return el;
  }
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {number} h
   */
  rect(w, h) {
    const el = this._make("rect");
    if (w !== void 0) {
      el.attr({ width: w, height: h });
    }
    return el;
  }
  /**
   * @param {number} d
   */
  circle(d) {
    const el = this._make("circle");
    if (d !== void 0) {
      el.attr({ r: d / 2, cx: d / 2, cy: d / 2 });
    }
    return el;
  }
  /**
   * @param {string} d
   */
  path(d) {
    const el = this._make("path");
    if (d) el.attr("d", d);
    return el;
  }
  /**
   * @param {string} pts
   */
  polygon(pts) {
    const el = this._make("polygon");
    if (pts) el.attr("points", pts);
    return el;
  }
  group() {
    return this._makeContainer("g");
  }
  defs() {
    return this._makeContainer("defs");
  }
  /**
   * @param {string} textContent
   */
  plain(textContent) {
    const node = BrowserAPIs.createElementNS(SVGNS, "text");
    node.textContent = textContent;
    const el = new SVGElement$1(node);
    this.node.appendChild(node);
    return el;
  }
  /**
   * @param {object} builder
   */
  text(builder) {
    const node = BrowserAPIs.createElementNS(SVGNS, "text");
    const el = new SVGElement$1(node);
    this.node.appendChild(node);
    if (typeof builder === "function") {
      builder(new TspanBuilder(node));
    }
    return el;
  }
  /**
   * @param {string} url
   * @param {Function} callback
   */
  image(url, callback) {
    const node = BrowserAPIs.createElementNS(SVGNS, "image");
    node.setAttributeNS("http://www.w3.org/1999/xlink", "href", url);
    const el = new SVGElement$1(node);
    this.node.appendChild(node);
    if (typeof callback === "function") {
      const img = new Image();
      img.onload = function() {
        el.size(img.width, img.height);
        callback.call(el, { width: img.width, height: img.height });
      };
      img.src = url;
    }
    return el;
  }
  /**
   * @param {string} type
   * @param {object} builder
   */
  gradient(type, builder) {
    return new SVGGradient(this, type, builder);
  }
  /**
   * @param {number} w
   * @param {number} h
   * @param {Function} builder
   */
  pattern(w, h, builder) {
    return new SVGPattern(this, w, h, builder);
  }
  /**
   * @param {string} tag
   */
  _make(tag) {
    const node = BrowserAPIs.createElementNS(SVGNS, tag);
    this.node.appendChild(node);
    return new SVGElement$1(node);
  }
  /**
   * @param {string} tag
   */
  _makeContainer(tag) {
    const node = BrowserAPIs.createElementNS(SVGNS, tag);
    this.node.appendChild(node);
    return new SVGContainer(node);
  }
}
class TspanBuilder {
  /**
   * @param {any} textNode
   */
  constructor(textNode) {
    this.textNode = textNode;
  }
  /**
   * @param {string} text
   */
  tspan(text) {
    const tspan = BrowserAPIs.createElementNS(SVGNS, "tspan");
    tspan.textContent = text;
    this.textNode.appendChild(tspan);
    return new TspanWrapper(tspan, this.textNode);
  }
}
class TspanWrapper {
  /**
   * @param {any} node
   * @param {any} textNode
   */
  constructor(node, textNode) {
    this.node = node;
    this.textNode = textNode;
  }
  newLine() {
    this.node.setAttribute("dy", "1.1em");
    this.node.dataset.newline = "1";
    return this;
  }
}
let filterCounter = 0;
class SVGFilter extends SVGElement$1 {
  constructor() {
    const node = BrowserAPIs.createElementNS(SVGNS, "filter");
    super(node);
    this._id = "SvgjsFilter" + ++filterCounter;
    this.attr("id", this._id);
  }
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {number} h
   * @param {number} x
   * @param {number} y
   */
  /**
   * @param {number} w
   * @param {number} h
   * @param {number} [x]
   * @param {number} [y]
   */
  size(w, h, x, y) {
    return this.attr({ width: w, height: h, x, y });
  }
}
class FilterBuilder {
  /**
   * @param {any} filter
   */
  constructor(filter) {
    this.filter = filter;
  }
  /**
   * @param {object} attrs
   */
  colorMatrix(attrs) {
    return this._primitive("feColorMatrix", attrs);
  }
  /**
   * @param {object} attrs
   */
  offset(attrs) {
    return this._primitive("feOffset", attrs);
  }
  /**
   * @param {object} attrs
   */
  gaussianBlur(attrs) {
    return this._primitive("feGaussianBlur", attrs);
  }
  /**
   * @param {object} attrs
   */
  flood(attrs) {
    return this._primitive("feFlood", attrs);
  }
  /**
   * @param {object} attrs
   */
  composite(attrs) {
    return this._primitive("feComposite", attrs);
  }
  /**
   * @param {string[]} sources
   */
  merge(sources) {
    const m = BrowserAPIs.createElementNS(SVGNS, "feMerge");
    sources.forEach((src) => {
      const mn = BrowserAPIs.createElementNS(SVGNS, "feMergeNode");
      mn.setAttribute("in", src);
      m.appendChild(mn);
    });
    this.filter.node.appendChild(m);
    return new SVGElement$1(m);
  }
  /**
   * @param {string} tag
   * @param {Record<string, any>} attrs
   */
  _primitive(tag, attrs) {
    const el = BrowserAPIs.createElementNS(SVGNS, tag);
    for (const key in attrs) {
      el.setAttribute(key, attrs[key]);
    }
    this.filter.node.appendChild(el);
    return new SVGElement$1(el);
  }
}
function installFilterMethods(ElementClass) {
  ElementClass.prototype.filterWith = function(fn) {
    const filter = new SVGFilter();
    this._filter = filter;
    let svgRoot = this.node;
    while (svgRoot && svgRoot.nodeName !== "svg") {
      svgRoot = svgRoot.parentNode;
    }
    if (svgRoot) {
      let defs = svgRoot.querySelector("defs");
      if (!defs) {
        defs = BrowserAPIs.createElementNS(SVGNS, "defs");
        svgRoot.insertBefore(defs, svgRoot.firstChild);
      }
      defs.appendChild(filter.node);
    }
    fn(new FilterBuilder(filter));
    this.attr("filter", "url(#" + filter._id + ")");
    return this;
  };
  ElementClass.prototype.unfilter = function(all) {
    if (this._filter) {
      this.node.removeAttribute("filter");
      if (all && this._filter.node && this._filter.node.parentNode) {
        this._filter.node.parentNode.removeChild(this._filter.node);
      }
      this._filter = null;
    }
    return this;
  };
  ElementClass.prototype.filterer = function() {
    return this._filter;
  };
}
/*!
 * Path morphing for SVG path animations
 * Based on svg.pathmorphing.js by Ulrich-Matthias Schäfer (MIT License)
 * Refactored to be standalone (no SVG.js dependency)
 */
function parsePath(d) {
  if (!d || typeof d !== "string") return [["M", 0, 0]];
  const commands = [];
  const re = /([MmLlHhVvCcSsQqTtAaZz])\s*/g;
  const numRe = /[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?/gi;
  let match;
  const letters = [];
  const positions = [];
  while ((match = re.exec(d)) !== null) {
    letters.push(match[1]);
    positions.push(match.index);
  }
  for (let i = 0; i < letters.length; i++) {
    const start = positions[i] + letters[i].length;
    const end = i + 1 < positions.length ? positions[i + 1] : d.length;
    const paramStr = d.substring(start, end);
    const nums = [];
    let numMatch;
    numRe.lastIndex = 0;
    while ((numMatch = numRe.exec(paramStr)) !== null) {
      nums.push(parseFloat(numMatch[0]));
    }
    const cmd = letters[i].toUpperCase();
    if (cmd === "Z") {
      commands.push(["Z"]);
    } else if (cmd === "M" || cmd === "L" || cmd === "T") {
      for (let j = 0; j < nums.length; j += 2) {
        commands.push([cmd, nums[j], nums[j + 1]]);
      }
    } else if (cmd === "H") {
      for (let j = 0; j < nums.length; j++) {
        commands.push([cmd, nums[j]]);
      }
    } else if (cmd === "V") {
      for (let j = 0; j < nums.length; j++) {
        commands.push([cmd, nums[j]]);
      }
    } else if (cmd === "C") {
      for (let j = 0; j < nums.length; j += 6) {
        commands.push([
          cmd,
          nums[j],
          nums[j + 1],
          nums[j + 2],
          nums[j + 3],
          nums[j + 4],
          nums[j + 5]
        ]);
      }
    } else if (cmd === "S" || cmd === "Q") {
      for (let j = 0; j < nums.length; j += 4) {
        commands.push([cmd, nums[j], nums[j + 1], nums[j + 2], nums[j + 3]]);
      }
    } else if (cmd === "A") {
      for (let j = 0; j < nums.length; j += 7) {
        commands.push([
          cmd,
          nums[j],
          nums[j + 1],
          nums[j + 2],
          nums[j + 3],
          nums[j + 4],
          nums[j + 5],
          nums[j + 6]
        ]);
      }
    }
  }
  if (commands.length === 0) {
    commands.push(["M", 0, 0]);
  }
  return commands;
}
function pathBbox(arr) {
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
  arr.forEach((cmd) => {
    for (let i = 1; i < cmd.length; i += 2) {
      if (i + 1 <= cmd.length) {
        const x = cmd[i];
        const y = cmd[i + 1];
        if (typeof x === "number" && typeof y === "number") {
          if (x < minX) minX = x;
          if (x > maxX) maxX = x;
          if (y < minY) minY = y;
          if (y > maxY) maxY = y;
        }
      }
    }
  });
  if (minX === Infinity) {
    return { x: 0, y: 0, width: 0, height: 0 };
  }
  return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
}
function arrayToPath(arr) {
  return arr.map((cmd) => cmd.join(" ")).join(" ");
}
function simplify(val) {
  switch (val[0]) {
    case "z":
    case "Z":
      val[0] = "L";
      val[1] = this.start[0];
      val[2] = this.start[1];
      break;
    case "H":
      val[0] = "L";
      val[2] = this.pos[1];
      break;
    case "V":
      val[0] = "L";
      val[2] = val[1];
      val[1] = this.pos[0];
      break;
    case "T":
      val[0] = "Q";
      val[3] = val[1];
      val[4] = val[2];
      val[1] = this.reflection[1];
      val[2] = this.reflection[0];
      break;
    case "S":
      val[0] = "C";
      val[6] = val[4];
      val[5] = val[3];
      val[4] = val[2];
      val[3] = val[1];
      val[2] = this.reflection[1];
      val[1] = this.reflection[0];
      break;
  }
  return val;
}
function setPosAndReflection(val) {
  var len = val.length;
  this.pos = [val[len - 2], val[len - 1]];
  if ("SCQT".indexOf(val[0]) != -1) {
    this.reflection = [
      2 * this.pos[0] - val[len - 4],
      2 * this.pos[1] - val[len - 3]
    ];
  }
  return val;
}
function toBezier(val) {
  var _a;
  var retVal = [val];
  switch (val[0]) {
    case "M":
      this.pos = this.start = [val[1], val[2]];
      return retVal;
    case "L":
      val[5] = val[3] = val[1];
      val[6] = val[4] = val[2];
      val[1] = this.pos[0];
      val[2] = this.pos[1];
      break;
    case "Q":
      val[6] = val[4];
      val[5] = val[3];
      val[4] = val[4] * 1 / 3 + val[2] * 2 / 3;
      val[3] = val[3] * 1 / 3 + val[1] * 2 / 3;
      val[2] = this.pos[1] * 1 / 3 + val[2] * 2 / 3;
      val[1] = this.pos[0] * 1 / 3 + val[1] * 2 / 3;
      break;
    case "A":
      retVal = arcToBezier((_a = this.pos) != null ? _a : [], val);
      val = retVal[0];
      break;
  }
  val[0] = "C";
  this.pos = [val[5], val[6]];
  this.reflection = [2 * val[5] - val[3], 2 * val[6] - val[4]];
  return retVal;
}
function findNextM(arr, offset) {
  if (offset === false) return false;
  for (var i = offset, len = arr.length; i < len; ++i) {
    if (arr[i][0] == "M") return i;
  }
  return false;
}
function arcToBezier(pos, val) {
  var rx = Math.abs(val[1]), ry = Math.abs(val[2]), xAxisRotation = val[3] % 360, largeArcFlag = val[4], sweepFlag = val[5], x = val[6], y = val[7], A = new Point(pos[0], pos[1]), B = new Point(x, y), primedCoord, lambda, mat, k, c, cSquare, t, O, OA, OB, tetaStart, tetaEnd, deltaTeta, nbSectors, f, arcSegPoints, angle, sinAngle, cosAngle, pt, i, il, retVal = [], x1, y1, x2, y2;
  if (rx === 0 || ry === 0 || A.x === B.x && A.y === B.y) {
    return [["C", A.x, A.y, B.x, B.y, B.x, B.y]];
  }
  primedCoord = new Point((A.x - B.x) / 2, (A.y - B.y) / 2).transform(
    /** @type {any} */
    new Matrix(0, 0, 0, 0, 0, 0).rotate(xAxisRotation)
  );
  lambda = primedCoord.x * primedCoord.x / (rx * rx) + primedCoord.y * primedCoord.y / (ry * ry);
  if (lambda > 1) {
    lambda = Math.sqrt(lambda);
    rx = lambda * rx;
    ry = lambda * ry;
  }
  mat = /** @type {any} */
  new Matrix(0, 0, 0, 0, 0, 0).rotate(xAxisRotation).scale(1 / rx, 1 / ry).rotate(-xAxisRotation);
  A = A.transform(mat);
  B = B.transform(mat);
  k = [B.x - A.x, B.y - A.y];
  cSquare = k[0] * k[0] + k[1] * k[1];
  c = Math.sqrt(cSquare);
  k[0] /= c;
  k[1] /= c;
  t = cSquare < 4 ? Math.sqrt(1 - cSquare / 4) : 0;
  if (largeArcFlag === sweepFlag) {
    t *= -1;
  }
  O = new Point((B.x + A.x) / 2 + t * -k[1], (B.y + A.y) / 2 + t * k[0]);
  OA = new Point(A.x - O.x, A.y - O.y);
  OB = new Point(B.x - O.x, B.y - O.y);
  tetaStart = Math.acos(OA.x / Math.sqrt(OA.x * OA.x + OA.y * OA.y));
  if (OA.y < 0) tetaStart *= -1;
  tetaEnd = Math.acos(OB.x / Math.sqrt(OB.x * OB.x + OB.y * OB.y));
  if (OB.y < 0) tetaEnd *= -1;
  if (sweepFlag && tetaStart > tetaEnd) {
    tetaEnd += 2 * Math.PI;
  }
  if (!sweepFlag && tetaStart < tetaEnd) {
    tetaEnd -= 2 * Math.PI;
  }
  nbSectors = Math.ceil(Math.abs(tetaStart - tetaEnd) * 2 / Math.PI);
  arcSegPoints = [];
  angle = tetaStart;
  deltaTeta = (tetaEnd - tetaStart) / nbSectors;
  f = 4 * Math.tan(deltaTeta / 4) / 3;
  for (i = 0; i <= nbSectors; i++) {
    cosAngle = Math.cos(angle);
    sinAngle = Math.sin(angle);
    pt = new Point(O.x + cosAngle, O.y + sinAngle);
    arcSegPoints[i] = [
      new Point(pt.x + f * sinAngle, pt.y - f * cosAngle),
      pt,
      new Point(pt.x - f * sinAngle, pt.y + f * cosAngle)
    ];
    angle += deltaTeta;
  }
  arcSegPoints[0][0] = arcSegPoints[0][1].clone();
  arcSegPoints[arcSegPoints.length - 1][2] = arcSegPoints[arcSegPoints.length - 1][1].clone();
  mat = /** @type {any} */
  new Matrix(0, 0, 0, 0, 0, 0).rotate(xAxisRotation).scale(rx, ry).rotate(-xAxisRotation);
  for (i = 0, il = arcSegPoints.length; i < il; i++) {
    arcSegPoints[i][0] = arcSegPoints[i][0].transform(mat);
    arcSegPoints[i][1] = arcSegPoints[i][1].transform(mat);
    arcSegPoints[i][2] = arcSegPoints[i][2].transform(mat);
  }
  for (i = 1, il = arcSegPoints.length; i < il; i++) {
    pt = arcSegPoints[i - 1][2];
    x1 = pt.x;
    y1 = pt.y;
    pt = arcSegPoints[i][0];
    x2 = pt.x;
    y2 = pt.y;
    pt = arcSegPoints[i][1];
    x = pt.x;
    y = pt.y;
    retVal.push(["C", x1, y1, x2, y2, x, y]);
  }
  return retVal;
}
function handleBlock(startArr, startOffsetM, startOffsetNextM, destArr, destOffsetM, destOffsetNextM) {
  var startArrTemp = startArr.slice(startOffsetM, startOffsetNextM || void 0);
  var destArrTemp = destArr.slice(destOffsetM, destOffsetNextM || void 0);
  var i = 0, posStart = { pos: [0, 0], start: [0, 0] }, posDest = { pos: [0, 0], start: [0, 0] };
  while (true) {
    startArrTemp[i] = simplify.call(posStart, startArrTemp[i]);
    destArrTemp[i] = simplify.call(posDest, destArrTemp[i]);
    if (startArrTemp[i][0] != destArrTemp[i][0] || startArrTemp[i][0] == "M" || startArrTemp[i][0] == "A" && (startArrTemp[i][4] != destArrTemp[i][4] || startArrTemp[i][5] != destArrTemp[i][5])) {
      Array.prototype.splice.apply(
        startArrTemp,
        /** @type {[number, number, ...any[]]} */
        [i, 1].concat(
          /** @type {any} */
          toBezier.call(posStart, startArrTemp[i])
        )
      );
      Array.prototype.splice.apply(
        destArrTemp,
        /** @type {[number, number, ...any[]]} */
        [i, 1].concat(
          /** @type {any} */
          toBezier.call(posDest, destArrTemp[i])
        )
      );
    } else {
      startArrTemp[i] = /** @type {any} */
      setPosAndReflection.call(
        posStart,
        startArrTemp[i]
      );
      destArrTemp[i] = /** @type {any} */
      setPosAndReflection.call(
        posDest,
        destArrTemp[i]
      );
    }
    if (++i == startArrTemp.length && i == destArrTemp.length) break;
    if (i == startArrTemp.length) {
      startArrTemp.push([
        "C",
        posStart.pos[0],
        posStart.pos[1],
        posStart.pos[0],
        posStart.pos[1],
        posStart.pos[0],
        posStart.pos[1]
      ]);
    }
    if (i == destArrTemp.length) {
      destArrTemp.push([
        "C",
        posDest.pos[0],
        posDest.pos[1],
        posDest.pos[0],
        posDest.pos[1],
        posDest.pos[0],
        posDest.pos[1]
      ]);
    }
  }
  return { start: startArrTemp, dest: destArrTemp };
}
function synchronizePaths(fromD, toD) {
  var startArr = parsePath(fromD);
  var destArr = parsePath(toD);
  var startOffsetM = 0;
  var destOffsetM = 0;
  var startOffsetNextM = false;
  var destOffsetNextM = false;
  var result;
  while (true) {
    if (startOffsetM === false && destOffsetM === false) break;
    startOffsetNextM = findNextM(
      startArr,
      startOffsetM === false ? false : startOffsetM + 1
    );
    destOffsetNextM = findNextM(
      destArr,
      destOffsetM === false ? false : destOffsetM + 1
    );
    if (startOffsetM === false) {
      const bbox = pathBbox(
        /** @type {any} */
        result.start
      );
      if (bbox.height == 0 || bbox.width == 0) {
        startOffsetM = startArr.push(startArr[0]) - 1;
      } else {
        startOffsetM = startArr.push([
          "M",
          bbox.x + bbox.width / 2,
          bbox.y + bbox.height / 2
        ]) - 1;
      }
    }
    if (destOffsetM === false) {
      const bbox = pathBbox(
        /** @type {any} */
        result.dest
      );
      if (bbox.height == 0 || bbox.width == 0) {
        destOffsetM = destArr.push(destArr[0]) - 1;
      } else {
        destOffsetM = destArr.push([
          "M",
          bbox.x + bbox.width / 2,
          bbox.y + bbox.height / 2
        ]) - 1;
      }
    }
    result = handleBlock(
      startArr,
      startOffsetM,
      startOffsetNextM,
      destArr,
      destOffsetM,
      destOffsetNextM
    );
    startArr = startArr.slice(0, startOffsetM).concat(
      result.start,
      startOffsetNextM === false ? [] : startArr.slice(startOffsetNextM)
    );
    destArr = destArr.slice(0, destOffsetM).concat(
      result.dest,
      destOffsetNextM === false ? [] : destArr.slice(destOffsetNextM)
    );
    startOffsetM = startOffsetNextM === false ? false : startOffsetM + result.start.length;
    destOffsetM = destOffsetNextM === false ? false : destOffsetM + result.dest.length;
  }
  return { start: startArr, dest: destArr };
}
function morphPaths(fromD, toD) {
  var synced = synchronizePaths(fromD, toD);
  var startArr = synced.start;
  var destArr = synced.dest;
  return function(pos) {
    var result = startArr.map(function(from, idx) {
      return destArr[idx].map(function(to, toIdx) {
        if (toIdx === 0) return to;
        return from[toIdx] + (destArr[idx][toIdx] - from[toIdx]) * pos;
      });
    });
    return arrayToPath(result);
  };
}
function easeInOut(t) {
  return -Math.cos(t * Math.PI) / 2 + 0.5;
}
function parseColor(str) {
  if (!str || typeof str !== "string") return null;
  if (str[0] === "#") {
    let hex = str.slice(1);
    if (hex.length === 3)
      hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
    const n = parseInt(hex, 16);
    return [n >> 16 & 255, n >> 8 & 255, n & 255, 1];
  }
  const m = str.match(
    /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/
  );
  if (m) return [+m[1], +m[2], +m[3], m[4] !== void 0 ? +m[4] : 1];
  return null;
}
function interpolateColor(from, to, pos) {
  return `rgba(${Math.round(from[0] + (to[0] - from[0]) * pos)},${Math.round(from[1] + (to[1] - from[1]) * pos)},${Math.round(from[2] + (to[2] - from[2]) * pos)},${from[3] + (to[3] - from[3]) * pos})`;
}
class SVGAnimationRunner {
  /**
   * @param {any} element
   * @param {number} duration
   * @param {number} delay
   */
  constructor(element, duration, delay) {
    this.el = element;
    this.duration = duration != null ? duration : 300;
    this.delay = delay || 0;
    this._attrTarget = null;
    this._plotTarget = null;
    this._afterCb = null;
    this._duringCb = null;
    this._next = null;
    this._root = null;
    this._scheduled = false;
  }
  /**
   * @param {Record<string, any>} to
   */
  attr(to) {
    this._attrTarget = to;
    this._schedule();
    return this;
  }
  /**
   * @param {string} d
   */
  plot(d) {
    this._plotTarget = d;
    this._schedule();
    return this;
  }
  /**
   * @param {Function} fn
   */
  after(fn) {
    this._afterCb = fn;
    this._schedule();
    return this;
  }
  /**
   * @param {Function} fn
   */
  during(fn) {
    this._duringCb = fn;
    this._schedule();
    return this;
  }
  /**
   * @param {number} duration
   * @param {number} delay
   */
  animate(duration, delay) {
    const next = new SVGAnimationRunner(this.el, duration, delay);
    this._next = next;
    next._root = this._root || this;
    return next;
  }
  _schedule() {
    const root = this._root || this;
    if (!root._scheduled) {
      root._scheduled = true;
      queueMicrotask(() => root._executeChain());
    }
  }
  _executeChain() {
    const chain = [];
    let r = this;
    while (r) {
      chain.push(r);
      r = r._next;
    }
    let cumulativeDelay = 0;
    chain.forEach((runner) => {
      cumulativeDelay += runner.delay;
      runner._execute(cumulativeDelay);
      cumulativeDelay += runner.duration;
    });
  }
  /**
   * @param {number} startDelay
   */
  _execute(startDelay) {
    const el = this.el;
    const duration = this.duration;
    if (duration <= 1) {
      const apply = () => {
        if (this._attrTarget) el.attr(this._attrTarget);
        if (this._plotTarget) el.plot(this._plotTarget);
        if (this._afterCb) this._afterCb.call(el);
      };
      if (startDelay > 0) {
        setTimeout(apply, startDelay);
      } else {
        apply();
      }
      return;
    }
    const run = () => {
      const fromAttrs = (
        /** @type {Record<string, any>} */
        {}
      );
      const fromColors = (
        /** @type {Record<string, any>} */
        {}
      );
      const toColors = (
        /** @type {Record<string, any>} */
        {}
      );
      if (this._attrTarget) {
        for (const key of Object.keys(this._attrTarget)) {
          const fromVal = el.attr(key);
          fromAttrs[key] = fromVal;
          const fc = parseColor(fromVal);
          const tc = parseColor(String(this._attrTarget[key]));
          if (fc && tc) {
            fromColors[key] = fc;
            toColors[key] = tc;
          }
        }
      }
      let morphFn = null;
      if (this._plotTarget) {
        const fromPath = el.attr("d") || "";
        try {
          morphFn = morphPaths(fromPath, this._plotTarget);
        } catch (e) {
          morphFn = null;
        }
      }
      const start = performance.now();
      const tick = (now) => {
        const elapsed = now - start;
        const rawPos = Math.min(elapsed / duration, 1);
        const pos = easeInOut(rawPos);
        if (this._attrTarget) {
          if (rawPos >= 1) {
            el.attr(this._attrTarget);
          } else {
            const current = (
              /** @type {Record<string, any>} */
              {}
            );
            for (const key of Object.keys(this._attrTarget)) {
              if (fromColors[key] && toColors[key]) {
                current[key] = interpolateColor(
                  fromColors[key],
                  toColors[key],
                  pos
                );
              } else {
                const from = parseFloat(fromAttrs[key]);
                const to = parseFloat(this._attrTarget[key]);
                if (!isNaN(from) && !isNaN(to)) {
                  current[key] = from + (to - from) * pos;
                }
              }
            }
            el.attr(current);
          }
        }
        if (morphFn && rawPos < 1) {
          el.attr(
            "d",
            /** @type {any} */
            morphFn(pos)
          );
        }
        if (this._duringCb) this._duringCb(pos);
        if (rawPos < 1) {
          BrowserAPIs.requestAnimationFrame(tick);
        } else {
          if (this._plotTarget) {
            el.attr("d", this._plotTarget);
          }
          if (this._afterCb) this._afterCb.call(el);
        }
      };
      BrowserAPIs.requestAnimationFrame(tick);
    };
    if (startDelay > 0) {
      setTimeout(run, startDelay);
    } else {
      run();
    }
  }
}
function installAnimationMethods(ElementClass) {
  ElementClass.prototype.animate = function(duration, delay) {
    return new SVGAnimationRunner(this, duration, delay);
  };
}
function installDraggable(ElementClass) {
  ElementClass.prototype.draggable = function(opts) {
    if (opts === false) {
      if (this._dragCleanup) {
        this._dragCleanup();
        this._dragCleanup = null;
      }
      return this;
    }
    const el = this;
    const constraints = opts || {};
    const onPointerDown = (e) => {
      if (e.button && e.button !== 0) return;
      e.stopPropagation();
      const isTouch = e.type === "touchstart";
      const ev = isTouch ? e.touches[0] : e;
      const svgEl = el.node;
      const startAttrX = parseFloat(svgEl.getAttribute("x")) || 0;
      const startAttrY = parseFloat(svgEl.getAttribute("y")) || 0;
      const startClientX = ev.clientX;
      const startClientY = ev.clientY;
      const svgRoot = svgEl.ownerSVGElement;
      let ctm = null;
      if (svgRoot) {
        ctm = svgRoot.getScreenCTM();
      }
      const onMove = (me) => {
        const mev = me.type === "touchmove" ? me.touches[0] : me;
        let dx = mev.clientX - startClientX;
        let dy = mev.clientY - startClientY;
        if (ctm) {
          dx = dx / ctm.a;
          dy = dy / ctm.d;
        }
        let newX = startAttrX + dx;
        let newY = startAttrY + dy;
        const w = parseFloat(svgEl.getAttribute("width")) || 0;
        const h = parseFloat(svgEl.getAttribute("height")) || 0;
        if (constraints.minX !== void 0 && newX < constraints.minX)
          newX = constraints.minX;
        if (constraints.minY !== void 0 && newY < constraints.minY)
          newY = constraints.minY;
        if (constraints.maxX !== void 0 && newX + w > constraints.maxX)
          newX = constraints.maxX - w;
        if (constraints.maxY !== void 0 && newY + h > constraints.maxY)
          newY = constraints.maxY - h;
        const box = {
          x: newX,
          y: newY,
          w,
          h,
          x2: newX + w,
          y2: newY + h
        };
        const event = new CustomEvent("dragmove", {
          detail: {
            handler: {
              /**
               * @param {number} x
               * @param {number} y
               */
              move: function(x, y) {
                svgEl.setAttribute("x", x);
                svgEl.setAttribute("y", y);
              }
            },
            box
          }
        });
        svgEl.dispatchEvent(event);
      };
      const onUp = () => {
        if (Environment.isBrowser()) {
          document.removeEventListener("mousemove", onMove);
          document.removeEventListener("touchmove", onMove);
          document.removeEventListener("mouseup", onUp);
          document.removeEventListener("touchend", onUp);
        }
      };
      if (Environment.isBrowser()) {
        document.addEventListener("mousemove", onMove);
        document.addEventListener("touchmove", onMove);
        document.addEventListener("mouseup", onUp);
        document.addEventListener("touchend", onUp);
      }
    };
    el.node.addEventListener("mousedown", onPointerDown);
    el.node.addEventListener("touchstart", onPointerDown);
    el._dragCleanup = () => {
      el.node.removeEventListener("mousedown", onPointerDown);
      el.node.removeEventListener("touchstart", onPointerDown);
    };
    return el;
  };
}
function installSelectable(ElementClass) {
  ElementClass.prototype.select = function(opts) {
    if (opts === false) {
      if (this._selectCleanup) {
        this._selectCleanup();
        this._selectCleanup = null;
      }
      return this;
    }
    const el = this;
    const { createHandle, updateHandle } = opts;
    const handleGroup = document.createElementNS(SVGNS, "g");
    handleGroup.setAttribute("class", "svg_select_points");
    const parent = el.node.parentNode;
    if (parent) {
      parent.appendChild(handleGroup);
    }
    const handles = {};
    const handleNames = ["t", "b", "l", "r", "lt", "rt", "lb", "rb"];
    handleNames.forEach((name2, index) => {
      const subGroup = new SVGContainer(document.createElementNS(SVGNS, "g"));
      handleGroup.appendChild(subGroup.node);
      const handle = createHandle(subGroup, [0, 0], index, [], name2);
      handles[name2] = { group: subGroup, handle };
    });
    const updatePositions = () => {
      const x = parseFloat(el.attr("x")) || 0;
      const y = parseFloat(el.attr("y")) || 0;
      const w = parseFloat(el.attr("width")) || 0;
      const h = parseFloat(el.attr("height")) || 0;
      const elTransform = el.node.getAttribute("transform");
      if (elTransform) {
        handleGroup.setAttribute("transform", elTransform);
      } else {
        handleGroup.removeAttribute("transform");
      }
      const positions = {
        t: [x + w / 2, y],
        b: [x + w / 2, y + h],
        l: [x, y + h / 2],
        r: [x + w, y + h / 2],
        lt: [x, y],
        rt: [x + w, y],
        lb: [x, y + h],
        rb: [x + w, y + h]
      };
      handleNames.forEach((name2) => {
        if (handles[name2] && positions[name2]) {
          updateHandle(handles[name2].group, positions[name2]);
        }
      });
    };
    updatePositions();
    el._selectHandles = handleGroup;
    el._selectHandlesMap = handles;
    el._updateSelectPositions = updatePositions;
    el._selectCleanup = () => {
      if (handleGroup.parentNode) {
        handleGroup.parentNode.removeChild(handleGroup);
      }
      el._selectHandles = null;
      el._selectHandlesMap = null;
      el._updateSelectPositions = null;
    };
    return el;
  };
  ElementClass.prototype.resize = function(enable) {
    if (enable === false) {
      if (this._resizeCleanup) {
        this._resizeCleanup();
        this._resizeCleanup = null;
      }
      return this;
    }
    const el = this;
    const handles = el._selectHandlesMap;
    if (!handles) return el;
    const cleanupFns = [];
    const makeHandleDraggable = (name2) => {
      const handleInfo = handles[name2];
      if (!handleInfo || !handleInfo.group || !handleInfo.group.node) return;
      const handleNode = handleInfo.group.node;
      const onPointerDown = (e) => {
        if (e.button && e.button !== 0) return;
        e.stopPropagation();
        const isTouch = e.type === "touchstart";
        const ev = isTouch ? e.touches[0] : e;
        const startClientX = ev.clientX;
        const svgRoot = el.node.ownerSVGElement;
        let ctm = null;
        if (svgRoot) {
          ctm = svgRoot.getScreenCTM();
        }
        const startX = parseFloat(el.attr("x")) || 0;
        const startW = parseFloat(el.attr("width")) || 0;
        const onMove = (me) => {
          const mev = me.type === "touchmove" ? me.touches[0] : me;
          let dx = mev.clientX - startClientX;
          if (ctm) dx = dx / /** @type {any} */
          ctm.a;
          let newX = startX;
          let newW = startW;
          if (name2 === "l") {
            newX = startX + dx;
            newW = startW - dx;
          } else if (name2 === "r") {
            newW = startW + dx;
          }
          if (newW < 0) {
            newW = 0;
          }
          el.attr({ x: newX, width: newW });
          if (el._updateSelectPositions) {
            el._updateSelectPositions();
          }
          const event = new CustomEvent("resize", {
            detail: { el }
          });
          el.node.dispatchEvent(event);
        };
        const onUp = () => {
          if (Environment.isBrowser()) {
            document.removeEventListener("mousemove", onMove);
            document.removeEventListener("touchmove", onMove);
            document.removeEventListener("mouseup", onUp);
            document.removeEventListener("touchend", onUp);
          }
          const event = new CustomEvent("resize", {
            detail: { el }
          });
          el.node.dispatchEvent(event);
        };
        if (Environment.isBrowser()) {
          document.addEventListener("mousemove", onMove);
          document.addEventListener("touchmove", onMove);
          document.addEventListener("mouseup", onUp);
          document.addEventListener("touchend", onUp);
        }
      };
      handleNode.addEventListener("mousedown", onPointerDown);
      handleNode.addEventListener("touchstart", onPointerDown);
      cleanupFns.push(() => {
        handleNode.removeEventListener("mousedown", onPointerDown);
        handleNode.removeEventListener("touchstart", onPointerDown);
      });
    };
    makeHandleDraggable("l");
    makeHandleDraggable("r");
    el._resizeCleanup = () => {
      cleanupFns.forEach((fn) => fn());
    };
    return el;
  };
}
installFilterMethods(SVGElement$1);
installAnimationMethods(SVGElement$1);
installDraggable(SVGElement$1);
installSelectable(SVGElement$1);
function SVG() {
  const svgEl = BrowserAPIs.createElementNS(SVGNS, "svg");
  const svg = new SVGContainer(svgEl);
  svg.attr({ xmlns: SVGNS });
  return svg;
}
SVG.xlink = "http://www.w3.org/1999/xlink";
if (Environment.isBrowser() && typeof window.SVG === "undefined") {
  window.SVG = SVG;
}
if (Environment.isBrowser()) {
  if (typeof window.SVG === "undefined") {
    window.SVG = SVG;
  }
  if (typeof window.Apex === "undefined") {
    window.Apex = {};
  }
} else {
  if (typeof global !== "undefined") {
    if (typeof /** @type {any} */
    global.Apex === "undefined") {
      global.Apex = {};
    }
    if (typeof /** @type {any} */
    global.SVG === "undefined") {
      global.SVG = SVG;
    }
  }
}
const _InitCtxVariables = class _InitCtxVariables {
  /**
   * Register one or more optional feature modules.
   *
   * @param {Record<string, new (w: object, ctx: object) => unknown>} featureMap
   *   Plain object mapping ctx property name → constructor.
   *
   * Example (called from src/features/legend.js):
   *   InitCtxVariables.registerFeatures({ legend: Legend })
   */
  static registerFeatures(featureMap) {
    for (const [key, Ctor] of Object.entries(featureMap)) {
      _InitCtxVariables._featureRegistry.set(key, Ctor);
    }
  }
  /**
   * @param {import('../../types/internal').ChartContext} ctx
   */
  constructor(ctx) {
    this.ctx = ctx;
    this.w = ctx.w;
  }
  initModules() {
    this.ctx.publicMethods = [
      "updateOptions",
      "updateSeries",
      "appendData",
      "appendSeries",
      "isSeriesHidden",
      "highlightSeries",
      "toggleSeries",
      "showSeries",
      "hideSeries",
      "setLocale",
      "resetSeries",
      "zoomX",
      "toggleDataPointSelection",
      "dataURI",
      "exportToCSV",
      "addXaxisAnnotation",
      "addYaxisAnnotation",
      "addPointAnnotation",
      "clearAnnotations",
      "removeAnnotation",
      "paper",
      "destroy"
    ];
    this.ctx.eventList = [
      "click",
      "mousedown",
      "mousemove",
      "mouseleave",
      "touchstart",
      "touchmove",
      "touchleave",
      "mouseup",
      "touchend",
      "keydown",
      "keyup"
    ];
    this.ctx.animations = new Animations(this.w, this.ctx);
    this.ctx.axes = new Axes(this.w, this.ctx);
    this.ctx.core = new Core(this.ctx.el, this.w, this.ctx);
    this.ctx.config = new Config({});
    this.ctx.data = new Data(this.w, {
      resetGlobals: () => this.ctx.core.resetGlobals(),
      isMultipleY: () => this.ctx.core.isMultipleY()
    });
    this.ctx.grid = new Grid(this.w, this.ctx);
    this.ctx.graphics = new Graphics(this.w, this.ctx);
    this.ctx.coreUtils = new CoreUtils(this.w);
    this.ctx.crosshairs = new Crosshairs(this.w);
    this.ctx.events = new Events(this.w, this.ctx);
    this.ctx.fill = new Fill(this.w);
    this.ctx.localization = new Localization(this.w);
    this.ctx.options = new Options();
    this.ctx.responsive = new Responsive(this.w);
    this.ctx.series = new Series(this.w, {
      // legend may not be registered — guard with ?.
      toggleDataSeries: (...a) => {
        var _a;
        return (_a = this.ctx.legend) == null ? void 0 : _a.legendHelpers.toggleDataSeries(...a);
      },
      revertDefaultAxisMinMax: () => this.ctx.updateHelpers.revertDefaultAxisMinMax(),
      updateSeries: (...a) => this.ctx.updateHelpers._updateSeries(...a)
    });
    this.ctx.theme = new Theme(this.w);
    this.ctx.formatters = new Formatters(this.w);
    this.ctx.titleSubtitle = new TitleSubtitle(this.w);
    this.ctx.dimensions = new Dimensions(this.w, this.ctx);
    this.ctx.updateHelpers = new UpdateHelpers(this.w, this.ctx);
    const tooltipInstance = new Tooltip(this.w, this.ctx);
    this.w.globals.tooltip = tooltipInstance;
    Object.defineProperty(this.ctx, "tooltip", {
      get() {
        return this.w.globals.tooltip;
      },
      configurable: true
    });
    this._initOptionalModules();
  }
  /**
   * Instantiate optional feature modules from the registry.
   *
   * Modules that are not registered are set to null on ctx so that call sites
   * can safely use optional-chaining (ctx.tooltip?.drawTooltip(...)).
   *
   * Lazy-getter features (toolbar, zoomPanSelection, keyboardNavigation) are
   * installed as on-demand getters so they are only constructed if accessed,
   * and only if their constructor was registered.
   */
  _initOptionalModules() {
    const reg = _InitCtxVariables._featureRegistry;
    const w = this.w;
    const ctx = this.ctx;
    const ExportsCtor = reg.get("exports");
    ctx.exports = ExportsCtor ? new ExportsCtor(w, ctx) : null;
    const LegendCtor = reg.get("legend");
    ctx.legend = LegendCtor ? new LegendCtor(w, ctx) : null;
    const ToolbarCtor = reg.get("toolbar");
    Object.defineProperty(ctx, "toolbar", {
      get() {
        var _a;
        if (!this._toolbar && ToolbarCtor)
          this._toolbar = new ToolbarCtor(w, this);
        return (_a = this._toolbar) != null ? _a : null;
      },
      configurable: true
    });
    const ZoomPanCtor = reg.get("zoomPanSelection");
    Object.defineProperty(ctx, "zoomPanSelection", {
      get() {
        var _a;
        if (!this._zoomPanSelection && ZoomPanCtor)
          this._zoomPanSelection = new ZoomPanCtor(w, this);
        return (_a = this._zoomPanSelection) != null ? _a : null;
      },
      configurable: true
    });
    const KeyboardCtor = reg.get("keyboardNavigation");
    Object.defineProperty(ctx, "keyboardNavigation", {
      get() {
        var _a;
        if (!this._keyboardNavigation && KeyboardCtor)
          this._keyboardNavigation = new KeyboardCtor(w, this);
        return (_a = this._keyboardNavigation) != null ? _a : null;
      },
      configurable: true
    });
  }
};
/**
 * Registry of optional feature modules.
 *
 * Populated by ApexCharts.registerFeatures() (called from feature entry
 * files such as src/features/legend.js). Keys match the ctx property name
 * the module is stored under (e.g. 'legend', 'exports').
 *
 * Core modules that every chart needs are NOT in this registry — they are
 * always instantiated unconditionally in initModules().
 */
__publicField(_InitCtxVariables, "_featureRegistry", /* @__PURE__ */ new Map());
let InitCtxVariables = _InitCtxVariables;
class Destroy {
  /**
   * @param {import('../../types/internal').ChartContext} ctx
   */
  constructor(ctx) {
    this.ctx = ctx;
    this.w = ctx.w;
  }
  /**
   * @param {{ isUpdating: boolean }} opts
   */
  clear({ isUpdating }) {
    if (this.ctx._zoomPanSelection) {
      this.ctx._zoomPanSelection.destroy();
    }
    if (this.ctx._toolbar) {
      this.ctx._toolbar.destroy();
    }
    if (this.w.globals.resizeObserver && typeof this.w.globals.resizeObserver.disconnect === "function") {
      this.w.globals.resizeObserver.disconnect();
      this.w.globals.resizeObserver = null;
    }
    PerformanceCache.invalidateAll(this.w);
    if (isUpdating) {
      this.ctx._zoomPanSelection = null;
      this.ctx._toolbar = null;
      this.ctx._keyboardNavigation = null;
    } else {
      this.ctx.animations = null;
      this.ctx.axes = null;
      this.ctx.annotations = null;
      this.ctx.core = null;
      this.ctx.data = null;
      this.ctx.grid = null;
      this.ctx.series = null;
      this.ctx.responsive = null;
      this.ctx.theme = null;
      this.ctx.formatters = null;
      this.ctx.titleSubtitle = null;
      this.ctx.legend = null;
      this.ctx.dimensions = null;
      this.ctx.options = null;
      this.ctx.crosshairs = null;
      this.ctx._zoomPanSelection = null;
      this.ctx.updateHelpers = null;
      this.ctx._toolbar = null;
      this.ctx.localization = null;
      this.ctx._keyboardNavigation = null;
      this.ctx.w.globals.tooltip = null;
    }
    this.clearDomElements({ isUpdating });
  }
  /**
   * @param {any} draw
   */
  killSVG(draw) {
    draw.each(
      /** @this {any} */
      function() {
        this.removeClass("*");
        this.off();
      },
      true
    );
    draw.clear();
  }
  /**
   * @param {{ isUpdating: boolean }} opts
   */
  clearDomElements({ isUpdating }) {
    const domEls = (
      /** @type {any} */
      this.w.dom
    );
    if (Environment.isBrowser()) {
      const elSVG = domEls.Paper.node;
      if (elSVG.parentNode && elSVG.parentNode.parentNode && !isUpdating) {
        elSVG.parentNode.parentNode.style.minHeight = "unset";
      }
      const baseEl = domEls.baseEl;
      if (baseEl) {
        this.ctx.eventList.forEach((event) => {
          baseEl.removeEventListener(event, this.ctx.events.documentEvent);
        });
      }
      if (this.ctx.el !== null) {
        while (this.ctx.el.firstChild) {
          this.ctx.el.removeChild(this.ctx.el.firstChild);
        }
      }
      this.killSVG(domEls.Paper);
      domEls.Paper.remove();
    }
    domEls.elWrap = null;
    domEls.elGraphical = null;
    domEls.elLegendWrap = null;
    domEls.elLegendForeign = null;
    domEls.baseEl = null;
    domEls.elGridRect = null;
    domEls.elGridRectMask = null;
    domEls.elGridRectBarMask = null;
    domEls.elGridRectMarkerMask = null;
    domEls.elForecastMask = null;
    domEls.elNonForecastMask = null;
    domEls.elDefs = null;
  }
}
const ros = /* @__PURE__ */ new WeakMap();
function addResizeListener(el, fn) {
  if (Environment.isSSR()) return;
  let called = false;
  if (el.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
    const elRect = el.getBoundingClientRect();
    if (el.style.display === "none" || elRect.width === 0) {
      called = true;
    }
  }
  const ro = new ResizeObserver((r) => {
    if (called) {
      fn.call(el, r);
    }
    called = true;
  });
  if (el.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
    Array.from(el.children).forEach((c) => ro.observe(c));
  } else {
    ro.observe(el);
  }
  ros.set(fn, ro);
}
function removeResizeListener(el, fn) {
  if (Environment.isSSR()) return;
  const ro = ros.get(fn);
  if (ro) {
    ro.disconnect();
    ros.delete(fn);
  }
}
const apexCSS = `@keyframes opaque {
  0% {
    opacity: 0
  }

  to {
    opacity: 1
  }
}

@keyframes resizeanim {

  0%,
  to {
    opacity: 0
  }
}

.apexcharts-canvas {
  position: relative;
  direction: ltr !important;
  user-select: none;
  /* Focus indicator colour. Themes override below. */
  --apexcharts-focus-color: #008FFB;
}

/* Dark theme & high-contrast: brighter focus colour for sufficient contrast. */
.apexcharts-canvas .apexcharts-theme-dark,
.apexcharts-theme-dark.apexcharts-canvas {
  --apexcharts-focus-color: #FFD500;
}
.apexcharts-canvas.apexcharts-high-contrast,
.apexcharts-high-contrast.apexcharts-canvas {
  --apexcharts-focus-color: #FFFF00;
}

/* Visually-hidden aria-live status region (WCAG 4.1.3 Status Messages). */
.apexcharts-sr-status {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Respect OS-level reduced-motion preference (WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce) {
  .apexcharts-canvas *,
  .apexcharts-canvas *::before,
  .apexcharts-canvas *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

.apexcharts-canvas ::-webkit-scrollbar {
  -webkit-appearance: none;
  width: 6px
}

.apexcharts-canvas ::-webkit-scrollbar-thumb {
  border-radius: 4px;
  background-color: rgba(0, 0, 0, .5);
  box-shadow: 0 0 1px rgba(255, 255, 255, .5);
  -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, .5)
}

.apexcharts-inner {
  position: relative
}

.apexcharts-text tspan {
  font-family: inherit
}

rect.legend-mouseover-inactive,
.legend-mouseover-inactive rect,
.legend-mouseover-inactive path,
.legend-mouseover-inactive circle,
.legend-mouseover-inactive line,
.legend-mouseover-inactive text.apexcharts-yaxis-title-text,
.legend-mouseover-inactive text.apexcharts-yaxis-label {
  transition: .15s ease all;
  opacity: .2
}

.apexcharts-legend-text {
  padding-left: 15px;
  margin-left: -15px;
}

.apexcharts-legend-series[role="button"]:focus {
  outline: 2px solid var(--apexcharts-focus-color, #008FFB);
  outline-offset: 2px;
}

.apexcharts-legend-series[role="button"]:focus:not(:focus-visible) {
  outline: none;
}

.apexcharts-legend-series[role="button"]:focus-visible {
  outline: 2px solid var(--apexcharts-focus-color, #008FFB);
  outline-offset: 2px;
}

.apexcharts-series-collapsed {
  opacity: 0
}

.apexcharts-canvas svg:focus:not(:focus-visible) {
  outline: none;
}

/* Keyboard navigation focus indicator on SVG data elements.
   SVG elements don't support CSS outline, so we use stroke. */
.apexcharts-bar-area.apexcharts-keyboard-focused,
.apexcharts-candlestick-area.apexcharts-keyboard-focused,
.apexcharts-boxPlot-area.apexcharts-keyboard-focused,
.apexcharts-rangebar-area.apexcharts-keyboard-focused,
.apexcharts-pie-area.apexcharts-keyboard-focused,
.apexcharts-heatmap-rect.apexcharts-keyboard-focused,
.apexcharts-treemap-rect.apexcharts-keyboard-focused {
  stroke: var(--apexcharts-focus-color, #008FFB);
  stroke-width: 2;
  stroke-opacity: 1;
}

.apexcharts-tooltip {
  border-radius: 5px;
  box-shadow: 2px 2px 6px -4px #999;
  cursor: default;
  font-size: 14px;
  left: 62px;
  opacity: 0;
  pointer-events: none;
  position: absolute;
  top: 20px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  white-space: nowrap;
  z-index: 12;
  transition: .15s ease all
}

.apexcharts-tooltip.apexcharts-active {
  opacity: 1;
  transition: .15s ease all
}

.apexcharts-tooltip.apexcharts-theme-light {
  border: 1px solid #e3e3e3;
  background: rgba(255, 255, 255, .96)
}

.apexcharts-tooltip.apexcharts-theme-dark {
  color: #fff;
  background: rgba(30, 30, 30, .8)
}

.apexcharts-tooltip * {
  font-family: inherit
}

.apexcharts-tooltip-title {
  padding: 6px;
  font-size: 15px;
  margin-bottom: 4px
}

.apexcharts-tooltip.apexcharts-theme-light .apexcharts-tooltip-title {
  background: #eceff1;
  border-bottom: 1px solid #ddd
}

.apexcharts-tooltip.apexcharts-theme-dark .apexcharts-tooltip-title {
  background: rgba(0, 0, 0, .7);
  border-bottom: 1px solid #333
}

.apexcharts-tooltip-text-goals-value,
.apexcharts-tooltip-text-y-value,
.apexcharts-tooltip-text-z-value {
  display: inline-block;
  margin-left: 5px;
  font-weight: 600
}

.apexcharts-tooltip-text-goals-label:empty,
.apexcharts-tooltip-text-goals-value:empty,
.apexcharts-tooltip-text-y-label:empty,
.apexcharts-tooltip-text-y-value:empty,
.apexcharts-tooltip-text-z-value:empty,
.apexcharts-tooltip-title:empty {
  display: none
}

.apexcharts-tooltip-text-goals-label,
.apexcharts-tooltip-text-goals-value {
  padding: 6px 0 5px
}

.apexcharts-tooltip-goals-group,
.apexcharts-tooltip-text-goals-label,
.apexcharts-tooltip-text-goals-value {
  display: flex
}

.apexcharts-tooltip-text-goals-label:not(:empty),
.apexcharts-tooltip-text-goals-value:not(:empty) {
  margin-top: -6px
}

.apexcharts-tooltip-marker {
  display: inline-block;
  position: relative;
  width: 16px;
  height: 16px;
  font-size: 16px;
  line-height: 16px;
  margin-right: 4px;
  text-align: center;
  vertical-align: middle;
  color: inherit;
}

.apexcharts-tooltip-marker::before {
  content: "";
  display: inline-block;
  width: 100%;
  text-align: center;
  color: currentcolor;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  font-size: 26px;
  font-family: Arial, Helvetica, sans-serif;
  line-height: 14px;
  font-weight: 900;
}

.apexcharts-tooltip-marker[shape="circle"]::before {
  content: "\\25CF";
}

.apexcharts-tooltip-marker[shape="square"]::before,
.apexcharts-tooltip-marker[shape="rect"]::before {
  content: "\\25A0";
  transform: translate(-1px, -2px);
}

.apexcharts-tooltip-marker[shape="line"]::before {
  content: "\\2500";
}

.apexcharts-tooltip-marker[shape="diamond"]::before {
  content: "\\25C6";
  font-size: 28px;
}

.apexcharts-tooltip-marker[shape="triangle"]::before {
  content: "\\25B2";
  font-size: 22px;
}

.apexcharts-tooltip-marker[shape="cross"]::before {
  content: "\\2715";
  font-size: 18px;
}

.apexcharts-tooltip-marker[shape="plus"]::before {
  content: "\\2715";
  transform: rotate(45deg) translate(-1px, -1px);
  font-size: 18px;
}

.apexcharts-tooltip-marker[shape="star"]::before {
  content: "\\2605";
  font-size: 18px;
}

.apexcharts-tooltip-marker[shape="sparkle"]::before {
  content: "\\2726";
  font-size: 20px;
}

.apexcharts-tooltip-series-group {
  padding: 0 10px;
  display: none;
  text-align: left;
  justify-content: left;
  align-items: center
}

.apexcharts-tooltip-series-group.apexcharts-active .apexcharts-tooltip-marker {
  opacity: 1
}

.apexcharts-tooltip-series-group.apexcharts-active,
.apexcharts-tooltip-series-group:last-child {
  padding-bottom: 4px
}

.apexcharts-tooltip-y-group {
  padding: 6px 0 5px
}

.apexcharts-custom-tooltip,
.apexcharts-tooltip-box {
  padding: 4px 8px
}

.apexcharts-tooltip-boxPlot {
  display: flex;
  flex-direction: column-reverse
}

.apexcharts-tooltip-box>div {
  margin: 4px 0
}

.apexcharts-tooltip-box span.value {
  font-weight: 700
}

.apexcharts-tooltip-rangebar {
  padding: 5px 8px
}

.apexcharts-tooltip-rangebar .category {
  font-weight: 600;
  color: #777
}

.apexcharts-tooltip-rangebar .series-name {
  font-weight: 700;
  display: block;
  margin-bottom: 5px
}

.apexcharts-xaxistooltip,
.apexcharts-yaxistooltip {
  opacity: 0;
  pointer-events: none;
  color: #373d3f;
  font-size: 13px;
  text-align: center;
  border-radius: 2px;
  position: absolute;
  z-index: 10;
  background: #eceff1;
  border: 1px solid #90a4ae
}

.apexcharts-xaxistooltip {
  padding: 9px 10px;
  transition: .15s ease all
}

.apexcharts-xaxistooltip.apexcharts-theme-dark {
  background: rgba(0, 0, 0, .7);
  border: 1px solid rgba(0, 0, 0, .5);
  color: #fff
}

.apexcharts-xaxistooltip:after,
.apexcharts-xaxistooltip:before {
  left: 50%;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none
}

.apexcharts-xaxistooltip:after {
  border-color: transparent;
  border-width: 6px;
  margin-left: -6px
}

.apexcharts-xaxistooltip:before {
  border-color: transparent;
  border-width: 7px;
  margin-left: -7px
}

.apexcharts-xaxistooltip-bottom:after,
.apexcharts-xaxistooltip-bottom:before {
  bottom: 100%
}

.apexcharts-xaxistooltip-top:after,
.apexcharts-xaxistooltip-top:before {
  top: 100%
}

.apexcharts-xaxistooltip-bottom:after {
  border-bottom-color: #eceff1
}

.apexcharts-xaxistooltip-bottom:before {
  border-bottom-color: #90a4ae
}

.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:after,
.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:before {
  border-bottom-color: rgba(0, 0, 0, .5)
}

.apexcharts-xaxistooltip-top:after {
  border-top-color: #eceff1
}

.apexcharts-xaxistooltip-top:before {
  border-top-color: #90a4ae
}

.apexcharts-xaxistooltip-top.apexcharts-theme-dark:after,
.apexcharts-xaxistooltip-top.apexcharts-theme-dark:before {
  border-top-color: rgba(0, 0, 0, .5)
}

.apexcharts-xaxistooltip.apexcharts-active {
  opacity: 1;
  transition: .15s ease all
}

.apexcharts-yaxistooltip {
  padding: 4px 10px
}

.apexcharts-yaxistooltip.apexcharts-theme-dark {
  background: rgba(0, 0, 0, .7);
  border: 1px solid rgba(0, 0, 0, .5);
  color: #fff
}

.apexcharts-yaxistooltip:after,
.apexcharts-yaxistooltip:before {
  top: 50%;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none
}

.apexcharts-yaxistooltip:after {
  border-color: transparent;
  border-width: 6px;
  margin-top: -6px
}

.apexcharts-yaxistooltip:before {
  border-color: transparent;
  border-width: 7px;
  margin-top: -7px
}

.apexcharts-yaxistooltip-left:after,
.apexcharts-yaxistooltip-left:before {
  left: 100%
}

.apexcharts-yaxistooltip-right:after,
.apexcharts-yaxistooltip-right:before {
  right: 100%
}

.apexcharts-yaxistooltip-left:after {
  border-left-color: #eceff1
}

.apexcharts-yaxistooltip-left:before {
  border-left-color: #90a4ae
}

.apexcharts-yaxistooltip-left.apexcharts-theme-dark:after,
.apexcharts-yaxistooltip-left.apexcharts-theme-dark:before {
  border-left-color: rgba(0, 0, 0, .5)
}

.apexcharts-yaxistooltip-right:after {
  border-right-color: #eceff1
}

.apexcharts-yaxistooltip-right:before {
  border-right-color: #90a4ae
}

.apexcharts-yaxistooltip-right.apexcharts-theme-dark:after,
.apexcharts-yaxistooltip-right.apexcharts-theme-dark:before {
  border-right-color: rgba(0, 0, 0, .5)
}

.apexcharts-yaxistooltip.apexcharts-active {
  opacity: 1
}

.apexcharts-yaxistooltip-hidden {
  display: none
}

.apexcharts-xcrosshairs,
.apexcharts-ycrosshairs {
  pointer-events: none;
  opacity: 0;
  transition: .15s ease all
}

.apexcharts-xcrosshairs.apexcharts-active,
.apexcharts-ycrosshairs.apexcharts-active {
  opacity: 1;
  transition: .15s ease all
}

.apexcharts-ycrosshairs-hidden {
  opacity: 0
}

.apexcharts-selection-rect {
  cursor: move
}

.svg_select_shape {
  stroke-width: 1;
  stroke-dasharray: 10 10;
  stroke: black;
  stroke-opacity: 0.1;
  pointer-events: none;
  fill: none;
}

.svg_select_handle {
  stroke-width: 3;
  stroke: black;
  fill: none;
}

.svg_select_handle_r {
  cursor: e-resize;
}

.svg_select_handle_l {
  cursor: w-resize;
}

.apexcharts-svg.apexcharts-zoomable.hovering-zoom {
  cursor: crosshair
}

.apexcharts-svg.apexcharts-zoomable.hovering-pan {
  cursor: move
}

.apexcharts-menu-icon,
.apexcharts-pan-icon,
.apexcharts-reset-icon,
.apexcharts-selection-icon,
.apexcharts-toolbar-custom-icon,
.apexcharts-zoom-icon,
.apexcharts-zoomin-icon,
.apexcharts-zoomout-icon {
  cursor: pointer;
  /* WCAG 2.5.8 Target Size (Minimum): 24×24 CSS px hit target. */
  width: 24px;
  height: 24px;
  line-height: 24px;
  color: #6e8192;
  text-align: center;
  /* Reset native <button> chrome — these are styled via SVG icons. */
  padding: 0;
  margin: 0;
  background: transparent;
  border: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.apexcharts-menu-icon svg,
.apexcharts-reset-icon svg,
.apexcharts-zoom-icon svg,
.apexcharts-zoomin-icon svg,
.apexcharts-zoomout-icon svg {
  fill: #6e8192
}

.apexcharts-selection-icon svg {
  fill: #444;
  transform: scale(.76)
}

.apexcharts-theme-dark .apexcharts-menu-icon svg,
.apexcharts-theme-dark .apexcharts-pan-icon svg,
.apexcharts-theme-dark .apexcharts-reset-icon svg,
.apexcharts-theme-dark .apexcharts-selection-icon svg,
.apexcharts-theme-dark .apexcharts-toolbar-custom-icon svg,
.apexcharts-theme-dark .apexcharts-zoom-icon svg,
.apexcharts-theme-dark .apexcharts-zoomin-icon svg,
.apexcharts-theme-dark .apexcharts-zoomout-icon svg {
  fill: #f3f4f5
}

.apexcharts-canvas .apexcharts-reset-zoom-icon.apexcharts-selected svg,
.apexcharts-canvas .apexcharts-selection-icon.apexcharts-selected svg,
.apexcharts-canvas .apexcharts-zoom-icon.apexcharts-selected svg {
  fill: #008ffb
}

.apexcharts-theme-light .apexcharts-menu-icon:hover svg,
.apexcharts-theme-light .apexcharts-reset-icon:hover svg,
.apexcharts-theme-light .apexcharts-selection-icon:not(.apexcharts-selected):hover svg,
.apexcharts-theme-light .apexcharts-zoom-icon:not(.apexcharts-selected):hover svg,
.apexcharts-theme-light .apexcharts-zoomin-icon:hover svg,
.apexcharts-theme-light .apexcharts-zoomout-icon:hover svg {
  fill: #333
}

.apexcharts-menu-icon,
.apexcharts-selection-icon {
  position: relative
}

.apexcharts-reset-icon {
  margin-left: 5px
}

.apexcharts-menu-icon,
.apexcharts-reset-icon,
.apexcharts-zoom-icon {
  transform: scale(.85)
}

.apexcharts-zoomin-icon,
.apexcharts-zoomout-icon {
  transform: scale(.7)
}

.apexcharts-zoomout-icon {
  margin-right: 3px
}

.apexcharts-pan-icon {
  transform: scale(.62);
  position: relative;
  left: 1px;
  top: 0
}

.apexcharts-pan-icon svg {
  fill: #fff;
  stroke: #6e8192;
  stroke-width: 2
}

.apexcharts-pan-icon.apexcharts-selected svg {
  stroke: #008ffb
}

.apexcharts-pan-icon:not(.apexcharts-selected):hover svg {
  stroke: #333
}

.apexcharts-toolbar {
  position: absolute;
  z-index: 11;
  max-width: 176px;
  text-align: right;
  border-radius: 3px;
  padding: 0 6px 2px;
  display: flex;
  justify-content: space-between;
  align-items: center
}

.apexcharts-menu {
  background: #fff;
  position: absolute;
  top: 100%;
  border: 1px solid #ddd;
  border-radius: 3px;
  padding: 3px;
  right: 10px;
  opacity: 0;
  min-width: 110px;
  transition: .15s ease all;
  pointer-events: none
}

.apexcharts-menu.apexcharts-menu-open {
  opacity: 1;
  pointer-events: all;
  transition: .15s ease all
}

.apexcharts-menu-item {
  padding: 6px 7px;
  font-size: 12px;
  cursor: pointer
}

.apexcharts-theme-light .apexcharts-menu-item:hover {
  background: #eee
}

.apexcharts-theme-dark .apexcharts-menu {
  background: rgba(0, 0, 0, .7);
  color: #fff
}

@media screen and (min-width:768px) {
  .apexcharts-canvas:hover .apexcharts-toolbar {
    opacity: 1
  }
}

/* Toolbar keyboard accessibility: show toolbar when any button inside it is focused */
.apexcharts-toolbar:focus-within {
  opacity: 1
}

/* Focus indicator for toolbar icon buttons */
.apexcharts-menu-icon:focus-visible,
.apexcharts-pan-icon:focus-visible,
.apexcharts-reset-icon:focus-visible,
.apexcharts-selection-icon:focus-visible,
.apexcharts-toolbar-custom-icon:focus-visible,
.apexcharts-zoom-icon:focus-visible,
.apexcharts-zoomin-icon:focus-visible,
.apexcharts-zoomout-icon:focus-visible {
  outline: 2px solid var(--apexcharts-focus-color, #008FFB);
  outline-offset: 2px;
  border-radius: 2px
}

/* Focus indicator for hamburger menu items */
.apexcharts-menu-item:focus-visible {
  outline: 2px solid var(--apexcharts-focus-color, #008FFB);
  outline-offset: -2px;
  background: #eee
}

.apexcharts-canvas .apexcharts-element-hidden,
.apexcharts-datalabel.apexcharts-element-hidden,
.apexcharts-hide .apexcharts-series-points {
  opacity: 0;
}

.apexcharts-hidden-element-shown {
  opacity: 1;
  transition: 0.25s ease all;
}

.apexcharts-datalabel,
.apexcharts-datalabel-label,
.apexcharts-datalabel-value,
.apexcharts-datalabels,
.apexcharts-pie-label {
  cursor: default;
  pointer-events: none
}

.apexcharts-pie-label-delay {
  opacity: 0;
  animation-name: opaque;
  animation-duration: .3s;
  animation-fill-mode: forwards;
  animation-timing-function: ease
}

.apexcharts-radialbar-label {
  cursor: pointer;
}

.apexcharts-annotation-rect,
.apexcharts-area-series .apexcharts-area,
.apexcharts-gridline,
.apexcharts-line,
.apexcharts-point-annotation-label,
.apexcharts-radar-series path:not(.apexcharts-marker),
.apexcharts-radar-series polygon,
.apexcharts-toolbar svg,
.apexcharts-tooltip .apexcharts-marker,
.apexcharts-xaxis-annotation-label,
.apexcharts-yaxis-annotation-label,
.apexcharts-zoom-rect,
.no-pointer-events {
  pointer-events: none
}

.apexcharts-tooltip-active .apexcharts-marker {
  transition: .15s ease all
}

.apexcharts-radar-series .apexcharts-yaxis {
  pointer-events: none;
}

.resize-triggers {
  animation: 1ms resizeanim;
  visibility: hidden;
  opacity: 0;
  height: 100%;
  width: 100%;
  overflow: hidden
}

.contract-trigger:before,
.resize-triggers,
.resize-triggers>div {
  content: " ";
  display: block;
  position: absolute;
  top: 0;
  left: 0
}

.resize-triggers>div {
  height: 100%;
  width: 100%;
  background: #eee;
  overflow: auto
}

.contract-trigger:before {
  overflow: hidden;
  width: 200%;
  height: 200%
}

.apexcharts-bar-goals-markers {
  pointer-events: none
}

.apexcharts-bar-shadows {
  pointer-events: none
}

.apexcharts-rangebar-goals-markers {
  pointer-events: none
}

.apexcharts-disable-transitions * {
  transition: none !important;
}`;
class ApexCharts {
  /**
   * Creates a new ApexCharts instance.
   *
   * @param {HTMLElement} el - The DOM element to render the chart into.
   * @param {ApexOptions} opts - Chart configuration options.
   */
  constructor(el, opts) {
    // Module properties set dynamically by InitCtxVariables.initModules().
    // Declared as typed class fields so @ts-check resolves them throughout the
    // class body without errors. Each field typed as `any` since the modules are
    // plain objects whose specific shapes are not yet typed.
    /** @type {any} */
    __publicField(this, "core");
    /** @type {any} */
    __publicField(this, "responsive");
    /** @type {any} */
    __publicField(this, "axes");
    /** @type {any} */
    __publicField(this, "grid");
    /** @type {any} */
    __publicField(this, "graphics");
    /** @type {any} */
    __publicField(this, "coreUtils");
    /** @type {any} */
    __publicField(this, "crosshairs");
    /** @type {any} */
    __publicField(this, "events");
    /** @type {any} */
    __publicField(this, "fill");
    /** @type {any} */
    __publicField(this, "localization");
    /** @type {any} */
    __publicField(this, "options");
    /** @type {any} */
    __publicField(this, "series");
    /** @type {any} */
    __publicField(this, "theme");
    /** @type {any} */
    __publicField(this, "formatters");
    /** @type {any} */
    __publicField(this, "titleSubtitle");
    /** @type {any} */
    __publicField(this, "dimensions");
    /** @type {any} */
    __publicField(this, "updateHelpers");
    /** @type {any} */
    __publicField(this, "tooltip");
    /** @type {any} */
    __publicField(this, "data");
    /** @type {any} */
    __publicField(this, "animations");
    /** @type {any} */
    __publicField(this, "exports");
    /** @type {any} */
    __publicField(this, "legend");
    /** @type {any} */
    __publicField(this, "toolbar");
    /** @type {any} */
    __publicField(this, "zoomPanSelection");
    /** @type {any} */
    __publicField(this, "keyboardNavigation");
    /** @type {any} */
    __publicField(this, "annotations");
    /** @type {any} */
    __publicField(this, "timeScale");
    /** @type {any} */
    __publicField(this, "_keyboardNavigation");
    /** @type {any} */
    __publicField(this, "windowResizeHandler");
    /** @type {any} */
    __publicField(this, "parentResizeHandler");
    /** @type {string[]} */
    __publicField(this, "publicMethods", []);
    /** @type {string[]} */
    __publicField(this, "eventList", []);
    /** @type {any} */
    __publicField(this, "config");
    this.opts = opts;
    this.ctx = this;
    this.w = new Base(opts).init();
    this.el = el;
    this.w.globals.cuid = Utils$1.randomId();
    this.w.globals.chartID = this.w.config.chart.id ? Utils$1.escapeString(this.w.config.chart.id) : this.w.globals.cuid;
    const initCtx = new InitCtxVariables(this);
    initCtx.initModules();
    this.lastUpdateOptions = null;
    this.create = this.create.bind(this);
    if (Environment.isBrowser()) {
      this.windowResizeHandler = this._windowResizeHandler.bind(this);
      this.parentResizeHandler = this._parentResizeCallback.bind(this);
    }
  }
  /**
   * Renders the chart. Must be called once after construction.
   *
   * @returns {Promise<ApexCharts>} Resolves with the chart instance after mount.
   */
  render() {
    var _a, _b;
    if (!((_b = (_a = this.w) == null ? void 0 : _a.config) == null ? void 0 : _b.chart)) {
      return Promise.reject(
        new Error(
          "ApexCharts: chart configuration is missing or invalid. Ensure the options object includes a `chart` property."
        )
      );
    }
    return new Promise((resolve, reject) => {
      var _a2;
      if (Utils$1.elementExists(this.el)) {
        if (typeof Apex._chartInstances === "undefined") {
          Apex._chartInstances = [];
        }
        if (this.w.config.chart.id) {
          Apex._chartInstances.push({
            id: this.w.globals.chartID,
            group: this.w.config.chart.group,
            chart: this
          });
        }
        this.setLocale(this.w.config.chart.defaultLocale);
        const beforeMount = this.w.config.chart.events.beforeMount;
        if (typeof beforeMount === "function") {
          beforeMount(this, this.w);
        }
        this.events.fireEvent("beforeMount", [this, this.w]);
        if (Environment.isBrowser()) {
          window.addEventListener("resize", this.windowResizeHandler);
          addResizeListener(
            /** @type {HTMLElement} */
            this.el.parentNode,
            this.parentResizeHandler
          );
          const rootNode = (
            /** @type {any} */
            this.el.getRootNode && this.el.getRootNode()
          );
          const inShadowRoot = Utils$1.is("ShadowRoot", rootNode);
          const doc = this.el.ownerDocument;
          let css = inShadowRoot ? rootNode.getElementById("apexcharts-css") : doc.getElementById("apexcharts-css");
          if (!css) {
            css = BrowserAPIs.createElementNS(
              "http://www.w3.org/1999/xhtml",
              "style"
            );
            css.id = "apexcharts-css";
            css.textContent = apexCSS;
            const nonce = ((_a2 = this.opts.chart) == null ? void 0 : _a2.nonce) || this.w.config.chart.nonce;
            if (nonce) {
              css.setAttribute("nonce", nonce);
            }
            if (inShadowRoot) {
              rootNode.prepend(css);
            } else if (this.w.config.chart.injectStyleSheet !== false) {
              doc.head.appendChild(css);
            }
          }
        }
        const graphData = this.create(this.w.config.series, {});
        if (!graphData) return resolve(this);
        this.mount(graphData).then(() => {
          if (typeof this.w.config.chart.events.mounted === "function") {
            this.w.config.chart.events.mounted(this, this.w);
          }
          this.events.fireEvent("mounted", [this, this.w]);
          resolve(graphData);
        }).catch((e) => {
          var _a3, _b2;
          const enriched = e instanceof Error ? e : new Error(String(e));
          const err = (
            /** @type {any} */
            enriched
          );
          err.chartId = (_b2 = (_a3 = this.w) == null ? void 0 : _a3.globals) == null ? void 0 : _b2.chartID;
          err.el = this.el;
          reject(enriched);
        });
      } else {
        reject(new Error("Element not found"));
      }
    });
  }
  /**
   * @param {any[]} ser
   * @param {object} opts
   */
  create(ser, opts) {
    var _a;
    const w = this.w;
    if (!this.core) {
      const initCtx = new InitCtxVariables(this);
      initCtx.initModules();
    }
    const gl = this.w.globals;
    gl.noData = false;
    gl.animationEnded = false;
    if (!Utils$1.elementExists(this.el)) {
      gl.animationEnded = true;
      return null;
    }
    this.responsive.checkResponsiveConfig(opts);
    if (w.config.xaxis.convertedCatToNumeric) {
      const defaults = new Defaults(w.config);
      defaults.convertCatToNumericXaxis(w.config, this.ctx);
    }
    this.core.setupElements();
    if (w.config.chart.type === "treemap") {
      w.config.grid.show = false;
      w.config.yaxis[0].show = false;
    }
    if (gl.svgWidth === 0) {
      gl.animationEnded = true;
      return null;
    }
    let series = ser;
    ser.forEach((s, realIndex) => {
      if (s.hidden) {
        series = this.legend.legendHelpers.getSeriesAfterCollapsing({
          realIndex
        });
      }
    });
    const combo = CoreUtils.checkComboSeries(series, w.config.chart.type);
    gl.comboCharts = combo.comboCharts;
    gl.comboBarCount = combo.comboBarCount;
    const allSeriesAreEmpty = series.every((s) => s.data && s.data.length === 0);
    if (series.length === 0 || allSeriesAreEmpty && gl.collapsedSeries.length < 1) {
      this.series.handleNoData();
    }
    if (Environment.isBrowser()) {
      this.events.setupEventHandlers();
    }
    const parsedState = this.data.parseData(series);
    this._writeParsedSeriesData(parsedState.seriesData);
    this._writeParsedRangeData(parsedState.rangeData);
    this._writeParsedCandleData(parsedState.candleData);
    this._writeParsedLabelData(parsedState.labelData);
    this._writeParsedAxisFlags(parsedState.axisFlags);
    this.theme.init();
    const markers = new Markers(this.w, this);
    markers.setGlobalMarkerSize();
    this.formatters.setLabelFormatters();
    this.titleSubtitle.draw();
    if (!gl.noData || gl.collapsedSeries.length === w.seriesData.series.length || w.config.legend.showForSingleSeries) {
      (_a = this.legend) == null ? void 0 : _a.init();
    }
    this.series.hasAllSeriesEqualX();
    if (gl.axisCharts) {
      this.core.coreCalculations();
      if (w.config.xaxis.type !== "category") {
        this.formatters.setLabelFormatters();
      }
      if (this.ctx.toolbar) {
        this.ctx.toolbar.minX = w.globals.minX;
        this.ctx.toolbar.maxX = w.globals.maxX;
      }
    }
    this.formatters.heatmapLabelFormatters();
    const coreUtils = new CoreUtils(this.w);
    coreUtils.getLargestMarkerSize();
    const layoutState = this.dimensions.plotCoords();
    this._writeLayoutCoords(layoutState.layout);
    const xyRatios = this.core.xySettings();
    this.grid.createGridMask();
    const elGraph = this.core.plotChartType(series, xyRatios);
    const dataLabels = new DataLabels(this.w, this);
    dataLabels.bringForward();
    if (w.config.dataLabels.background.enabled) {
      dataLabels.dataLabelsBackground();
    }
    this.core.shiftGraphPosition();
    if (w.globals.dataPoints > 50) {
      w.dom.elWrap.classList.add("apexcharts-disable-transitions");
    }
    const dim = {
      plot: {
        left: w.layout.translateX,
        top: w.layout.translateY,
        width: w.layout.gridWidth,
        height: w.layout.gridHeight
      }
    };
    return {
      elGraph,
      xyRatios,
      dimensions: dim
    };
  }
  /**
   * @param {any} graphData
   */
  mount(graphData = null) {
    const me = this;
    const w = me.w;
    return new Promise((resolve, reject) => {
      var _a, _b, _c, _d, _e, _f, _g, _h, _i;
      if (me.el === null) {
        return reject(
          new Error("Not enough data to display or target element not found")
        );
      } else if (graphData === null || w.globals.allSeriesCollapsed) {
        me.series.handleNoData();
      }
      me.grid = new Grid(me.w, me);
      const elgrid = me.grid.drawGrid();
      const AnnotationsCtor = InitCtxVariables._featureRegistry.get("annotations");
      me.annotations = AnnotationsCtor ? new AnnotationsCtor(me.w, {
        theme: me.theme,
        timeScale: me.timeScale
      }) : null;
      (_a = me.annotations) == null ? void 0 : _a.drawImageAnnos();
      (_b = me.annotations) == null ? void 0 : _b.drawTextAnnos();
      if (w.config.grid.position === "back") {
        if (elgrid) {
          w.dom.elGraphical.add(elgrid.el);
        }
        if ((_c = elgrid == null ? void 0 : elgrid.elGridBorders) == null ? void 0 : _c.node) {
          w.dom.elGraphical.add(elgrid.elGridBorders);
        }
      }
      if (Array.isArray(graphData.elGraph)) {
        for (let g = 0; g < graphData.elGraph.length; g++) {
          w.dom.elGraphical.add(graphData.elGraph[g]);
        }
      } else {
        w.dom.elGraphical.add(graphData.elGraph);
      }
      if (w.config.grid.position === "front") {
        if (elgrid) {
          w.dom.elGraphical.add(elgrid.el);
        }
        if ((_d = elgrid == null ? void 0 : elgrid.elGridBorders) == null ? void 0 : _d.node) {
          w.dom.elGraphical.add(elgrid.elGridBorders);
        }
      }
      if (w.config.xaxis.crosshairs.position === "front") {
        me.crosshairs.drawXCrosshairs();
      }
      if (w.config.yaxis[0].crosshairs.position === "front") {
        me.crosshairs.drawYCrosshairs();
      }
      if (w.config.chart.type !== "treemap") {
        me.axes.drawAxis(w.config.chart.type, elgrid);
      }
      const xAxis = new XAxis(this.w, this.ctx, elgrid);
      const yaxis = new YAxis(
        this.w,
        { theme: this.theme, timeScale: this.timeScale },
        elgrid
      );
      if (elgrid !== null) {
        xAxis.xAxisLabelCorrections();
        yaxis.setYAxisTextAlignments();
        w.config.yaxis.map((yaxe, index) => {
          if (w.globals.ignoreYAxisIndexes.indexOf(index) === -1) {
            yaxis.yAxisTitleRotate(index, yaxe.opposite);
          }
        });
      }
      (_e = me.annotations) == null ? void 0 : _e.drawAxesAnnotations();
      if (!w.globals.noData) {
        if (Environment.isBrowser() && w.config.tooltip.enabled && !w.globals.noData) {
          (_f = me.w.globals.tooltip) == null ? void 0 : _f.drawTooltip(graphData.xyRatios);
        }
        if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled && w.config.chart.accessibility.keyboard.navigation.enabled) {
          (_g = me.keyboardNavigation) == null ? void 0 : _g.init();
        }
        if (Environment.isBrowser() && w.globals.axisCharts && (w.axisFlags.isXNumeric || /** @type {Record<string,any>} */
        w.config.xaxis.convertedCatToNumeric || w.axisFlags.isRangeBar)) {
          if (w.config.chart.zoom.enabled || w.config.chart.selection && w.config.chart.selection.enabled || // @ts-ignore — chart.pan is an internal toolbar config property
          w.config.chart.pan && w.config.chart.pan.enabled) {
            (_h = me.zoomPanSelection) == null ? void 0 : _h.init({
              xyRatios: graphData.xyRatios
            });
          }
        } else {
          const tools = w.config.chart.toolbar.tools;
          const toolsArr = [
            "zoom",
            "zoomin",
            "zoomout",
            "selection",
            "pan",
            "reset"
          ];
          toolsArr.forEach((t) => {
            tools[t] = false;
          });
        }
        if (w.config.chart.toolbar.show && !w.globals.allSeriesCollapsed) {
          (_i = me.toolbar) == null ? void 0 : _i.createToolbar();
        }
      }
      if (w.globals.memory.methodsToExec.length > 0) {
        w.globals.memory.methodsToExec.forEach((fn) => {
          fn.method(fn.params, false, fn.context);
        });
      }
      if (!w.globals.axisCharts && !w.globals.noData) {
        me.core.resizeNonAxisCharts();
      }
      resolve(me);
    });
  }
  /**
   * Destroys the chart instance, removes all DOM elements and event listeners.
   * After calling this, the instance should not be used again.
   */
  destroy() {
    if (Environment.isBrowser()) {
      window.removeEventListener("resize", this.windowResizeHandler);
      removeResizeListener(
        /** @type {Element} */
        this.el.parentNode,
        this.parentResizeHandler
      );
    }
    const chartID = this.w.config.chart.id;
    if (chartID) {
      Apex._chartInstances.forEach(
        (c, i) => {
          if (c.id === Utils$1.escapeString(chartID)) {
            Apex._chartInstances.splice(i, 1);
          }
        }
      );
    }
    if (this._keyboardNavigation) {
      this._keyboardNavigation.destroy();
    }
    new Destroy(this.ctx).clear({ isUpdating: false });
  }
  /**
   * Merges new options into the existing config and re-renders the chart.
   *
   * @param {ApexOptions} options - Partial config object merged with the existing config.
   * @param {boolean} [redraw=false] - When true, redraws the chart from scratch instead of animating from previous paths.
   * @param {boolean} [animate=true] - Whether to animate the update.
   * @param {boolean} [updateSyncedCharts=true] - Whether to propagate the update to charts in the same group.
   * @param {boolean} [overwriteInitialConfig=true] - When true, replaces the stored initial config used by resetSeries().
   * @returns {Promise<ApexCharts>} Resolves with the chart instance after re-render.
   */
  updateOptions(options2, redraw = false, animate = true, updateSyncedCharts = true, overwriteInitialConfig = true) {
    const w = this.w;
    w.interact.selection = void 0;
    if (this.lastUpdateOptions) {
      if (Utils$1.shallowEqual(this.lastUpdateOptions, options2)) {
        return Promise.resolve(this);
      }
      if (options2.series && this.lastUpdateOptions.series) {
        if (JSON.stringify(this.lastUpdateOptions.series) === JSON.stringify(options2.series)) {
          const optionsWithoutSeries = __spreadValues({}, options2);
          const lastWithoutSeries = __spreadValues({}, this.lastUpdateOptions);
          delete optionsWithoutSeries.series;
          delete lastWithoutSeries.series;
          if (Utils$1.shallowEqual(optionsWithoutSeries, lastWithoutSeries)) {
            return Promise.resolve(this);
          }
        }
      }
    }
    if (options2.series) {
      this.data.resetParsingFlags();
      this.series.resetSeries(false, true, false);
      if (options2.series.length && options2.series[0].data) {
        options2.series = options2.series.map(
          (s, i) => {
            return this.updateHelpers._extendSeries(s, i);
          }
        );
      }
      this.updateHelpers.revertDefaultAxisMinMax();
    }
    if (options2.xaxis) {
      options2 = this.updateHelpers.forceXAxisUpdate(options2);
    }
    if (options2.yaxis) {
      options2 = this.updateHelpers.forceYAxisUpdate(options2);
    }
    if (w.globals.collapsedSeriesIndices.length > 0) {
      this.series.clearPreviousPaths();
    }
    if (options2.theme) {
      options2 = this.theme.updateThemeOptions(options2);
    }
    return this.updateHelpers._updateOptions(
      options2,
      redraw,
      animate,
      updateSyncedCharts,
      overwriteInitialConfig
    );
  }
  /**
   * Replaces the chart's series data and re-renders.
   *
   * @param {ApexAxisChartSeries | ApexNonAxisChartSeries} [newSeries=[]] - The replacement series array.
   * @param {boolean} [animate=true] - Whether to animate the update.
   * @param {boolean} [overwriteInitialSeries=true] - When true, replaces the stored initial series used by resetSeries().
   * @returns {Promise<ApexCharts>} Resolves with the chart instance after re-render.
   */
  updateSeries(newSeries = [], animate = true, overwriteInitialSeries = true) {
    this.data.resetParsingFlags();
    this.series.resetSeries(false);
    this.updateHelpers.revertDefaultAxisMinMax();
    return this.updateHelpers._updateSeries(
      newSeries,
      animate,
      overwriteInitialSeries
    );
  }
  /**
   * Appends a new series to the existing series array and re-renders.
   *
   * @param {ApexAxisChartSeries[0] | ApexNonAxisChartSeries} newSerie - The series object to append.
   * @param {boolean} [animate=true] - Whether to animate the update.
   * @param {boolean} [overwriteInitialSeries=true] - When true, replaces the stored initial series used by resetSeries().
   * @returns {Promise<ApexCharts>} Resolves with the chart instance after re-render.
   */
  appendSeries(newSerie, animate = true, overwriteInitialSeries = true) {
    this.data.resetParsingFlags();
    const newSeries = this.w.config.series.slice();
    newSeries.push(
      /** @type {any} */
      newSerie
    );
    this.series.resetSeries(false);
    this.updateHelpers.revertDefaultAxisMinMax();
    return this.updateHelpers._updateSeries(
      newSeries,
      animate,
      overwriteInitialSeries
    );
  }
  /**
   * Appends data points to existing series without replacing them.
   * Each element of `newData` corresponds to the series at the same index.
   *
   * @param {Array<{ data: any[] }>} newData - Data to append, in the same shape as series[].data.
   * @param {boolean} [overwriteInitialSeries=true] - When true, updates the stored initial series used by resetSeries().
   * @returns {Promise<ApexCharts>} Resolves with the chart instance after re-render.
   */
  appendData(newData, overwriteInitialSeries = true) {
    const me = this;
    me.data.resetParsingFlags();
    me.w.globals.dataChanged = true;
    me.series.getPreviousPaths();
    const newSeries = me.w.config.series.slice();
    for (let i = 0; i < newSeries.length; i++) {
      if (newData[i] !== null && typeof newData[i] !== "undefined") {
        const srcSerie = (
          /** @type {any} */
          newData[i]
        );
        const dstSerie = (
          /** @type {any} */
          newSeries[i]
        );
        for (let j = 0; j < srcSerie.data.length; j++) {
          dstSerie.data.push(srcSerie.data[j]);
        }
      }
    }
    me.w.config.series = newSeries;
    if (overwriteInitialSeries) {
      me.w.globals.initialSeries = Utils$1.clone(me.w.config.series);
    }
    return this.update();
  }
  /**
   * @param {object} [options]
   */
  update(options2) {
    return new Promise((resolve, reject) => {
      if (this.lastUpdateOptions && JSON.stringify(this.lastUpdateOptions) === JSON.stringify(options2)) {
        return resolve(this);
      }
      this.lastUpdateOptions = Utils$1.clone(options2);
      new Destroy(this.ctx).clear({ isUpdating: true });
      const graphData = this.create(this.w.config.series, options2 != null ? options2 : {});
      if (!graphData) return resolve(this);
      this.mount(graphData).then(() => {
        if (typeof this.w.config.chart.events.updated === "function") {
          this.w.config.chart.events.updated(this, this.w);
        }
        this.events.fireEvent("updated", [this, this.w]);
        this.w.globals.isDirty = true;
        resolve(this);
      }).catch((e) => {
        reject(e);
      });
    });
  }
  /**
   * Fast update path for data-only series changes.
   *
   * Skips rebuilding grid, axes, dimensions, legend, annotations, tooltip DOM,
   * and toolbar. Only recalculates scales and replots the series paths.
   * Called automatically by _updateSeries() when the fast path is eligible.
   *
   * @param {boolean} animate - Whether to animate the update.
   * @returns {Promise<ApexCharts>} Resolves with the chart instance.
   */
  fastUpdate(animate) {
    return new Promise((resolve, reject) => {
      var _a;
      try {
        const w = this.w;
        const gl = w.globals;
        gl.shouldAnimate = animate;
        gl.dataChanged = true;
        gl.animationEnded = false;
        PerformanceCache.invalidateSelectors(w);
        const gl2 = w.globals;
        gl2.maxY = -Number.MAX_VALUE;
        gl2.minY = Number.MIN_VALUE;
        gl2.minYArr = [];
        gl2.maxYArr = [];
        gl2.maxX = -Number.MAX_VALUE;
        gl2.minX = Number.MAX_VALUE;
        gl2.initialMaxX = -Number.MAX_VALUE;
        gl2.initialMinX = Number.MAX_VALUE;
        gl2.yAxisScale = [];
        gl2.xAxisScale = null;
        gl2.xAxisTicksPositions = [];
        gl2.xRange = 0;
        gl2.yRange = [];
        gl2.zRange = 0;
        gl2.xTickAmount = 0;
        gl2.multiAxisTickAmount = 0;
        gl2.pointsArray = [];
        gl2.dataLabelsRects = [];
        gl2.lastDrawnDataLabelsIndexes = [];
        gl2.textRectsCache = /* @__PURE__ */ new Map();
        gl2.domCache = /* @__PURE__ */ new Map();
        gl2.cachedSelectors = {};
        gl2.disableZoomIn = false;
        gl2.disableZoomOut = false;
        if (gl.axisCharts) {
          this.core.coreCalculations();
          if (w.config.xaxis.type !== "category") {
            this.formatters.setLabelFormatters();
          }
        }
        const xyRatios = this.core.xySettings();
        const innerEl = w.dom.elGraphical.node;
        const toRemove = innerEl.querySelectorAll(
          ".apexcharts-series, .apexcharts-datalabels, .apexcharts-datalabels-background"
        );
        toRemove.forEach(
          (el) => {
            var _a2;
            return (_a2 = el.parentNode) == null ? void 0 : _a2.removeChild(el);
          }
        );
        const elGraph = this.core.plotChartType(w.config.series, xyRatios);
        const gridEl = innerEl.querySelector(".apexcharts-grid");
        const graphs = Array.isArray(elGraph) ? elGraph : [elGraph];
        if (gridEl && w.config.grid.position === "front") {
          graphs.forEach((g) => {
            const node = g && g.node ? g.node : g;
            if (node) innerEl.insertBefore(node, gridEl);
          });
        } else {
          graphs.forEach((g) => {
            w.dom.elGraphical.add(g);
          });
        }
        const dataLabels = new DataLabels(w, this);
        dataLabels.bringForward();
        if (w.config.dataLabels.background.enabled) {
          dataLabels.dataLabelsBackground();
        }
        if (Environment.isBrowser() && w.config.tooltip.enabled && !gl.noData) {
          (_a = w.globals.tooltip) == null ? void 0 : _a.drawTooltip(xyRatios);
        }
        if (typeof w.config.chart.events.updated === "function") {
          w.config.chart.events.updated(this, w);
        }
        this.events.fireEvent("updated", [this, w]);
        gl.isDirty = true;
        resolve(this);
      } catch (e) {
        reject(e);
      }
    });
  }
  /**
   * Returns all charts in the same `chart.group` (including this instance),
   * used to synchronise zoom/pan across grouped charts.
   *
   * @returns {ApexCharts[]}
   */
  getSyncedCharts() {
    const chartGroups = this.getGroupedCharts();
    let allCharts = (
      /** @type {ApexCharts[]} */
      [this]
    );
    if (chartGroups.length) {
      allCharts = [];
      chartGroups.forEach((ch) => {
        allCharts.push(ch);
      });
    }
    return allCharts;
  }
  /**
   * Returns all charts in the same `chart.group`, excluding this instance.
   * Used internally to apply hover/zoom effects to sibling charts.
   *
   * @returns {ApexCharts[]}
   */
  getGroupedCharts() {
    return Apex._chartInstances.filter((ch) => {
      if (ch.group) {
        return true;
      }
    }).map(
      (ch) => this.w.config.chart.group === ch.group ? ch.chart : this
    );
  }
  /**
   * Retrieves a rendered chart instance by its `chart.id` config value.
   *
   * @param {string} id - The chart ID set via `chart.id` in options.
   * @returns {ApexCharts | undefined}
   */
  static getChartByID(id) {
    const chartId = Utils$1.escapeString(id);
    if (!Apex._chartInstances) return void 0;
    const c = Apex._chartInstances.filter(
      (ch) => ch.id === chartId
    )[0];
    return c && c.chart;
  }
  /**
   * Scans the document for elements with a `data-apexcharts` attribute and
   * `data-options` JSON, then renders a chart in each one automatically.
   * Useful for non-framework HTML pages.
   */
  static initOnLoad() {
    var _a;
    const els = document.querySelectorAll("[data-apexcharts]");
    for (let i = 0; i < els.length; i++) {
      const el = (
        /** @type {HTMLElement} */
        els[i]
      );
      const options2 = JSON.parse((_a = els[i].getAttribute("data-options")) != null ? _a : "");
      const apexChart = new ApexCharts(el, options2);
      apexChart.render();
    }
  }
  /**
   * This static method allows users to call chart methods without necessarily from the
   * instance of the chart in case user has assigned chartID to the targeted chart.
   * The chartID is used for mapping the instance stored in Apex._chartInstances global variable
   *
   * This is helpful in cases when you don't have reference of the chart instance
   * easily and need to call the method from anywhere.
   * For eg, in React/Vue applications when you have many parent/child components,
   * and need easy reference to other charts for performing dynamic operations
   *
   * @param {string} chartID - The unique identifier which will be used to call methods
   * on that chart instance
   * @param {string} fn - The method name to call
   * @param {...any} opts - The parameters which are accepted in the original method will be passed here in the same order.
   */
  static exec(chartID, fn, ...opts) {
    const chart = this.getChartByID(chartID);
    if (!chart) return;
    chart.w.globals.isExecCalled = true;
    let ret = null;
    if (chart.publicMethods.indexOf(fn) !== -1) {
      ret = /** @type {any} */
      chart[fn](...opts);
    }
    return ret;
  }
  /**
   * Deep-merges `source` into `target` and returns the result.
   * Thin wrapper around the internal `Utils.extend` utility.
   *
   * @param {object} target
   * @param {object} source
   * @returns {object}
   */
  static merge(target, source) {
    return Utils$1.extend(target, source);
  }
  static getThemePalettes() {
    return getThemePalettes();
  }
  /**
   * Register additional chart types. Used by sub-entry points so that only
   * the types they include are bundled.
   *
   * @param {Record<string, new (...args: any[]) => any>} typeMap  e.g. { line: Line, area: Line }
   */
  static use(typeMap) {
    register(typeMap);
  }
  /**
   * Register optional feature modules (Exports, Legend, Toolbar,
   * ZoomPanSelection, KeyboardNavigation, Annotations).
   *
   * Call this before rendering any chart. Feature entry files (e.g.
   * `apexcharts/features/legend`) call this automatically when imported.
   * Note: Tooltip is part of core and does not need to be registered.
   *
   * @param {Record<string, new (...args: any[]) => any>} featureMap  e.g. { legend: Legend, exports: Exports }
   */
  static registerFeatures(featureMap) {
    InitCtxVariables.registerFeatures(featureMap);
  }
  /**
   * Toggles (show/hide) the series identified by name.
   * Mirrors a click on the corresponding legend item.
   *
   * @param {string} seriesName
   * @returns {object | undefined} The collapsed series object, if now hidden.
   */
  toggleSeries(seriesName) {
    return this.series.toggleSeries(seriesName);
  }
  /**
   * Highlights or un-highlights a series when the user hovers a legend item.
   * Called internally by the legend; not typically called by consumers.
   *
   * @param {MouseEvent} e
   * @param {HTMLElement} targetElement - The legend marker element being hovered.
   */
  highlightSeriesOnLegendHover(e, targetElement) {
    return this.series.toggleSeriesOnHover(e, targetElement);
  }
  /**
   * Makes a previously hidden series visible and re-renders.
   *
   * @param {string} seriesName
   */
  showSeries(seriesName) {
    this.series.showSeries(seriesName);
  }
  /**
   * Hides a visible series and re-renders.
   *
   * @param {string} seriesName
   */
  hideSeries(seriesName) {
    this.series.hideSeries(seriesName);
  }
  /**
   * Highlights (dims all other series) the series identified by name.
   *
   * @param {string} seriesName
   */
  highlightSeries(seriesName) {
    this.series.highlightSeries(seriesName);
  }
  /**
   * Returns whether the series identified by name is currently hidden.
   *
   * @param {string} seriesName
   * @returns {boolean}
   */
  isSeriesHidden(seriesName) {
    return this.series.isSeriesHidden(seriesName);
  }
  /**
   * Resets the chart to the initial series and optionally the initial zoom level.
   *
   * @param {boolean} [shouldUpdateChart=true] - When true, triggers a re-render.
   * @param {boolean} [shouldResetZoom=true] - When true, restores the initial zoom level.
   */
  resetSeries(shouldUpdateChart = true, shouldResetZoom = true) {
    this.series.resetSeries(shouldUpdateChart, shouldResetZoom);
  }
  /**
   * Subscribes to a chart event by name.
   * Supported event names mirror the `chart.events` option keys
   * (e.g. `'mounted'`, `'updated'`, `'dataPointMouseEnter'`).
   *
   * @param {string} name - Event name.
   * @param {Function} handler - Callback invoked when the event fires.
   */
  addEventListener(name2, handler) {
    this.events.addEventListener(name2, handler);
  }
  /**
   * Removes a previously registered event listener.
   *
   * @param {string} name - Event name.
   * @param {Function} handler - The exact function reference passed to addEventListener.
   */
  removeEventListener(name2, handler) {
    this.events.removeEventListener(name2, handler);
  }
  /**
   * Adds an x-axis annotation dynamically after render.
   *
   * @param {XAxisAnnotations} opts - Annotation configuration.
   * @param {boolean} [pushToMemory=true] - When true, the annotation persists across re-renders.
   * @param {ApexCharts} [context] - Override the target chart instance (used by exec()).
   */
  addXaxisAnnotation(opts, pushToMemory = true, context = void 0) {
    var _a;
    let me = (
      /** @type {ApexCharts} */
      /** @type {unknown} */
      this
    );
    if (context) {
      me = context;
    }
    (_a = me.annotations) == null ? void 0 : _a.addXaxisAnnotationExternal(opts, pushToMemory, me);
  }
  /**
   * Adds a y-axis annotation dynamically after render.
   *
   * @param {YAxisAnnotations} opts - Annotation configuration.
   * @param {boolean} [pushToMemory=true] - When true, the annotation persists across re-renders.
   * @param {ApexCharts} [context] - Override the target chart instance (used by exec()).
   */
  addYaxisAnnotation(opts, pushToMemory = true, context = void 0) {
    var _a;
    let me = (
      /** @type {ApexCharts} */
      /** @type {unknown} */
      this
    );
    if (context) {
      me = context;
    }
    (_a = me.annotations) == null ? void 0 : _a.addYaxisAnnotationExternal(opts, pushToMemory, me);
  }
  /**
   * Adds a point annotation dynamically after render.
   *
   * @param {PointAnnotations} opts - Annotation configuration.
   * @param {boolean} [pushToMemory=true] - When true, the annotation persists across re-renders.
   * @param {ApexCharts} [context] - Override the target chart instance (used by exec()).
   */
  addPointAnnotation(opts, pushToMemory = true, context = void 0) {
    var _a;
    let me = (
      /** @type {ApexCharts} */
      /** @type {unknown} */
      this
    );
    if (context) {
      me = context;
    }
    (_a = me.annotations) == null ? void 0 : _a.addPointAnnotationExternal(opts, pushToMemory, me);
  }
  /**
   * Removes all annotations from the chart.
   *
   * @param {ApexCharts} [context] - Override the target chart instance (used by exec()).
   */
  clearAnnotations(context = void 0) {
    var _a;
    let me = (
      /** @type {ApexCharts} */
      /** @type {unknown} */
      this
    );
    if (context) {
      me = context;
    }
    (_a = me.annotations) == null ? void 0 : _a.clearAnnotations(me);
  }
  /**
   * Removes a specific annotation by its `id`.
   *
   * @param {string} id - The annotation id as set in the annotation config.
   * @param {ApexCharts} [context] - Override the target chart instance (used by exec()).
   */
  removeAnnotation(id, context = void 0) {
    var _a;
    let me = (
      /** @type {ApexCharts} */
      /** @type {unknown} */
      this
    );
    if (context) {
      me = context;
    }
    (_a = me.annotations) == null ? void 0 : _a.removeAnnotation(me, id);
  }
  /**
   * Returns the inner SVG group element that contains all chart graphics.
   *
   * @returns {Element | null}
   */
  getChartArea() {
    const el = this.w.dom.baseEl.querySelector(".apexcharts-inner");
    return el;
  }
  /**
   * Returns the sum of all data points whose x value falls within [minX, maxX].
   *
   * @param {number} minX
   * @param {number} maxX
   * @returns {number[]} One total per series.
   */
  getSeriesTotalXRange(minX, maxX) {
    return this.coreUtils.getSeriesTotalsXRange(minX, maxX);
  }
  /**
   * Returns the highest y value in the specified series.
   *
   * @param {number} [seriesIndex=0]
   * @returns {number}
   */
  getHighestValueInSeries(seriesIndex = 0) {
    const range = new Range(this.w);
    return range.getMinYMaxY(seriesIndex).highestY;
  }
  /**
   * Returns the lowest y value in the specified series.
   *
   * @param {number} [seriesIndex=0]
   * @returns {number}
   */
  getLowestValueInSeries(seriesIndex = 0) {
    const range = new Range(this.w);
    return range.getMinYMaxY(seriesIndex).lowestY;
  }
  /**
   * Returns the sum of each series (the totals used for percentage calculations).
   *
   * @returns {number[]}
   */
  getSeriesTotal() {
    return this.w.globals.seriesTotals;
  }
  /**
   * Returns a curated snapshot of chart state for use in formatters, events,
   * and external integrations. Prefer this over accessing `chart.w` directly.
   *
   * The shape of this object is stable and versioned. `chart.w` is internal
   * and will be restricted in a future major version.
   */
  getState() {
    const w = this.w;
    const gl = w.globals;
    return {
      // Series data — computed/parsed form used for rendering
      series: w.seriesData.series,
      seriesNames: w.seriesData.seriesNames,
      colors: gl.colors,
      labels: w.labelData.labels,
      seriesTotals: gl.seriesTotals,
      seriesPercent: gl.seriesPercent,
      seriesXvalues: gl.seriesXvalues,
      seriesYvalues: gl.seriesYvalues,
      // Axis bounds — updated after each render
      minX: gl.minX,
      maxX: gl.maxX,
      minY: gl.minY,
      maxY: gl.maxY,
      minYArr: gl.minYArr,
      maxYArr: gl.maxYArr,
      minXDiff: gl.minXDiff,
      dataPoints: gl.dataPoints,
      // Axis scale objects — computed tick/scale results
      xAxisScale: gl.xAxisScale,
      yAxisScale: gl.yAxisScale,
      xTickAmount: gl.xTickAmount,
      // Axis type flags
      isXNumeric: w.axisFlags.isXNumeric,
      // Multi-axis series mapping
      seriesYAxisMap: gl.seriesYAxisMap,
      seriesYAxisReverseMap: gl.seriesYAxisReverseMap,
      // Chart dimensions — updated after each render/resize
      svgWidth: gl.svgWidth,
      svgHeight: gl.svgHeight,
      gridWidth: w.layout.gridWidth,
      gridHeight: w.layout.gridHeight,
      // Interactive state
      selectedDataPoints: w.interact.selectedDataPoints,
      collapsedSeriesIndices: gl.collapsedSeriesIndices,
      zoomed: w.interact.zoomed,
      // Chart-type-specific series data (null when not applicable)
      seriesX: w.seriesData.seriesX,
      seriesZ: w.seriesData.seriesZ,
      seriesCandleO: w.candleData.seriesCandleO,
      seriesCandleH: w.candleData.seriesCandleH,
      seriesCandleM: w.candleData.seriesCandleM,
      seriesCandleL: w.candleData.seriesCandleL,
      seriesCandleC: w.candleData.seriesCandleC,
      seriesRangeStart: w.rangeData.seriesRangeStart,
      seriesRangeEnd: w.rangeData.seriesRangeEnd,
      seriesGoals: w.seriesData.seriesGoals
    };
  }
  /**
   * Programmatically selects or deselects a data point.
   * Equivalent to a user click on the data point.
   *
   * @param {number} seriesIndex - Zero-based series index.
   * @param {number} [dataPointIndex] - Zero-based data point index within the series.
   * @returns {number[][] | null} Updated selectedDataPoints array, or null.
   */
  toggleDataPointSelection(seriesIndex, dataPointIndex) {
    return this.updateHelpers.toggleDataPointSelection(
      seriesIndex,
      dataPointIndex
    );
  }
  /**
   * Programmatically zooms the x-axis to the given range.
   * Requires zoom to be enabled (`chart.zoom.enabled: true`).
   *
   * @param {number} min - The minimum x value (timestamp or numeric).
   * @param {number} max - The maximum x value (timestamp or numeric).
   */
  zoomX(min, max) {
    var _a;
    (_a = this.ctx.toolbar) == null ? void 0 : _a.zoomUpdateOptions(min, max);
  }
  /**
   * Switches the active locale, updating all locale-dependent labels (toolbar tooltips, month names, etc.).
   *
   * @param {string} localeName - Must match a locale name defined in `chart.locales`.
   */
  setLocale(localeName) {
    this.localization.setCurrentLocaleValues(localeName);
  }
  /**
   * Exports the chart to a PNG or SVG data URI.
   * Requires the Exports feature: `import 'apexcharts/features/exports'`.
   *
   * @param {{ scale?: number, width?: number }} [options]
   * @returns {Promise<{ imgURI: string } | { blob: Blob }>}
   */
  dataURI(options2) {
    if (!this.ctx.exports)
      throw new Error(
        "apexcharts: Exports feature is not registered. Import apexcharts/features/exports."
      );
    return this.ctx.exports.dataURI(options2);
  }
  /**
   * Returns the chart's SVG markup as a string, optionally scaled.
   * Requires the Exports feature: `import 'apexcharts/features/exports'`.
   *
   * @param {number} [scale=1]
   * @returns {Promise<string>}
   */
  getSvgString(scale) {
    if (!this.ctx.exports)
      throw new Error(
        "apexcharts: Exports feature is not registered. Import apexcharts/features/exports."
      );
    return this.ctx.exports.getSvgString(scale);
  }
  /**
   * Triggers a CSV download of the chart's data.
   * Requires the Exports feature: `import 'apexcharts/features/exports'`.
   *
   * @param {{ series?: any, fileName?: string, columnDelimiter?: string, lineDelimiter?: string }} [options]
   */
  exportToCSV(options2 = {}) {
    if (!this.ctx.exports)
      throw new Error(
        "apexcharts: Exports feature is not registered. Import apexcharts/features/exports."
      );
    return this.ctx.exports.exportToCSV(options2);
  }
  paper() {
    return this.w.dom.Paper;
  }
  // ─── Slice write-back stubs ─────────────────────────────────────────────────
  /**
   * @param {Partial<import('./types/internal').SeriesData>} slice
   */
  _writeParsedSeriesData(slice) {
    Object.assign(this.w.seriesData, slice);
  }
  /**
   * @param {Partial<import('./types/internal').RangeData>} slice
   */
  _writeParsedRangeData(slice) {
    Object.assign(this.w.rangeData, slice);
  }
  /**
   * @param {Partial<import('./types/internal').CandleData>} slice
   */
  _writeParsedCandleData(slice) {
    Object.assign(this.w.candleData, slice);
  }
  /**
   * @param {Partial<import('./types/internal').LabelData>} slice
   */
  _writeParsedLabelData(slice) {
    Object.assign(this.w.labelData, slice);
  }
  /**
   * @param {Partial<import('./types/internal').AxisFlags>} slice
   */
  _writeParsedAxisFlags(slice) {
    Object.assign(this.w.axisFlags, slice);
  }
  /**
   * @param {Partial<import('./types/internal').LayoutCoords>} slice
   */
  _writeLayoutCoords(slice) {
    Object.assign(this.w.layout, slice);
  }
  _parentResizeCallback() {
    if (this.w.globals.animationEnded && this.w.config.chart.redrawOnParentResize) {
      this._windowResize();
    }
  }
  /**
   * Handle window resize and re-draw the whole chart.
   */
  _windowResize() {
    this.w.globals.resizeTimer = window.setTimeout(() => {
      this.w.globals.resized = true;
      this.w.globals.dataChanged = false;
      this.ctx.update();
    }, 150);
  }
  _windowResizeHandler() {
    var _a;
    clearTimeout((_a = this.w.globals.resizeTimer) != null ? _a : void 0);
    let { redrawOnWindowResize: redraw } = this.w.config.chart;
    if (typeof redraw === "function") {
      redraw = /** @type {any} */
      redraw();
    }
    redraw && this._windowResize();
  }
}
const apexchartsLegendCSS = ".apexcharts-flip-y {\n  transform: scaleY(-1) translateY(-100%);\n  transform-origin: top;\n  transform-box: fill-box;\n}\n.apexcharts-flip-x {\n  transform: scaleX(-1);\n  transform-origin: center;\n  transform-box: fill-box;\n}\n.apexcharts-legend {\n  display: flex;\n  overflow: auto;\n  padding: 0 10px;\n}\n.apexcharts-legend.apexcharts-legend-group-horizontal {\n  flex-direction: column;\n}\n.apexcharts-legend-group {\n  display: flex;\n}\n.apexcharts-legend-group-vertical {\n  flex-direction: column-reverse;\n}\n.apexcharts-legend.apx-legend-position-bottom, .apexcharts-legend.apx-legend-position-top {\n  flex-wrap: wrap\n}\n.apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {\n  flex-direction: column;\n  bottom: 0;\n}\n.apexcharts-legend.apx-legend-position-bottom.apexcharts-align-left, .apexcharts-legend.apx-legend-position-top.apexcharts-align-left, .apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {\n  justify-content: flex-start;\n  align-items: flex-start;\n}\n.apexcharts-legend.apx-legend-position-bottom.apexcharts-align-center, .apexcharts-legend.apx-legend-position-top.apexcharts-align-center {\n  justify-content: center;\n  align-items: center;\n}\n.apexcharts-legend.apx-legend-position-bottom.apexcharts-align-right, .apexcharts-legend.apx-legend-position-top.apexcharts-align-right {\n  justify-content: flex-end;\n  align-items: flex-end;\n}\n.apexcharts-legend-series {\n  cursor: pointer;\n  line-height: normal;\n  display: flex;\n  align-items: center;\n}\n.apexcharts-legend-text {\n  position: relative;\n  font-size: 14px;\n}\n.apexcharts-legend-text *, .apexcharts-legend-marker * {\n  pointer-events: none;\n}\n.apexcharts-legend-marker {\n  position: relative;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  cursor: pointer;\n  margin-right: 1px;\n}\n\n.apexcharts-legend-series.apexcharts-no-click {\n  cursor: auto;\n}\n.apexcharts-legend .apexcharts-hidden-zero-series, .apexcharts-legend .apexcharts-hidden-null-series {\n  display: none !important;\n}\n.apexcharts-inactive-legend {\n  opacity: 0.45;\n} ";
class Exports {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
  }
  /**
   * @param {string} svgString
   */
  svgStringToNode(svgString) {
    const parser = new DOMParser();
    const svgDoc = parser.parseFromString(svgString, "image/svg+xml");
    return svgDoc.documentElement;
  }
  /**
   * @param {any} svg
   * @param {number} scale
   */
  scaleSvgNode(svg, scale) {
    const svgWidth = parseFloat(svg.getAttributeNS(null, "width"));
    const svgHeight = parseFloat(svg.getAttributeNS(null, "height"));
    svg.setAttributeNS(null, "width", svgWidth * scale);
    svg.setAttributeNS(null, "height", svgHeight * scale);
    svg.setAttributeNS(null, "viewBox", "0 0 " + svgWidth + " " + svgHeight);
  }
  /**
   * @param {number} [_scale]
   */
  getSvgString(_scale) {
    return new Promise((resolve) => {
      const w = this.w;
      let scale = _scale || w.config.chart.toolbar.export.scale || w.config.chart.toolbar.export.width / w.globals.svgWidth;
      if (!scale) {
        scale = 1;
      }
      const width = w.globals.svgWidth * scale;
      const height = w.globals.svgHeight * scale;
      const clonedNode = (
        /** @type {HTMLElement} */
        w.dom.elWrap.cloneNode(true)
      );
      clonedNode.style.width = width + "px";
      clonedNode.style.height = height + "px";
      const serializedNode = new XMLSerializer().serializeToString(clonedNode);
      const shouldIncludeLegendStyles = w.config.legend.show && w.dom.elLegendWrap && w.dom.elLegendWrap.children.length > 0;
      let exportStyles = `
        .apexcharts-tooltip, .apexcharts-toolbar, .apexcharts-xaxistooltip, .apexcharts-yaxistooltip, .apexcharts-xcrosshairs, .apexcharts-ycrosshairs, .apexcharts-zoom-rect, .apexcharts-selection-rect {
          display: none;
        }
      `;
      if (shouldIncludeLegendStyles) {
        exportStyles += apexchartsLegendCSS;
      }
      let svgString = `
        <svg xmlns="http://www.w3.org/2000/svg"
          version="1.1"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          class="apexcharts-svg"
          xmlns:data="ApexChartsNS"
          transform="translate(0, 0)"
          width="${w.globals.svgWidth}px" height="${w.globals.svgHeight}px">
          <foreignObject width="100%" height="100%">
            <div xmlns="http://www.w3.org/1999/xhtml" style="width:${width}px; height:${height}px;">
            <style type="text/css">
              ${exportStyles}
            </style>
              ${serializedNode}
            </div>
          </foreignObject>
        </svg>
      `;
      const svgNode = this.svgStringToNode(svgString);
      if (scale !== 1) {
        this.scaleSvgNode(svgNode, scale);
      }
      this.convertImagesToBase64(svgNode).then(() => {
        svgString = new XMLSerializer().serializeToString(svgNode);
        resolve(svgString.replace(/&nbsp;/g, "&#160;"));
      });
    });
  }
  /**
   * @param {any} svgNode
   */
  convertImagesToBase64(svgNode) {
    const images = svgNode.getElementsByTagName("image");
    const promises = Array.from(images).map((img) => {
      const href = img.getAttributeNS("http://www.w3.org/1999/xlink", "href");
      if (href && !href.startsWith("data:")) {
        return this.getBase64FromUrl(href).then((base64) => {
          img.setAttributeNS("http://www.w3.org/1999/xlink", "href", base64);
        }).catch((error) => {
          console.error("Error converting image to base64:", error);
        });
      }
      return Promise.resolve();
    });
    return Promise.all(promises);
  }
  /**
   * @param {string} url
   */
  getBase64FromUrl(url) {
    if (Environment.isSSR()) return Promise.resolve(url);
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.crossOrigin = "Anonymous";
      img.onload = () => {
        const canvas = document.createElement("canvas");
        canvas.width = img.width;
        canvas.height = img.height;
        const ctx = canvas.getContext("2d");
        if (ctx) ctx.drawImage(img, 0, 0);
        resolve(canvas.toDataURL());
      };
      img.onerror = reject;
      img.src = url;
    });
  }
  svgUrl() {
    return new Promise((resolve) => {
      this.getSvgString().then((svgData) => {
        const svgBlob = new Blob([svgData], {
          type: "image/svg+xml;charset=utf-8"
        });
        resolve(URL.createObjectURL(svgBlob));
      });
    });
  }
  /**
   * @param {Record<string, any> | undefined} options
   */
  dataURI(options2) {
    if (Environment.isSSR()) return Promise.resolve({ imgURI: "" });
    return new Promise((resolve) => {
      const w = this.w;
      const scale = options2 ? options2.scale || options2.width / w.globals.svgWidth : 1;
      const canvas = document.createElement("canvas");
      canvas.width = w.globals.svgWidth * scale;
      canvas.height = parseInt(w.dom.elWrap.style.height, 10) * scale;
      const canvasBg = w.config.chart.background === "transparent" || !w.config.chart.background ? "#fff" : w.config.chart.background;
      const ctx = canvas.getContext("2d");
      if (!ctx) return;
      ctx.fillStyle = canvasBg;
      ctx.fillRect(0, 0, canvas.width * scale, canvas.height * scale);
      this.getSvgString(scale).then((svgData) => {
        const svgUrl = "data:image/svg+xml," + encodeURIComponent(svgData);
        const img = new Image();
        img.crossOrigin = "anonymous";
        img.onload = () => {
          ctx.drawImage(img, 0, 0);
          const edgeCanvas = canvas;
          if (edgeCanvas.msToBlob) {
            const blob = edgeCanvas.msToBlob();
            resolve({ blob });
          } else {
            const imgURI = canvas.toDataURL("image/png");
            resolve({ imgURI });
          }
        };
        img.src = svgUrl;
      });
    });
  }
  exportToSVG() {
    this.svgUrl().then((url) => {
      this.triggerDownload(
        url,
        this.w.config.chart.toolbar.export.svg.filename,
        ".svg"
      );
    });
  }
  exportToPng() {
    const scale = this.w.config.chart.toolbar.export.scale;
    const width = this.w.config.chart.toolbar.export.width;
    const option = scale ? { scale } : width ? { width } : void 0;
    this.dataURI(option).then(({ imgURI, blob }) => {
      if (blob) {
        navigator.msSaveOrOpenBlob(blob, this.w.globals.chartID + ".png");
      } else {
        this.triggerDownload(
          imgURI,
          this.w.config.chart.toolbar.export.png.filename,
          ".png"
        );
      }
    });
  }
  /** @param {{ series?: any, fileName?: any, columnDelimiter?: string, lineDelimiter?: string }} opts */
  exportToCSV({
    series,
    fileName,
    columnDelimiter = ",",
    lineDelimiter = "\n"
  }) {
    const w = this.w;
    if (!series) series = w.config.series;
    let columns = [];
    const rows = [];
    let result = "";
    const universalBOM = "\uFEFF";
    const gSeries = w.seriesData.series.map((s, i) => {
      return w.globals.collapsedSeriesIndices.indexOf(i) === -1 ? s : [];
    });
    const getFormattedCategory = (cat) => {
      if (typeof w.config.chart.toolbar.export.csv.categoryFormatter === "function") {
        return w.config.chart.toolbar.export.csv.categoryFormatter(cat);
      }
      if (w.config.xaxis.type === "datetime" && String(cat).length >= 10) {
        return new Date(cat).toDateString();
      }
      return Utils$1.isNumber(cat) ? cat : cat.split(columnDelimiter).join("");
    };
    const getFormattedValue = (value) => {
      return typeof w.config.chart.toolbar.export.csv.valueFormatter === "function" ? w.config.chart.toolbar.export.csv.valueFormatter(value) : value;
    };
    const seriesMaxDataLength = Math.max(
      ...series.map((s) => {
        return s.data ? s.data.length : 0;
      })
    );
    const dataFormat = new Data(this.w);
    const axesUtils = new AxesUtils(this.w, {
      theme: this.ctx.theme,
      timeScale: this.ctx.timeScale
    });
    const getCat = (i) => {
      let cat = "";
      if (!w.globals.axisCharts) {
        cat = w.config.labels[i];
      } else {
        if (w.config.xaxis.type === "category" || w.config.xaxis.convertedCatToNumeric) {
          if (w.globals.isBarHorizontal) {
            const lbFormatter = w.formatters.yLabelFormatters[0];
            const sr = new Series(this.ctx.w);
            const activeSeries = sr.getActiveConfigSeriesIndex();
            cat = lbFormatter(w.labelData.labels[i], {
              seriesIndex: activeSeries,
              dataPointIndex: i,
              w
            });
          } else {
            cat = axesUtils.getLabel(
              w.labelData.labels,
              w.labelData.timescaleLabels,
              0,
              i
            ).text;
          }
        }
        if (w.config.xaxis.type === "datetime") {
          if (w.config.xaxis.categories.length) {
            cat = w.config.xaxis.categories[i];
          } else if (w.config.labels.length) {
            cat = w.config.labels[i];
          }
        }
      }
      if (cat === null) return "nullvalue";
      if (Array.isArray(cat)) {
        cat = cat.join(" ");
      }
      return Utils$1.isNumber(cat) ? cat : cat.split(columnDelimiter).join("");
    };
    const getEmptyDataForCsvColumn = () => {
      return [...Array(seriesMaxDataLength)].map(() => "");
    };
    const handleAxisRowsColumns = (s, sI) => {
      var _a;
      if (columns.length && sI === 0) {
        rows.push(columns.join(columnDelimiter));
      }
      if (s.data) {
        s.data = s.data.length && s.data || getEmptyDataForCsvColumn();
        for (let i = 0; i < s.data.length; i++) {
          columns = [];
          let cat = getCat(i);
          if (cat === "nullvalue") continue;
          if (!cat) {
            if (dataFormat.isFormatXY()) {
              cat = series[sI].data[i].x;
            } else if (dataFormat.isFormat2DArray()) {
              cat = series[sI].data[i] ? series[sI].data[i][0] : "";
            }
          }
          if (sI === 0) {
            columns.push(getFormattedCategory(cat));
            for (let ci = 0; ci < w.seriesData.series.length; ci++) {
              const value = dataFormat.isFormatXY() ? (_a = series[ci].data[i]) == null ? void 0 : _a.y : gSeries[ci][i];
              columns.push(getFormattedValue(value));
            }
          }
          if (w.config.chart.type === "candlestick" || s.type && s.type === "candlestick") {
            columns.pop();
            columns.push(w.candleData.seriesCandleO[sI][i]);
            columns.push(w.candleData.seriesCandleH[sI][i]);
            columns.push(w.candleData.seriesCandleL[sI][i]);
            columns.push(w.candleData.seriesCandleC[sI][i]);
          }
          if (w.config.chart.type === "boxPlot" || s.type && s.type === "boxPlot") {
            columns.pop();
            columns.push(w.candleData.seriesCandleO[sI][i]);
            columns.push(w.candleData.seriesCandleH[sI][i]);
            columns.push(w.candleData.seriesCandleM[sI][i]);
            columns.push(w.candleData.seriesCandleL[sI][i]);
            columns.push(w.candleData.seriesCandleC[sI][i]);
          }
          if (w.config.chart.type === "rangeBar") {
            columns.pop();
            columns.push(w.rangeData.seriesRangeStart[sI][i]);
            columns.push(w.rangeData.seriesRangeEnd[sI][i]);
          }
          if (columns.length) {
            rows.push(columns.join(columnDelimiter));
          }
        }
      }
    };
    const handleUnequalXValues = () => {
      const categories = /* @__PURE__ */ new Set();
      const data = {};
      series.forEach((s, sI) => {
        s == null ? void 0 : s.data.forEach((dataItem) => {
          let cat, value;
          if (dataFormat.isFormatXY()) {
            cat = dataItem.x;
            value = dataItem.y;
          } else if (dataFormat.isFormat2DArray()) {
            cat = dataItem[0];
            value = dataItem[1];
          } else {
            return;
          }
          if (!/** @type {Record<string,any>} */
          data[cat]) {
            data[cat] = Array(
              series.length
            ).fill("");
          }
          data[cat][sI] = getFormattedValue(value);
          categories.add(cat);
        });
      });
      if (columns.length) {
        rows.push(columns.join(columnDelimiter));
      }
      Array.from(categories).sort().forEach((cat) => {
        rows.push([
          getFormattedCategory(cat),
          /** @type {Record<string,any>} */
          data[cat].join(columnDelimiter)
        ]);
      });
    };
    columns.push(w.config.chart.toolbar.export.csv.headerCategory);
    if (w.config.chart.type === "boxPlot") {
      columns.push("minimum");
      columns.push("q1");
      columns.push("median");
      columns.push("q3");
      columns.push("maximum");
    } else if (w.config.chart.type === "candlestick") {
      columns.push("open");
      columns.push("high");
      columns.push("low");
      columns.push("close");
    } else if (w.config.chart.type === "rangeBar") {
      columns.push("minimum");
      columns.push("maximum");
    } else {
      series.map((s, sI) => {
        const sname = (s.name ? s.name : `series-${sI}`) + "";
        if (w.globals.axisCharts) {
          columns.push(
            sname.split(columnDelimiter).join("") ? sname.split(columnDelimiter).join("") : `series-${sI}`
          );
        }
      });
    }
    if (!w.globals.axisCharts) {
      columns.push(w.config.chart.toolbar.export.csv.headerValue);
      rows.push(columns.join(columnDelimiter));
    }
    if (!w.globals.allSeriesHasEqualX && w.globals.axisCharts && !w.config.xaxis.categories.length && !w.config.labels.length) {
      handleUnequalXValues();
    } else {
      series.map((s, sI) => {
        if (w.globals.axisCharts) {
          handleAxisRowsColumns(s, sI);
        } else {
          columns = [];
          columns.push(getFormattedCategory(w.labelData.labels[sI]));
          columns.push(getFormattedValue(gSeries[sI]));
          rows.push(columns.join(columnDelimiter));
        }
      });
    }
    result += rows.join(lineDelimiter);
    this.triggerDownload(
      "data:text/csv; charset=utf-8," + encodeURIComponent(universalBOM + result),
      fileName ? fileName : w.config.chart.toolbar.export.csv.filename,
      ".csv"
    );
  }
  /**
   * @param {string} href
   * @param {string} filename
   * @param {string} ext
   */
  triggerDownload(href, filename, ext) {
    if (Environment.isSSR()) return;
    const downloadLink = document.createElement("a");
    downloadLink.href = href;
    downloadLink.download = (filename ? filename : this.w.globals.chartID) + ext;
    document.body.appendChild(downloadLink);
    downloadLink.click();
    document.body.removeChild(downloadLink);
  }
}
ApexCharts.registerFeatures({ exports: Exports });
let Helpers$3 = class Helpers2 {
  /**
   * @param {import('./Legend').default} lgCtx
   */
  constructor(lgCtx) {
    this.w = lgCtx.w;
    this.lgCtx = lgCtx;
  }
  getLegendStyles() {
    if (Environment.isSSR()) return null;
    const stylesheet = document.createElement("style");
    stylesheet.setAttribute("type", "text/css");
    const nonce = this.w.config.chart.nonce;
    if (nonce) {
      stylesheet.setAttribute("nonce", nonce);
    }
    const rule = document.createTextNode(apexchartsLegendCSS);
    stylesheet.appendChild(rule);
    return stylesheet;
  }
  getLegendDimensions() {
    const w = this.w;
    const currLegendsWrap = w.dom.baseEl.querySelector(".apexcharts-legend");
    if (!currLegendsWrap) {
      return { clwh: 0, clww: 0 };
    }
    const { width: currLegendsWrapWidth, height: currLegendsWrapHeight } = currLegendsWrap.getBoundingClientRect();
    return {
      clwh: currLegendsWrapHeight,
      clww: currLegendsWrapWidth
    };
  }
  appendToForeignObject() {
    var _a;
    const legendStyles = this.getLegendStyles();
    if (this.w.config.chart.injectStyleSheet !== false && legendStyles) {
      (_a = this.w.dom.elLegendForeign) == null ? void 0 : _a.appendChild(legendStyles);
    }
  }
  /**
   * @param {number} seriesCnt
   * @param {boolean} isHidden
   */
  toggleDataSeries(seriesCnt, isHidden) {
    var _a, _b;
    const w = this.w;
    if (w.globals.axisCharts || w.config.chart.type === "radialBar") {
      w.globals.resized = true;
      let seriesEl = null;
      let realIndex = null;
      w.globals.risingSeries = [];
      if (w.globals.axisCharts) {
        seriesEl = w.dom.baseEl.querySelector(
          `.apexcharts-series[data\\:realIndex='${seriesCnt}']`
        );
        if (!seriesEl) return;
        realIndex = parseInt((_a = seriesEl.getAttribute("data:realIndex")) != null ? _a : "", 10);
      } else {
        seriesEl = w.dom.baseEl.querySelector(
          `.apexcharts-series[rel='${seriesCnt + 1}']`
        );
        if (!seriesEl) return;
        realIndex = parseInt((_b = seriesEl.getAttribute("rel")) != null ? _b : "", 10) - 1;
      }
      if (isHidden) {
        const seriesToMakeVisible = [
          {
            cs: w.globals.collapsedSeries,
            csi: w.globals.collapsedSeriesIndices
          },
          {
            cs: w.globals.ancillaryCollapsedSeries,
            csi: w.globals.ancillaryCollapsedSeriesIndices
          }
        ];
        seriesToMakeVisible.forEach((r) => {
          const cs = (
            /** @type {any} */
            r.cs
          );
          const csi = (
            /** @type {any} */
            r.csi
          );
          this.riseCollapsedSeries(
            cs,
            csi,
            /** @type {number} */
            realIndex
          );
        });
      } else {
        this.hideSeries({ seriesEl, realIndex });
      }
      if (w.config.chart.accessibility.enabled) {
        const legendItem = w.dom.baseEl.querySelector(
          `.apexcharts-legend-series[rel="${seriesCnt + 1}"]`
        );
        if (legendItem) {
          const isCollapsed = w.globals.collapsedSeriesIndices.includes(realIndex) || w.globals.ancillaryCollapsedSeriesIndices.includes(realIndex);
          legendItem.setAttribute(
            "aria-pressed",
            isCollapsed ? "true" : "false"
          );
          const legendTextEl = legendItem.querySelector(
            ".apexcharts-legend-text"
          );
          const seriesName = legendTextEl ? legendTextEl.textContent : w.seriesData.seriesNames[seriesCnt];
          const statusText = isCollapsed ? "hidden" : "visible";
          legendItem.setAttribute(
            "aria-label",
            `${seriesName}, ${statusText}. Press Enter or Space to toggle.`
          );
        }
      }
    } else {
      const seriesEl = w.dom.Paper.findOne(
        ` .apexcharts-series[rel='${seriesCnt + 1}'] path`
      );
      const type = w.config.chart.type;
      if (type === "pie" || type === "polarArea" || type === "donut") {
        const dataLabels = w.config.plotOptions.pie.donut.labels;
        const graphics = new Graphics(this.w);
        graphics.pathMouseDown(seriesEl, null);
        this.lgCtx.printDataLabelsInner(seriesEl.node, dataLabels);
      }
      if (w.config.chart.accessibility.enabled) {
        const legendItem = w.dom.baseEl.querySelector(
          `.apexcharts-legend-series[rel="${seriesCnt + 1}"]`
        );
        if (legendItem) {
          const isCollapsed = w.globals.collapsedSeriesIndices.includes(seriesCnt);
          legendItem.setAttribute(
            "aria-pressed",
            isCollapsed ? "true" : "false"
          );
          const legendTextEl = legendItem.querySelector(
            ".apexcharts-legend-text"
          );
          const seriesName = legendTextEl ? legendTextEl.textContent : w.seriesData.seriesNames[seriesCnt];
          const statusText = isCollapsed ? "hidden" : "visible";
          legendItem.setAttribute(
            "aria-label",
            `${seriesName}, ${statusText}. Press Enter or Space to toggle.`
          );
        }
      }
    }
  }
  /** @param {{realIndex: any}} opts */
  getSeriesAfterCollapsing({ realIndex }) {
    var _a;
    const w = this.w;
    const gl = w.globals;
    const series = Utils$1.clone(w.config.series);
    if (gl.axisCharts) {
      const yaxis = w.config.yaxis[gl.seriesYAxisReverseMap[realIndex]];
      const collapseData = {
        index: realIndex,
        data: series[realIndex].data.slice(),
        type: series[realIndex].type || w.config.chart.type
      };
      if (yaxis && yaxis.show && yaxis.showAlways) {
        if (gl.ancillaryCollapsedSeriesIndices.indexOf(realIndex) < 0) {
          gl.ancillaryCollapsedSeries.push(collapseData);
          gl.ancillaryCollapsedSeriesIndices.push(realIndex);
        }
      } else {
        if (gl.collapsedSeriesIndices.indexOf(realIndex) < 0) {
          gl.collapsedSeries.push(collapseData);
          gl.collapsedSeriesIndices.push(realIndex);
          const removeIndexOfRising = gl.risingSeries.indexOf(realIndex);
          gl.risingSeries.splice(removeIndexOfRising, 1);
        }
      }
    } else {
      gl.collapsedSeries.push({
        index: realIndex,
        data: series[realIndex],
        type: (
          /** @type {any} */
          (_a = w.config.series[realIndex].type) != null ? _a : "line"
        )
      });
      gl.collapsedSeriesIndices.push(realIndex);
    }
    gl.allSeriesCollapsed = gl.collapsedSeries.length + gl.ancillaryCollapsedSeries.length === w.config.series.length;
    return this._getSeriesBasedOnCollapsedState(series);
  }
  /** @param {{seriesEl: any, realIndex: any}} opts */
  hideSeries({ seriesEl, realIndex }) {
    const w = this.w;
    const series = this.getSeriesAfterCollapsing({
      realIndex
    });
    const seriesChildren = seriesEl.childNodes;
    for (let sc = 0; sc < seriesChildren.length; sc++) {
      if (seriesChildren[sc].classList.contains("apexcharts-series-markers-wrap")) {
        if (seriesChildren[sc].classList.contains("apexcharts-hide")) {
          seriesChildren[sc].classList.remove("apexcharts-hide");
        } else {
          seriesChildren[sc].classList.add("apexcharts-hide");
        }
      }
    }
    this.lgCtx.updateSeries(
      series,
      w.config.chart.animations.dynamicAnimation.enabled
    );
  }
  /**
   * @param {any[]} collapsedSeries
   * @param {number[]} seriesIndices
   * @param {number} realIndex
   */
  riseCollapsedSeries(collapsedSeries, seriesIndices, realIndex) {
    const w = this.w;
    let series = Utils$1.clone(w.config.series);
    if (collapsedSeries.length > 0) {
      for (let c = 0; c < collapsedSeries.length; c++) {
        if (collapsedSeries[c].index === realIndex) {
          if (w.globals.axisCharts) {
            series[realIndex].data = collapsedSeries[c].data.slice();
          } else {
            series[realIndex] = collapsedSeries[c].data;
          }
          if (typeof series[realIndex] !== "number") {
            series[realIndex].hidden = false;
          }
          collapsedSeries.splice(c, 1);
          seriesIndices.splice(c, 1);
          w.globals.risingSeries.push(realIndex);
          c--;
        }
      }
      series = this._getSeriesBasedOnCollapsedState(series);
      this.lgCtx.updateSeries(
        series,
        w.config.chart.animations.dynamicAnimation.enabled
      );
    }
  }
  /**
   * @param {any[]} series
   */
  _getSeriesBasedOnCollapsedState(series) {
    const w = this.w;
    let collapsed = 0;
    if (w.globals.axisCharts) {
      series.forEach((s, sI) => {
        if (!(w.globals.collapsedSeriesIndices.indexOf(sI) < 0 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(sI) < 0)) {
          series[sI].data = [];
          collapsed++;
        }
      });
    } else {
      series.forEach((s, sI) => {
        if (!(w.globals.collapsedSeriesIndices.indexOf(sI) < 0)) {
          series[sI] = 0;
          collapsed++;
        }
      });
    }
    w.globals.allSeriesCollapsed = collapsed === series.length;
    return series;
  }
};
class Legend {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   * @param {import('../../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
    this.printDataLabelsInner = (...a) => {
      var _a;
      return (_a = ctx.pie) == null ? void 0 : _a.printDataLabelsInner(...a);
    };
    this.updateSeries = (...a) => ctx.updateHelpers._updateSeries(...a);
    this.onLegendClick = this.onLegendClick.bind(this);
    this.onLegendHovered = this.onLegendHovered.bind(this);
    this.isBarsDistributed = this.w.config.chart.type === "bar" && this.w.config.plotOptions.bar.distributed && this.w.config.series.length === 1;
    this.legendHelpers = new Helpers$3(this);
  }
  init() {
    const w = this.w;
    const gl = w.globals;
    const cnf = w.config;
    const showLegendAlways = cnf.legend.showForSingleSeries && this.w.seriesData.series.length === 1 || this.isBarsDistributed || this.w.seriesData.series.length > 1;
    this.legendHelpers.appendToForeignObject();
    if ((showLegendAlways || !gl.axisCharts) && cnf.legend.show) {
      const elLegendWrap = (
        /** @type {HTMLElement} */
        w.dom.elLegendWrap
      );
      while (elLegendWrap.firstChild) {
        elLegendWrap.removeChild(elLegendWrap.firstChild);
      }
      this.drawLegends();
      if (cnf.legend.position === "bottom" || cnf.legend.position === "top") {
        this.legendAlignHorizontal();
      } else if (cnf.legend.position === "right" || cnf.legend.position === "left") {
        this.legendAlignVertical();
      }
    }
  }
  createLegendMarker({ i, fillcolor }) {
    const w = this.w;
    const elMarker = BrowserAPIs.createElement("span");
    elMarker.classList.add("apexcharts-legend-marker");
    const mShape = w.config.legend.markers.shape || w.config.markers.shape;
    let shape = mShape;
    if (Array.isArray(mShape)) {
      shape = mShape[i];
    }
    const mSize = Array.isArray(w.config.legend.markers.size) ? parseFloat(w.config.legend.markers.size[i]) : parseFloat(w.config.legend.markers.size);
    const mOffsetX = Array.isArray(w.config.legend.markers.offsetX) ? parseFloat(w.config.legend.markers.offsetX[i]) : parseFloat(w.config.legend.markers.offsetX);
    const mOffsetY = Array.isArray(w.config.legend.markers.offsetY) ? parseFloat(w.config.legend.markers.offsetY[i]) : parseFloat(w.config.legend.markers.offsetY);
    const mBorderWidth = Array.isArray(w.config.legend.markers.strokeWidth) ? parseFloat(w.config.legend.markers.strokeWidth[i]) : parseFloat(w.config.legend.markers.strokeWidth);
    const mStyle = elMarker.style;
    mStyle.height = (mSize + mBorderWidth) * 2 + "px";
    mStyle.width = (mSize + mBorderWidth) * 2 + "px";
    mStyle.left = mOffsetX + "px";
    mStyle.top = mOffsetY + "px";
    if (w.config.legend.markers.customHTML) {
      mStyle.background = "transparent";
      mStyle.color = fillcolor[i];
      if (Array.isArray(w.config.legend.markers.customHTML)) {
        if (w.config.legend.markers.customHTML[i]) {
          elMarker.innerHTML = w.config.legend.markers.customHTML[i]();
        }
      } else {
        elMarker.innerHTML = w.config.legend.markers.customHTML();
      }
    } else {
      const markers = new Markers(this.ctx.w, this.ctx);
      const markerConfig = markers.getMarkerConfig({
        cssClass: `apexcharts-legend-marker apexcharts-marker apexcharts-marker-${shape}`,
        seriesIndex: i,
        strokeWidth: mBorderWidth,
        size: mSize
      });
      const SVGLib = Environment.isBrowser() ? (
        /** @type {any} */
        window.SVG
      ) : (
        /** @type {any} */
        global.SVG
      );
      const SVGMarker = SVGLib().addTo(elMarker).size("100%", "100%");
      const marker = new Graphics(this.w).drawMarker(0, 0, __spreadProps(__spreadValues({}, markerConfig), {
        pointFillColor: Array.isArray(fillcolor) ? fillcolor[i] : markerConfig.pointFillColor,
        shape
      }));
      const shapesEls = w.dom.Paper.find(
        ".apexcharts-legend-marker.apexcharts-marker"
      );
      shapesEls.forEach((shapeEl) => {
        if (shapeEl.node.classList.contains("apexcharts-marker-triangle")) {
          shapeEl.node.style.transform = "translate(50%, 45%)";
        } else {
          shapeEl.node.style.transform = "translate(50%, 50%)";
        }
      });
      SVGMarker.add(marker);
    }
    return elMarker;
  }
  drawLegends() {
    var _a;
    const me = this;
    const w = this.w;
    const elLegendWrap = (
      /** @type {HTMLElement} */
      w.dom.elLegendWrap
    );
    const fontFamily = w.config.legend.fontFamily;
    let legendNames = w.seriesData.seriesNames;
    let fillcolor = w.config.legend.markers.fillColors ? w.config.legend.markers.fillColors.slice() : w.globals.colors.slice();
    if (w.config.chart.type === "heatmap") {
      const ranges = w.config.plotOptions.heatmap.colorScale.ranges;
      legendNames = ranges.map((colorScale) => {
        return colorScale.name ? colorScale.name : colorScale.from + " - " + colorScale.to;
      });
      fillcolor = ranges.map((color) => color.color);
    } else if (this.isBarsDistributed) {
      legendNames = w.labelData.labels.slice();
    }
    if (w.config.legend.customLegendItems.length) {
      legendNames = w.config.legend.customLegendItems;
    }
    const legendFormatter = w.formatters.legendFormatter;
    const isLegendInversed = w.config.legend.inverseOrder;
    const legendGroups = [];
    if (w.labelData.seriesGroups.length > 1 && w.config.legend.clusterGroupedSeries) {
      w.labelData.seriesGroups.forEach((_, gi) => {
        legendGroups[gi] = BrowserAPIs.createElement("div");
        legendGroups[gi].classList.add(
          "apexcharts-legend-group",
          `apexcharts-legend-group-${gi}`
        );
        if (w.config.legend.clusterGroupedSeriesOrientation === "horizontal") {
          elLegendWrap.classList.add("apexcharts-legend-group-horizontal");
        } else {
          legendGroups[gi].classList.add("apexcharts-legend-group-vertical");
        }
      });
    }
    for (let i = isLegendInversed ? legendNames.length - 1 : 0; isLegendInversed ? i >= 0 : i <= legendNames.length - 1; isLegendInversed ? i-- : i++) {
      const text = legendFormatter(legendNames[i], { seriesIndex: i, w });
      let collapsedSeries = false;
      let ancillaryCollapsedSeries = false;
      if (w.globals.collapsedSeries.length > 0) {
        for (let c = 0; c < w.globals.collapsedSeries.length; c++) {
          if (w.globals.collapsedSeries[c].index === i) {
            collapsedSeries = true;
          }
        }
      }
      if (w.globals.ancillaryCollapsedSeriesIndices.length > 0) {
        for (let c = 0; c < w.globals.ancillaryCollapsedSeriesIndices.length; c++) {
          if (w.globals.ancillaryCollapsedSeriesIndices[c] === i) {
            ancillaryCollapsedSeries = true;
          }
        }
      }
      const elMarker = this.createLegendMarker({ i, fillcolor });
      Graphics.setAttrs(elMarker, {
        rel: i + 1,
        "data:collapsed": collapsedSeries || ancillaryCollapsedSeries
      });
      if (collapsedSeries || ancillaryCollapsedSeries) {
        elMarker.classList.add("apexcharts-inactive-legend");
      }
      const elLegend = BrowserAPIs.createElement("div");
      if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled) {
        elLegend.setAttribute("role", "button");
        elLegend.setAttribute("tabindex", "0");
        const seriesName = Array.isArray(text) ? text.join(" ") : text;
        const isCollapsed = collapsedSeries || ancillaryCollapsedSeries;
        const statusText = isCollapsed ? "hidden" : "visible";
        elLegend.setAttribute(
          "aria-label",
          `${seriesName}, ${statusText}. Press Enter or Space to toggle.`
        );
        elLegend.setAttribute("aria-pressed", isCollapsed ? "true" : "false");
      }
      const elLegendText = BrowserAPIs.createElement("span");
      elLegendText.classList.add("apexcharts-legend-text");
      elLegendText.innerHTML = Array.isArray(text) ? text.join(" ") : text;
      let textColor = w.config.legend.labels.useSeriesColors ? w.globals.colors[i] : Array.isArray(w.config.legend.labels.colors) ? (_a = w.config.legend.labels.colors) == null ? void 0 : _a[i] : w.config.legend.labels.colors;
      if (!textColor) {
        textColor = w.config.chart.foreColor;
      }
      elLegendText.style.color = textColor;
      elLegendText.style.fontSize = w.config.legend.fontSize;
      elLegendText.style.fontWeight = w.config.legend.fontWeight;
      elLegendText.style.fontFamily = fontFamily || w.config.chart.fontFamily;
      Graphics.setAttrs(elLegendText, {
        rel: i + 1,
        i,
        "data:default-text": encodeURIComponent(text),
        "data:collapsed": collapsedSeries || ancillaryCollapsedSeries
      });
      elLegend.appendChild(elMarker);
      elLegend.appendChild(elLegendText);
      const coreUtils = new CoreUtils(this.w);
      if (!w.config.legend.showForZeroSeries) {
        const total = coreUtils.getSeriesTotalByIndex(i);
        if (total === 0 && coreUtils.seriesHaveSameValues(i) && !coreUtils.isSeriesNull(i) && w.globals.collapsedSeriesIndices.indexOf(i) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(i) === -1) {
          elLegend.classList.add("apexcharts-hidden-zero-series");
        }
      }
      if (!w.config.legend.showForNullSeries) {
        if (coreUtils.isSeriesNull(i) && w.globals.collapsedSeriesIndices.indexOf(i) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(i) === -1) {
          elLegend.classList.add("apexcharts-hidden-null-series");
        }
      }
      if (legendGroups.length) {
        w.labelData.seriesGroups.forEach((group, gi) => {
          var _a2, _b;
          if (group.includes(
            /** @type {Record<string,any>} */
            (_b = (_a2 = w.config.series[i]) == null ? void 0 : _a2.name) != null ? _b : ""
          )) {
            elLegendWrap.appendChild(legendGroups[gi]);
            legendGroups[gi].appendChild(elLegend);
          }
        });
      } else {
        elLegendWrap.appendChild(elLegend);
      }
      elLegendWrap.classList.add(
        `apexcharts-align-${w.config.legend.horizontalAlign}`
      );
      elLegendWrap.classList.add(
        "apx-legend-position-" + w.config.legend.position
      );
      elLegend.classList.add("apexcharts-legend-series");
      elLegend.style.margin = `${w.config.legend.itemMargin.vertical}px ${w.config.legend.itemMargin.horizontal}px`;
      elLegendWrap.style.width = w.config.legend.width ? w.config.legend.width + "px" : "";
      elLegendWrap.style.height = w.config.legend.height ? w.config.legend.height + "px" : "";
      Graphics.setAttrs(elLegend, {
        rel: i + 1,
        seriesName: Utils$1.escapeString(legendNames[i]),
        "data:collapsed": collapsedSeries || ancillaryCollapsedSeries
      });
      if (collapsedSeries || ancillaryCollapsedSeries) {
        elLegend.classList.add("apexcharts-inactive-legend");
      }
      if (!w.config.legend.onItemClick.toggleDataSeries) {
        elLegend.classList.add("apexcharts-no-click");
      }
    }
    w.dom.elWrap.addEventListener("click", me.onLegendClick, true);
    if (w.config.legend.onItemHover.highlightDataSeries && w.config.legend.customLegendItems.length === 0) {
      w.dom.elWrap.addEventListener("mousemove", me.onLegendHovered, true);
      w.dom.elWrap.addEventListener("mouseout", me.onLegendHovered, true);
    }
    if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled) {
      w.dom.elWrap.addEventListener(
        "keydown",
        me.onLegendKeyDown.bind(me),
        true
      );
    }
  }
  /**
   * @param {number} offsetX
   * @param {number} offsetY
   */
  setLegendWrapXY(offsetX, offsetY) {
    const w = this.w;
    const elLegendWrap = (
      /** @type {HTMLElement} */
      w.dom.elLegendWrap
    );
    const legendHeight = elLegendWrap.clientHeight;
    let x = 0;
    let y = 0;
    if (w.config.legend.position === "bottom") {
      y = w.globals.svgHeight - Math.min(legendHeight, w.globals.svgHeight / 2) - 5;
    } else if (w.config.legend.position === "top") {
      const dim = new Dimensions(this.w, this.ctx);
      const titleH = dim.dimHelpers.getTitleSubtitleCoords("title").height;
      const subtitleH = dim.dimHelpers.getTitleSubtitleCoords("subtitle").height;
      y = (titleH > 0 ? titleH - 10 : 0) + (subtitleH > 0 ? subtitleH - 10 : 0);
    }
    elLegendWrap.style.position = "absolute";
    x = x + offsetX + w.config.legend.offsetX;
    y = y + offsetY + w.config.legend.offsetY;
    elLegendWrap.style.left = x + "px";
    elLegendWrap.style.top = y + "px";
    if (w.config.legend.position === "right") {
      elLegendWrap.style.left = "auto";
      elLegendWrap.style.right = 25 + w.config.legend.offsetX + "px";
    }
    const fixedHeigthWidth = (
      /** @type {const} */
      ["width", "height"]
    );
    fixedHeigthWidth.forEach((hw) => {
      if (elLegendWrap && elLegendWrap.style[hw]) {
        elLegendWrap.style[hw] = parseInt(String(w.config.legend[hw]), 10) + "px";
      }
    });
  }
  legendAlignHorizontal() {
    const w = this.w;
    const elLegendWrap = (
      /** @type {HTMLElement} */
      w.dom.elLegendWrap
    );
    elLegendWrap.style.right = "0";
    const dimensions = new Dimensions(this.w, this.ctx);
    const titleRect = dimensions.dimHelpers.getTitleSubtitleCoords("title");
    const subtitleRect = dimensions.dimHelpers.getTitleSubtitleCoords("subtitle");
    const offsetX = 20;
    let offsetY = 0;
    if (w.config.legend.position === "top") {
      offsetY = titleRect.height + subtitleRect.height + w.config.title.margin + w.config.subtitle.margin - 10;
    }
    this.setLegendWrapXY(offsetX, offsetY);
  }
  legendAlignVertical() {
    const w = this.w;
    const lRect = this.legendHelpers.getLegendDimensions();
    const offsetY = 20;
    let offsetX = 0;
    if (w.config.legend.position === "left") {
      offsetX = 20;
    }
    if (w.config.legend.position === "right") {
      offsetX = w.globals.svgWidth - lRect.clww - 10;
    }
    this.setLegendWrapXY(offsetX, offsetY);
  }
  /**
   * @param {MouseEvent} e
   */
  onLegendHovered(e) {
    var _a;
    const w = this.w;
    const target = (
      /** @type {Element} */
      e.target
    );
    const hoverOverLegend = target.classList.contains("apexcharts-legend-series") || target.classList.contains("apexcharts-legend-text") || target.classList.contains("apexcharts-legend-marker");
    if (w.config.chart.type !== "heatmap" && !this.isBarsDistributed) {
      if (!target.classList.contains("apexcharts-inactive-legend") && hoverOverLegend) {
        const series = new Series(this.ctx.w);
        series.toggleSeriesOnHover(e, target);
      }
    } else {
      if (hoverOverLegend) {
        const seriesCnt = parseInt((_a = target.getAttribute("rel")) != null ? _a : "0", 10) - 1;
        this.ctx.events.fireEvent("legendHover", [this.ctx, seriesCnt, this.w]);
        const series = new Series(this.ctx.w);
        series.highlightRangeInSeries(e, target);
      }
    }
  }
  /**
   * @param {KeyboardEvent} e
   */
  onLegendKeyDown(e) {
    const me = this;
    const w = this.w;
    const target = (
      /** @type {Element} */
      e.target
    );
    const isLegendItem = target.classList.contains("apexcharts-legend-series") || target.classList.contains("apexcharts-legend-text") || target.classList.contains("apexcharts-legend-marker");
    if (!isLegendItem) return;
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault();
      const rel = target.getAttribute("rel");
      me.onLegendClick(e);
      if (rel !== null && w.config.legend.onItemClick.toggleDataSeries) {
        requestAnimationFrame(() => {
          const restored = w.dom.baseEl.querySelector(
            `.apexcharts-legend-series[rel="${rel}"]`
          );
          if (restored) restored.focus();
        });
      }
    }
  }
  /**
   * @param {Event} e
   */
  onLegendClick(e) {
    var _a;
    const w = this.w;
    const target = (
      /** @type {Element} */
      e.target
    );
    if (w.config.legend.customLegendItems.length) return;
    if (target.classList.contains("apexcharts-legend-series") || target.classList.contains("apexcharts-legend-text") || target.classList.contains("apexcharts-legend-marker")) {
      const seriesCnt = parseInt((_a = target.getAttribute("rel")) != null ? _a : "0", 10) - 1;
      const isHidden = target.getAttribute("data:collapsed") === "true";
      const legendClick = this.w.config.chart.events.legendClick;
      if (typeof legendClick === "function") {
        legendClick(this.ctx, seriesCnt, this.w);
      }
      this.ctx.events.fireEvent("legendClick", [this.ctx, seriesCnt, this.w]);
      const markerClick = this.w.config.legend.markers.onClick;
      if (typeof markerClick === "function" && target.classList.contains("apexcharts-legend-marker")) {
        markerClick(this.ctx, seriesCnt, this.w);
        this.ctx.events.fireEvent("legendMarkerClick", [
          this.ctx,
          seriesCnt,
          this.w
        ]);
      }
      const clickAllowed = w.config.chart.type !== "treemap" && w.config.chart.type !== "heatmap" && !this.isBarsDistributed;
      if (clickAllowed && w.config.legend.onItemClick.toggleDataSeries) {
        this.legendHelpers.toggleDataSeries(seriesCnt, isHidden);
      }
    }
  }
}
ApexCharts.registerFeatures({ legend: Legend });
const icoPan = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#000000" height="24" viewBox="0 0 24 24" width="24">\n    <defs>\n        <path d="M0 0h24v24H0z" id="a"/>\n    </defs>\n    <clipPath id="b">\n        <use overflow="visible" xlink:href="#a"/>\n    </clipPath>\n    <path clip-path="url(#b)" d="M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z"/>\n</svg>';
const icoZoom = '<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" height="24" viewBox="0 0 24 24" width="24">\n    <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>\n    <path d="M0 0h24v24H0V0z" fill="none"/>\n    <path d="M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z"/>\n</svg>';
const icoReset = '<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">\n    <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>\n    <path d="M0 0h24v24H0z" fill="none"/>\n</svg>';
const icoZoomIn = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n    <path d="M0 0h24v24H0z" fill="none"/>\n    <path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\n</svg>\n';
const icoZoomOut = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n    <path d="M0 0h24v24H0z" fill="none"/>\n    <path d="M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\n</svg>\n';
const icoSelect = '<svg fill="#6E8192" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">\n    <path d="M0 0h24v24H0z" fill="none"/>\n    <path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2z"/>\n</svg>';
const icoMenu = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>';
class Toolbar {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
    this.ev = this.w.config.chart.events;
    this.selectedClass = "apexcharts-selected";
    this.localeValues = this.w.globals.locale.toolbar;
    this.minX = w.globals.minX;
    this.maxX = w.globals.maxX;
    this.elZoom = null;
    this.elZoomIn = null;
    this.elZoomOut = null;
    this.elPan = null;
    this.elSelection = null;
    this.elZoomReset = null;
    this.elMenuIcon = null;
    this.elMenu = null;
    this.elMenuItems = [];
    this.t = null;
  }
  createToolbar() {
    const w = this.w;
    const createDiv = () => {
      return BrowserAPIs.createElementNS("http://www.w3.org/1999/xhtml", "div");
    };
    const createBtn = () => {
      const btn = (
        /** @type {HTMLButtonElement} */
        BrowserAPIs.createElementNS("http://www.w3.org/1999/xhtml", "button")
      );
      btn.setAttribute("type", "button");
      return btn;
    };
    const elToolbarWrap = createDiv();
    elToolbarWrap.setAttribute("class", "apexcharts-toolbar");
    elToolbarWrap.style.top = w.config.chart.toolbar.offsetY + "px";
    elToolbarWrap.style.right = -w.config.chart.toolbar.offsetX + 3 + "px";
    w.dom.elWrap.appendChild(elToolbarWrap);
    this.elZoom = createBtn();
    this.elZoomIn = createBtn();
    this.elZoomOut = createBtn();
    this.elPan = createBtn();
    this.elSelection = createBtn();
    this.elZoomReset = createBtn();
    this.elMenuIcon = createBtn();
    this.elMenu = createDiv();
    this.elCustomIcons = [];
    this.t = w.config.chart.toolbar.tools;
    if (Array.isArray(this.t.customIcons)) {
      for (let i = 0; i < this.t.customIcons.length; i++) {
        this.elCustomIcons.push(createBtn());
      }
    }
    const toolbarControls = [];
    const appendZoomControl = (type, el, ico) => {
      const tool = type.toLowerCase();
      if (this.t[tool] && w.config.chart.zoom.enabled) {
        toolbarControls.push({
          el,
          icon: typeof this.t[tool] === "string" ? this.t[tool] : ico,
          title: (
            /** @type {any} */
            this.localeValues[type]
          ),
          class: `apexcharts-${tool}-icon`
        });
      }
    };
    appendZoomControl("zoomIn", this.elZoomIn, icoZoomIn);
    appendZoomControl("zoomOut", this.elZoomOut, icoZoomOut);
    const zoomSelectionCtrls = (z) => {
      if (this.t[z] && w.config.chart[z].enabled) {
        toolbarControls.push({
          el: z === "zoom" ? this.elZoom : this.elSelection,
          icon: typeof this.t[z] === "string" ? this.t[z] : z === "zoom" ? icoZoom : icoSelect,
          title: (
            /** @type {any} */
            this.localeValues[z === "zoom" ? "selectionZoom" : "selection"]
          ),
          class: `apexcharts-${z}-icon`
        });
      }
    };
    zoomSelectionCtrls("zoom");
    zoomSelectionCtrls("selection");
    if (this.t.pan && w.config.chart.zoom.enabled) {
      toolbarControls.push({
        el: this.elPan,
        icon: typeof this.t.pan === "string" ? this.t.pan : icoPan,
        title: this.localeValues.pan,
        class: "apexcharts-pan-icon"
      });
    }
    appendZoomControl("reset", this.elZoomReset, icoReset);
    if (this.t.download) {
      toolbarControls.push({
        el: this.elMenuIcon,
        icon: typeof this.t.download === "string" ? this.t.download : icoMenu,
        title: this.localeValues.menu,
        class: "apexcharts-menu-icon"
      });
    }
    for (let i = 0; i < this.elCustomIcons.length; i++) {
      toolbarControls.push({
        el: this.elCustomIcons[i],
        icon: this.t.customIcons[i].icon,
        title: this.t.customIcons[i].title,
        index: this.t.customIcons[i].index,
        class: "apexcharts-toolbar-custom-icon " + this.t.customIcons[i].class
      });
    }
    toolbarControls.forEach((t, index) => {
      if (t.index) {
        Utils$1.moveIndexInArray(toolbarControls, index, t.index);
      }
    });
    for (let i = 0; i < toolbarControls.length; i++) {
      Graphics.setAttrs(toolbarControls[i].el, {
        class: toolbarControls[i].class,
        title: toolbarControls[i].title,
        "aria-label": toolbarControls[i].title
      });
      toolbarControls[i].el.innerHTML = toolbarControls[i].icon;
      elToolbarWrap.appendChild(toolbarControls[i].el);
    }
    if (this.elZoom.parentNode) {
      this.elZoom.setAttribute("aria-pressed", String(!!w.interact.zoomEnabled));
    }
    if (this.elSelection.parentNode) {
      this.elSelection.setAttribute(
        "aria-pressed",
        String(!!w.interact.selectionEnabled)
      );
    }
    if (this.elPan.parentNode) {
      this.elPan.setAttribute("aria-pressed", String(!!w.interact.panEnabled));
    }
    if (this.elMenuIcon.parentNode) {
      this.elMenuIcon.setAttribute("aria-haspopup", "true");
      this.elMenuIcon.setAttribute("aria-expanded", "false");
    }
    this._createHamburgerMenu(elToolbarWrap);
    if (w.interact.zoomEnabled) {
      this.elZoom.classList.add(this.selectedClass);
    } else if (w.interact.panEnabled) {
      this.elPan.classList.add(this.selectedClass);
    } else if (w.interact.selectionEnabled) {
      this.elSelection.classList.add(this.selectedClass);
    }
    this.addToolbarEventListeners();
  }
  /**
   * @param {Element} parent
   */
  _createHamburgerMenu(parent) {
    this.elMenuItems = [];
    parent.appendChild(
      /** @type {Node} */
      this.elMenu
    );
    Graphics.setAttrs(this.elMenu, {
      class: "apexcharts-menu",
      role: "menu"
    });
    const menuItems = [
      {
        name: "exportSVG",
        title: this.localeValues.exportToSVG
      },
      {
        name: "exportPNG",
        title: this.localeValues.exportToPNG
      },
      {
        name: "exportCSV",
        title: this.localeValues.exportToCSV
      }
    ];
    for (let i = 0; i < menuItems.length; i++) {
      this.elMenuItems.push(
        BrowserAPIs.createElementNS("http://www.w3.org/1999/xhtml", "div")
      );
      this.elMenuItems[i].innerHTML = menuItems[i].title;
      Graphics.setAttrs(this.elMenuItems[i], {
        class: `apexcharts-menu-item ${menuItems[i].name}`,
        title: menuItems[i].title,
        role: "menuitem",
        tabindex: "-1"
      });
      this.elMenu.appendChild(this.elMenuItems[i]);
    }
  }
  addToolbarEventListeners() {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    (_a = this.elZoomReset) == null ? void 0 : _a.addEventListener("click", this.handleZoomReset.bind(this));
    (_b = this.elSelection) == null ? void 0 : _b.addEventListener(
      "click",
      this.toggleZoomSelection.bind(this, "selection")
    );
    (_c = this.elZoom) == null ? void 0 : _c.addEventListener(
      "click",
      this.toggleZoomSelection.bind(this, "zoom")
    );
    (_d = this.elZoomIn) == null ? void 0 : _d.addEventListener("click", this.handleZoomIn.bind(this));
    (_e = this.elZoomOut) == null ? void 0 : _e.addEventListener("click", this.handleZoomOut.bind(this));
    (_f = this.elPan) == null ? void 0 : _f.addEventListener("click", this.togglePanning.bind(this));
    (_g = this.elMenuIcon) == null ? void 0 : _g.addEventListener("click", this.toggleMenu.bind(this));
    this.elMenuItems.forEach((m) => {
      if (m.classList.contains("exportSVG")) {
        m.addEventListener("click", this.handleDownload.bind(this, "svg"));
      } else if (m.classList.contains("exportPNG")) {
        m.addEventListener("click", this.handleDownload.bind(this, "png"));
      } else if (m.classList.contains("exportCSV")) {
        m.addEventListener("click", this.handleDownload.bind(this, "csv"));
      }
    });
    for (let i = 0; i < this.t.customIcons.length; i++) {
      this.elCustomIcons[i].addEventListener(
        "click",
        this.t.customIcons[i].click.bind(this, this.ctx, this.ctx.w)
      );
    }
    const toolbarButtons = [
      this.elZoomReset,
      this.elSelection,
      this.elZoom,
      this.elZoomIn,
      this.elZoomOut,
      this.elPan,
      this.elMenuIcon,
      ...this.elCustomIcons
    ];
    toolbarButtons.forEach((btn) => {
      btn.addEventListener("keydown", (e) => {
        if (e.key === "Enter" || e.key === " ") {
          e.preventDefault();
          const btnClass = btn.className;
          btn.click();
          requestAnimationFrame(() => {
            const baseEl = this.w.dom.baseEl;
            if (!baseEl) return;
            const apexClass = btnClass.split(" ").find((c) => c.startsWith("apexcharts-"));
            if (!apexClass) return;
            const restored = baseEl.querySelector(`.${apexClass}`);
            if (restored) restored.focus();
          });
        }
      });
    });
    (_h = this.elMenuIcon) == null ? void 0 : _h.addEventListener(
      "keydown",
      (e) => {
        var _a2;
        if (e.key === "ArrowDown" || e.key === "ArrowUp") {
          e.preventDefault();
          if (!((_a2 = this.elMenu) == null ? void 0 : _a2.classList.contains("apexcharts-menu-open"))) {
            this.toggleMenu();
          }
          window.setTimeout(() => {
            const idx = e.key === "ArrowDown" ? 0 : this.elMenuItems.length - 1;
            if (this.elMenuItems[idx])
              this.elMenuItems[idx].focus();
          }, 20);
        }
      }
    );
    this.elMenuItems.forEach((m, idx) => {
      m.addEventListener("keydown", (e) => {
        var _a2;
        if (e.key === "ArrowDown") {
          e.preventDefault();
          const next = this.elMenuItems[idx + 1] || this.elMenuItems[0];
          next.focus();
        } else if (e.key === "ArrowUp") {
          e.preventDefault();
          const prev = this.elMenuItems[idx - 1] || this.elMenuItems[this.elMenuItems.length - 1];
          prev.focus();
        } else if (e.key === "Escape" || e.key === "Tab") {
          this._closeMenu();
          (_a2 = this.elMenuIcon) == null ? void 0 : _a2.focus();
          if (e.key === "Tab") ;
          else {
            e.preventDefault();
          }
        } else if (e.key === "Enter" || e.key === " ") {
          e.preventDefault();
          m.click();
        }
      });
    });
  }
  /**
   * @param {string} type
   */
  toggleZoomSelection(type) {
    const charts = this.ctx.getSyncedCharts();
    charts.forEach((ch) => {
      ch.ctx.toolbar.toggleOtherControls();
      const el = type === "selection" ? ch.ctx.toolbar.elSelection : ch.ctx.toolbar.elZoom;
      const enabledType = type === "selection" ? "selectionEnabled" : "zoomEnabled";
      ch.w.globals[enabledType] = !ch.w.globals[enabledType];
      if (!el.classList.contains(ch.ctx.toolbar.selectedClass)) {
        el.classList.add(ch.ctx.toolbar.selectedClass);
      } else {
        el.classList.remove(ch.ctx.toolbar.selectedClass);
      }
      el.setAttribute("aria-pressed", String(ch.w.globals[enabledType]));
    });
  }
  getToolbarIconsReference() {
    const w = this.w;
    if (!this.elZoom) {
      this.elZoom = w.dom.baseEl.querySelector(".apexcharts-zoom-icon");
    }
    if (!this.elPan) {
      this.elPan = w.dom.baseEl.querySelector(".apexcharts-pan-icon");
    }
    if (!this.elSelection) {
      this.elSelection = w.dom.baseEl.querySelector(
        ".apexcharts-selection-icon"
      );
    }
  }
  /**
   * @param {string} type
   */
  enableZoomPanFromToolbar(type) {
    this.toggleOtherControls();
    type === "pan" ? this.w.interact.panEnabled = true : this.w.interact.zoomEnabled = true;
    const el = type === "pan" ? this.elPan : this.elZoom;
    const el2 = type === "pan" ? this.elZoom : this.elPan;
    if (el) {
      el.classList.add(this.selectedClass);
    }
    if (el2) {
      el2.classList.remove(this.selectedClass);
    }
  }
  togglePanning() {
    const charts = this.ctx.getSyncedCharts();
    charts.forEach((ch) => {
      ch.ctx.toolbar.toggleOtherControls();
      ch.w.interact.panEnabled = !ch.w.interact.panEnabled;
      if (!ch.ctx.toolbar.elPan.classList.contains(ch.ctx.toolbar.selectedClass)) {
        ch.ctx.toolbar.elPan.classList.add(ch.ctx.toolbar.selectedClass);
      } else {
        ch.ctx.toolbar.elPan.classList.remove(ch.ctx.toolbar.selectedClass);
      }
      ch.ctx.toolbar.elPan.setAttribute(
        "aria-pressed",
        String(ch.w.interact.panEnabled)
      );
    });
  }
  toggleOtherControls() {
    const w = this.w;
    w.interact.panEnabled = false;
    w.interact.zoomEnabled = false;
    w.interact.selectionEnabled = false;
    this.getToolbarIconsReference();
    const toggleEls = [this.elPan, this.elSelection, this.elZoom];
    toggleEls.forEach((el) => {
      if (el) {
        el.classList.remove(this.selectedClass);
      }
    });
  }
  handleZoomIn() {
    const w = this.w;
    if (w.axisFlags.isRangeBar) {
      this.minX = w.globals.minY;
      this.maxX = w.globals.maxY;
    }
    const centerX = (this.minX + this.maxX) / 2;
    const newMinX = (this.minX + centerX) / 2;
    const newMaxX = (this.maxX + centerX) / 2;
    const newMinXMaxX = this._getNewMinXMaxX(newMinX, newMaxX);
    if (!w.interact.disableZoomIn) {
      this.zoomUpdateOptions(newMinXMaxX.minX, newMinXMaxX.maxX);
    }
  }
  handleZoomOut() {
    const w = this.w;
    if (w.axisFlags.isRangeBar) {
      this.minX = w.globals.minY;
      this.maxX = w.globals.maxY;
    }
    if (w.config.xaxis.type === "datetime" && new Date(this.minX).getUTCFullYear() < 1e3) {
      return;
    }
    const centerX = (this.minX + this.maxX) / 2;
    const newMinX = this.minX - (centerX - this.minX);
    const newMaxX = this.maxX - (centerX - this.maxX);
    const newMinXMaxX = this._getNewMinXMaxX(newMinX, newMaxX);
    if (!w.interact.disableZoomOut) {
      this.zoomUpdateOptions(newMinXMaxX.minX, newMinXMaxX.maxX);
    }
  }
  /**
   * @param {number} newMinX
   * @param {number} newMaxX
   */
  _getNewMinXMaxX(newMinX, newMaxX) {
    const shouldFloor = this.w.config.xaxis.convertedCatToNumeric;
    return {
      minX: shouldFloor ? Math.floor(newMinX) : newMinX,
      maxX: shouldFloor ? Math.floor(newMaxX) : newMaxX
    };
  }
  /**
   * @param {number} newMinX
   * @param {number} newMaxX
   */
  zoomUpdateOptions(newMinX, newMaxX) {
    const w = this.w;
    if (newMinX === void 0 && newMaxX === void 0) {
      this.handleZoomReset();
      return;
    }
    if (w.config.xaxis.convertedCatToNumeric) {
      if (newMinX < 1) {
        newMinX = 1;
        newMaxX = w.globals.dataPoints;
      }
      if (newMaxX - newMinX < 2) {
        return;
      }
    }
    let xaxis = {
      min: newMinX,
      max: newMaxX
    };
    const beforeZoomRange = this.getBeforeZoomRange(
      xaxis,
      /** @type {any} */
      void 0
    );
    if (beforeZoomRange) {
      xaxis = beforeZoomRange.xaxis;
    }
    const options2 = {
      xaxis
    };
    if (!w.globals.initialConfig) return;
    const yaxis = Utils$1.clone(w.globals.initialConfig.yaxis);
    if (!w.config.chart.group) {
      options2.yaxis = yaxis;
    }
    this.w.interact.zoomed = true;
    this.ctx.updateHelpers._updateOptions(
      options2,
      false,
      this.w.config.chart.animations.dynamicAnimation.enabled
    );
    this.zoomCallback(xaxis, yaxis);
  }
  /**
   * @param {Record<string, any>} xaxis
   * @param {Record<string, any>} yaxis
   */
  zoomCallback(xaxis, yaxis) {
    if (typeof this.ev.zoomed === "function") {
      this.ev.zoomed(this.ctx, { xaxis, yaxis });
      this.ctx.events.fireEvent("zoomed", { xaxis, yaxis });
    }
  }
  /**
   * @param {Record<string, any>} xaxis
   * @param {Record<string, any>} yaxis
   */
  getBeforeZoomRange(xaxis, yaxis) {
    let newRange = null;
    if (typeof this.ev.beforeZoom === "function") {
      newRange = this.ev.beforeZoom(this, { xaxis, yaxis });
    }
    return newRange;
  }
  toggleMenu() {
    window.setTimeout(() => {
      var _a, _b, _c;
      if ((_a = this.elMenu) == null ? void 0 : _a.classList.contains("apexcharts-menu-open")) {
        this._closeMenu();
      } else {
        (_b = this.elMenu) == null ? void 0 : _b.classList.add("apexcharts-menu-open");
        (_c = this.elMenuIcon) == null ? void 0 : _c.setAttribute("aria-expanded", "true");
      }
    }, 0);
  }
  _closeMenu() {
    var _a, _b;
    (_a = this.elMenu) == null ? void 0 : _a.classList.remove("apexcharts-menu-open");
    (_b = this.elMenuIcon) == null ? void 0 : _b.setAttribute("aria-expanded", "false");
  }
  /**
   * @param {string} type
   */
  handleDownload(type) {
    const w = this.w;
    const exprt = new Exports(this.w, this.ctx);
    switch (type) {
      case "svg":
        exprt.exportToSVG();
        break;
      case "png":
        exprt.exportToPng();
        break;
      case "csv":
        exprt.exportToCSV({
          series: w.config.series,
          columnDelimiter: w.config.chart.toolbar.export.csv.columnDelimiter
        });
        break;
    }
  }
  handleZoomReset() {
    const charts = this.ctx.getSyncedCharts();
    charts.forEach((ch) => {
      const w = ch.w;
      if (!w.interact.zoomed) return;
      w.globals.lastXAxis.min = w.globals.initialConfig.xaxis.min;
      w.globals.lastXAxis.max = w.globals.initialConfig.xaxis.max;
      ch.updateHelpers.revertDefaultAxisMinMax();
      if (typeof w.config.chart.events.beforeResetZoom === "function") {
        const resetZoomRange = w.config.chart.events.beforeResetZoom(ch, w);
        if (resetZoomRange) {
          ch.updateHelpers.revertDefaultAxisMinMax(resetZoomRange);
        }
      }
      if (typeof w.config.chart.events.zoomed === "function") {
        ch.ctx.toolbar.zoomCallback({
          min: w.config.xaxis.min,
          max: w.config.xaxis.max
        });
      }
      const series = ch.ctx.series.emptyCollapsedSeries(
        Utils$1.clone(w.globals.initialSeries)
      );
      ch.updateHelpers._updateSeries(
        series,
        w.config.chart.animations.dynamicAnimation.enabled
      );
      w.interact.zoomed = false;
    });
  }
  destroy() {
    this.elZoom = null;
    this.elZoomIn = null;
    this.elZoomOut = null;
    this.elPan = null;
    this.elSelection = null;
    this.elZoomReset = null;
    this.elMenuIcon = null;
  }
}
class ZoomPanSelection extends Toolbar {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    super(w, ctx);
    this.w = w;
    this.ctx = ctx;
    this.dragged = false;
    this.graphics = new Graphics(this.w);
    this.eventList = [
      "mousedown",
      "mouseleave",
      "mousemove",
      "touchstart",
      "touchmove",
      "mouseup",
      "touchend",
      "wheel"
    ];
    this.clientX = 0;
    this.clientY = 0;
    this.startX = 0;
    this.endX = 0;
    this.dragX = 0;
    this.startY = 0;
    this.endY = 0;
    this.dragY = 0;
    this.moveDirection = "none";
    this.debounceTimer = null;
    this.debounceDelay = 100;
    this.wheelDelay = 400;
  }
  /** @param {{xyRatios: any}} opts */
  init({ xyRatios }) {
    const w = this.w;
    const me = this;
    this.xyRatios = xyRatios;
    this.zoomRect = this.graphics.drawRect(0, 0, 0, 0);
    this.selectionRect = this.graphics.drawRect(0, 0, 0, 0);
    this.gridRect = w.dom.baseEl.querySelector(".apexcharts-grid");
    this.constraints = new Box(0, 0, w.layout.gridWidth, w.layout.gridHeight);
    this.zoomRect.node.classList.add("apexcharts-zoom-rect");
    this.selectionRect.node.classList.add("apexcharts-selection-rect");
    w.dom.Paper.add(this.zoomRect);
    w.dom.Paper.add(this.selectionRect);
    if (w.config.chart.selection.type === "x") {
      this.slDraggableRect = this.selectionRect.draggable({
        minX: 0,
        minY: 0,
        maxX: w.layout.gridWidth,
        maxY: w.layout.gridHeight
      }).on("dragmove.namespace", this.selectionDragging.bind(this, "dragging"));
    } else if (w.config.chart.selection.type === "y") {
      this.slDraggableRect = this.selectionRect.draggable({
        minX: 0,
        maxX: w.layout.gridWidth
      }).on("dragmove.namespace", this.selectionDragging.bind(this, "dragging"));
    } else {
      this.slDraggableRect = this.selectionRect.draggable().on("dragmove.namespace", this.selectionDragging.bind(this, "dragging"));
    }
    this.preselectedSelection();
    this.hoverArea = /** @type {Element} */
    w.dom.baseEl.querySelector(`${w.globals.chartClass} .apexcharts-svg`);
    if (!this.hoverArea) return;
    this.hoverArea.classList.add("apexcharts-zoomable");
    this.eventList.forEach((event) => {
      var _a;
      (_a = this.hoverArea) == null ? void 0 : _a.addEventListener(
        event,
        me.svgMouseEvents.bind(me, xyRatios),
        {
          capture: false,
          passive: true
        }
      );
    });
    if (w.config.chart.zoom.enabled && w.config.chart.zoom.allowMouseWheelZoom) {
      this.hoverArea.addEventListener("wheel", me.mouseWheelEvent.bind(me), {
        capture: false,
        passive: false
      });
    }
  }
  // remove the event listeners which were previously added on hover area
  destroy() {
    if (this.slDraggableRect) {
      this.slDraggableRect.draggable(false);
      this.slDraggableRect.off();
      this.selectionRect.off();
    }
    this.selectionRect = null;
    this.zoomRect = null;
    this.gridRect = null;
  }
  /**
   * @param {import('../types/internal').XYRatios} xyRatios
   * @param {any} e
   */
  svgMouseEvents(xyRatios, e) {
    var _a;
    const w = this.w;
    const toolbar = this.ctx.toolbar;
    const zoomtype = w.interact.zoomEnabled ? w.config.chart.zoom.type : w.config.chart.selection.type;
    const autoSelected = w.config.chart.toolbar.autoSelected;
    if (e.shiftKey) {
      this.shiftWasPressed = true;
      toolbar.enableZoomPanFromToolbar(autoSelected === "pan" ? "zoom" : "pan");
    } else {
      if (this.shiftWasPressed) {
        toolbar.enableZoomPanFromToolbar(autoSelected);
        this.shiftWasPressed = false;
      }
    }
    if (!e.target) return;
    const tc = e.target.classList;
    let pc;
    if (e.target.parentNode && e.target.parentNode !== null) {
      pc = e.target.parentNode.classList;
    }
    const falsePositives = tc.contains("apexcharts-legend-marker") || tc.contains("apexcharts-legend-text") || pc && pc.contains("apexcharts-toolbar");
    if (falsePositives) return;
    this.clientX = e.type === "touchmove" || e.type === "touchstart" ? e.touches[0].clientX : e.type === "touchend" ? e.changedTouches[0].clientX : e.clientX;
    this.clientY = e.type === "touchmove" || e.type === "touchstart" ? e.touches[0].clientY : e.type === "touchend" ? e.changedTouches[0].clientY : e.clientY;
    if (e.type === "mousedown" && e.which === 1 || e.type === "touchstart") {
      const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
      if (!gridRectDim) return;
      this.startX = this.clientX - gridRectDim.left - w.globals.barPadForNumericAxis;
      this.startY = this.clientY - gridRectDim.top;
      this.dragged = false;
      this.w.interact.mousedown = true;
    }
    if (e.type === "mousemove" && e.which === 1 || e.type === "touchmove") {
      this.dragged = true;
      if (w.interact.panEnabled) {
        w.interact.selection = null;
        if (this.w.interact.mousedown) {
          this.panDragging({
            context: this,
            zoomtype,
            xyRatios
          });
        }
      } else {
        if (this.w.interact.mousedown && w.interact.zoomEnabled || this.w.interact.mousedown && w.interact.selectionEnabled) {
          this.selection = this.selectionDrawing({
            context: this,
            zoomtype
          });
        }
      }
    }
    if (e.type === "mouseup" || e.type === "touchend" || e.type === "mouseleave") {
      this.handleMouseUp({ zoomtype });
    }
    this.makeSelectionRectDraggable();
  }
  /** @param {{ zoomtype?: any, isResized?: any }} opts */
  handleMouseUp({ zoomtype, isResized }) {
    var _a;
    const w = this.w;
    const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
    if (gridRectDim && (this.w.interact.mousedown || isResized)) {
      this.endX = this.clientX - gridRectDim.left - w.globals.barPadForNumericAxis;
      this.endY = this.clientY - gridRectDim.top;
      this.dragX = Math.abs(this.endX - this.startX);
      this.dragY = Math.abs(this.endY - this.startY);
      if (w.interact.zoomEnabled || w.interact.selectionEnabled) {
        this.selectionDrawn({
          context: this,
          zoomtype
        });
      }
    }
    if (w.interact.zoomEnabled) {
      this.hideSelectionRect(this.selectionRect);
    }
    this.dragged = false;
    this.w.interact.mousedown = false;
  }
  /**
   * @param {Event} e
   */
  mouseWheelEvent(e) {
    const w = this.w;
    e.preventDefault();
    const now = Date.now();
    if (now - w.interact.lastWheelExecution > this.wheelDelay) {
      this.executeMouseWheelZoom(e);
      w.interact.lastWheelExecution = now;
    }
    if (this.debounceTimer) clearTimeout(this.debounceTimer);
    this.debounceTimer = setTimeout(() => {
      if (now - w.interact.lastWheelExecution > this.wheelDelay) {
        this.executeMouseWheelZoom(e);
        w.interact.lastWheelExecution = now;
      }
    }, this.debounceDelay);
  }
  /**
   * @param {any} e
   */
  executeMouseWheelZoom(e) {
    var _a;
    const w = this.w;
    this.minX = w.axisFlags.isRangeBar ? w.globals.minY : w.globals.minX;
    this.maxX = w.axisFlags.isRangeBar ? w.globals.maxY : w.globals.maxX;
    const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
    if (!gridRectDim) return;
    const mouseX = (e.clientX - gridRectDim.left) / gridRectDim.width;
    const currentMinX = this.minX;
    const currentMaxX = this.maxX;
    const totalX = currentMaxX - currentMinX;
    const zoomFactorIn = 0.5;
    const zoomFactorOut = 1.5;
    let zoomRange;
    let newMinX, newMaxX;
    if (e.deltaY < 0) {
      zoomRange = zoomFactorIn * totalX;
      const midPoint = currentMinX + mouseX * totalX;
      newMinX = midPoint - zoomRange / 2;
      newMaxX = midPoint + zoomRange / 2;
    } else {
      zoomRange = zoomFactorOut * totalX;
      newMinX = currentMinX - zoomRange / 2;
      newMaxX = currentMaxX + zoomRange / 2;
    }
    if (!w.axisFlags.isRangeBar) {
      newMinX = Math.max(newMinX, w.globals.initialMinX);
      newMaxX = Math.min(newMaxX, w.globals.initialMaxX);
      const minRange = (w.globals.initialMaxX - w.globals.initialMinX) * 0.01;
      if (newMaxX - newMinX < minRange) {
        const midPoint = (newMinX + newMaxX) / 2;
        newMinX = midPoint - minRange / 2;
        newMaxX = midPoint + minRange / 2;
      }
    }
    const newMinXMaxX = this._getNewMinXMaxX(newMinX, newMaxX);
    if (!isNaN(newMinXMaxX.minX) && !isNaN(newMinXMaxX.maxX)) {
      this.zoomUpdateOptions(newMinXMaxX.minX, newMinXMaxX.maxX);
    }
  }
  makeSelectionRectDraggable() {
    const w = this.w;
    if (!this.selectionRect) return;
    const rectDim = this.selectionRect.node.getBoundingClientRect();
    if (rectDim.width > 0 && rectDim.height > 0) {
      this.selectionRect.select(false).resize(false);
      this.selectionRect.select({
        createRot: () => {
        },
        updateRot: () => {
        },
        createHandle: (group, p, index, pointArr, handleName) => {
          if (handleName === "l" || handleName === "r")
            return group.circle(8).css({ "stroke-width": 1, stroke: "#333", fill: "#fff" });
          return group.circle(0);
        },
        updateHandle: (group, p) => {
          return group.center(p[0], p[1]);
        }
      }).resize().on("resize", () => {
        const zoomtype = w.interact.zoomEnabled ? w.config.chart.zoom.type : w.config.chart.selection.type;
        this.handleMouseUp({ zoomtype, isResized: true });
      });
    }
  }
  preselectedSelection() {
    const w = this.w;
    const xyRatios = this.xyRatios;
    if (!w.interact.zoomEnabled) {
      if (typeof w.interact.selection !== "undefined" && w.interact.selection !== null) {
        this.drawSelectionRect(__spreadProps(__spreadValues({}, w.interact.selection), {
          translateX: w.layout.translateX,
          translateY: w.layout.translateY
        }));
      } else {
        if (w.config.chart.selection.xaxis.min !== void 0 && w.config.chart.selection.xaxis.max !== void 0) {
          let x = (w.config.chart.selection.xaxis.min - w.globals.minX) / xyRatios.xRatio;
          let width = w.layout.gridWidth - (w.globals.maxX - w.config.chart.selection.xaxis.max) / xyRatios.xRatio - x;
          if (w.axisFlags.isRangeBar) {
            x = (w.config.chart.selection.xaxis.min - w.globals.yAxisScale[0].niceMin) / xyRatios.invertedYRatio;
            width = (w.config.chart.selection.xaxis.max - w.config.chart.selection.xaxis.min) / xyRatios.invertedYRatio;
          }
          const selectionRect = {
            x,
            y: 0,
            width,
            height: w.layout.gridHeight,
            translateX: w.layout.translateX,
            translateY: w.layout.translateY,
            selectionEnabled: true
          };
          this.drawSelectionRect(selectionRect);
          this.makeSelectionRectDraggable();
          if (typeof w.config.chart.events.selection === "function") {
            w.config.chart.events.selection(this.ctx, {
              xaxis: {
                min: w.config.chart.selection.xaxis.min,
                max: w.config.chart.selection.xaxis.max
              },
              yaxis: {}
            });
          }
        }
      }
    }
  }
  /** @param {{x: any, y: any, width: any, height: any, translateX: any, translateY: any}} opts */
  drawSelectionRect({ x, y, width, height, translateX = 0, translateY = 0 }) {
    const w = this.w;
    const zoomRect = this.zoomRect;
    const selectionRect = this.selectionRect;
    if (this.dragged || w.interact.selection !== null) {
      const scalingAttrs = {
        transform: "translate(" + translateX + ", " + translateY + ")"
      };
      if (w.interact.zoomEnabled && this.dragged) {
        if (width < 0) width = 1;
        zoomRect.attr({
          x,
          y,
          width,
          height,
          fill: w.config.chart.zoom.zoomedArea.fill.color,
          "fill-opacity": w.config.chart.zoom.zoomedArea.fill.opacity,
          stroke: w.config.chart.zoom.zoomedArea.stroke.color,
          "stroke-width": w.config.chart.zoom.zoomedArea.stroke.width,
          "stroke-opacity": w.config.chart.zoom.zoomedArea.stroke.opacity
        });
        Graphics.setAttrs(zoomRect.node, scalingAttrs);
      }
      if (w.interact.selectionEnabled) {
        selectionRect.attr({
          x,
          y,
          width: width > 0 ? width : 0,
          height: height > 0 ? height : 0,
          fill: w.config.chart.selection.fill.color,
          "fill-opacity": w.config.chart.selection.fill.opacity,
          stroke: w.config.chart.selection.stroke.color,
          "stroke-width": w.config.chart.selection.stroke.width,
          "stroke-dasharray": w.config.chart.selection.stroke.dashArray,
          "stroke-opacity": w.config.chart.selection.stroke.opacity
        });
        Graphics.setAttrs(selectionRect.node, scalingAttrs);
      }
    }
  }
  /**
   * @param {any} rect
   */
  hideSelectionRect(rect) {
    if (rect) {
      rect.attr({
        x: 0,
        y: 0,
        width: 0,
        height: 0
      });
    }
  }
  selectionDrawing({ context, zoomtype }) {
    var _a;
    const w = this.w;
    const me = context;
    const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
    if (!gridRectDim) return;
    const startX = me.startX - 1;
    const startY = me.startY;
    let inversedX = false;
    let inversedY = false;
    const left = me.clientX - gridRectDim.left - w.globals.barPadForNumericAxis;
    const top = me.clientY - gridRectDim.top;
    let selectionWidth = left - startX;
    let selectionHeight = top - startY;
    let selectionRect = {
      translateX: w.layout.translateX,
      translateY: w.layout.translateY
    };
    if (Math.abs(selectionWidth + startX) > w.layout.gridWidth) {
      selectionWidth = w.layout.gridWidth - startX;
    } else if (left < 0) {
      selectionWidth = startX;
    }
    if (startX > left) {
      inversedX = true;
      selectionWidth = Math.abs(selectionWidth);
    }
    if (startY > top) {
      inversedY = true;
      selectionHeight = Math.abs(selectionHeight);
    }
    if (zoomtype === "x") {
      selectionRect = {
        x: inversedX ? startX - selectionWidth : startX,
        y: 0,
        width: selectionWidth,
        height: w.layout.gridHeight
      };
    } else if (zoomtype === "y") {
      selectionRect = {
        x: 0,
        y: inversedY ? startY - selectionHeight : startY,
        width: w.layout.gridWidth,
        height: selectionHeight
      };
    } else {
      selectionRect = {
        x: inversedX ? startX - selectionWidth : startX,
        y: inversedY ? startY - selectionHeight : startY,
        width: selectionWidth,
        height: selectionHeight
      };
    }
    selectionRect = __spreadProps(__spreadValues({}, selectionRect), {
      translateX: w.layout.translateX,
      translateY: w.layout.translateY
    });
    me.drawSelectionRect(selectionRect);
    me.selectionDragging("resizing");
    return selectionRect;
  }
  /**
   * @param {string} type
   * @param {CustomEvent} e
   */
  selectionDragging(type, e) {
    var _a;
    const w = this.w;
    if (!e) return;
    e.preventDefault();
    const { handler, box } = e.detail;
    const constraints = (
      /** @type {any} */
      this.constraints
    );
    let { x, y } = box;
    if (x < constraints.x) {
      x = constraints.x;
    }
    if (y < constraints.y) {
      y = constraints.y;
    }
    if (box.x2 > constraints.x2) {
      x = constraints.x2 - box.w;
    }
    if (box.y2 > constraints.y2) {
      y = constraints.y2 - box.h;
    }
    handler.move(x, y);
    const xyRatios = this.xyRatios;
    const selRect = this.selectionRect;
    let timerInterval = 0;
    if (type === "resizing") {
      timerInterval = 30;
    }
    const getSelAttr = (attr) => {
      return parseFloat(selRect.node.getAttribute(attr));
    };
    const draggedProps = {
      x: getSelAttr("x"),
      y: getSelAttr("y"),
      width: getSelAttr("width"),
      height: getSelAttr("height")
    };
    w.interact.selection = draggedProps;
    if (typeof w.config.chart.events.selection === "function" && w.interact.selectionEnabled) {
      clearTimeout((_a = this.w.globals.selectionResizeTimer) != null ? _a : void 0);
      this.w.globals.selectionResizeTimer = window.setTimeout(() => {
        var _a2;
        const gridRectDim = (_a2 = this.gridRect) == null ? void 0 : _a2.getBoundingClientRect();
        if (!gridRectDim) return;
        const selectionRect = selRect.node.getBoundingClientRect();
        let minX, maxX, minY, maxY;
        if (!w.axisFlags.isRangeBar) {
          if (!w.globals.xAxisScale) return;
          minX = w.globals.xAxisScale.niceMin + (selectionRect.left - gridRectDim.left) * xyRatios.xRatio;
          maxX = w.globals.xAxisScale.niceMin + (selectionRect.right - gridRectDim.left) * xyRatios.xRatio;
          minY = w.globals.yAxisScale[0].niceMin + (gridRectDim.bottom - selectionRect.bottom) * xyRatios.yRatio[0];
          maxY = w.globals.yAxisScale[0].niceMax - (selectionRect.top - gridRectDim.top) * xyRatios.yRatio[0];
        } else {
          minX = w.globals.yAxisScale[0].niceMin + (selectionRect.left - gridRectDim.left) * xyRatios.invertedYRatio;
          maxX = w.globals.yAxisScale[0].niceMin + (selectionRect.right - gridRectDim.left) * xyRatios.invertedYRatio;
          minY = 0;
          maxY = 1;
        }
        const xyAxis = {
          xaxis: {
            min: minX,
            max: maxX
          },
          yaxis: {
            min: minY,
            max: maxY
          }
        };
        w.config.chart.events.selection(this.ctx, xyAxis);
        if (w.config.chart.brush.enabled && w.config.chart.events.brushScrolled !== void 0) {
          w.config.chart.events.brushScrolled(this.ctx, xyAxis);
        }
      }, timerInterval);
    }
  }
  /** @param {{context: any, zoomtype: any}} opts */
  selectionDrawn({ context, zoomtype }) {
    var _a, _b;
    const w = this.w;
    const me = context;
    const xyRatios = this.xyRatios;
    const toolbar = this.ctx.toolbar;
    const selRect = w.interact.zoomEnabled ? me.zoomRect.node.getBoundingClientRect() : me.selectionRect.node.getBoundingClientRect();
    const gridRectDim = me.gridRect.getBoundingClientRect();
    const localStartX = selRect.left - gridRectDim.left - w.globals.barPadForNumericAxis;
    const localEndX = selRect.right - gridRectDim.left - w.globals.barPadForNumericAxis;
    const localStartY = selRect.top - gridRectDim.top;
    const localEndY = selRect.bottom - gridRectDim.top;
    let xLowestValue, xHighestValue;
    if (!w.axisFlags.isRangeBar) {
      const niceMin = (_b = (_a = w.globals.xAxisScale) == null ? void 0 : _a.niceMin) != null ? _b : 0;
      xLowestValue = niceMin + localStartX * xyRatios.xRatio;
      xHighestValue = niceMin + localEndX * xyRatios.xRatio;
    } else {
      xLowestValue = w.globals.yAxisScale[0].niceMin + localStartX * xyRatios.invertedYRatio;
      xHighestValue = w.globals.yAxisScale[0].niceMin + localEndX * xyRatios.invertedYRatio;
    }
    const yHighestValue = [];
    const yLowestValue = [];
    w.config.yaxis.forEach((yaxe, index) => {
      const seriesIndex = w.globals.seriesYAxisMap[index][0];
      const highestVal = w.globals.yAxisScale[index].niceMax - xyRatios.yRatio[seriesIndex] * localStartY;
      const lowestVal = w.globals.yAxisScale[index].niceMax - xyRatios.yRatio[seriesIndex] * localEndY;
      yHighestValue.push(highestVal);
      yLowestValue.push(lowestVal);
    });
    if (me.dragged && (me.dragX > 10 || me.dragY > 10) && xLowestValue !== xHighestValue) {
      if (w.interact.zoomEnabled) {
        if (!w.globals.initialConfig) return;
        let yaxis = Utils$1.clone(w.globals.initialConfig.yaxis);
        let xaxis = Utils$1.clone(w.globals.initialConfig.xaxis);
        w.interact.zoomed = true;
        if (w.config.xaxis.convertedCatToNumeric) {
          xLowestValue = Math.floor(xLowestValue);
          xHighestValue = Math.floor(xHighestValue);
          if (xLowestValue < 1) {
            xLowestValue = 1;
            xHighestValue = w.globals.dataPoints;
          }
          if (xHighestValue - xLowestValue < 2) {
            xHighestValue = xLowestValue + 1;
          }
        }
        if (zoomtype === "xy" || zoomtype === "x") {
          xaxis = {
            min: xLowestValue,
            max: xHighestValue
          };
        }
        if (zoomtype === "xy" || zoomtype === "y") {
          yaxis.forEach((yaxe, index) => {
            yaxis[index].min = yLowestValue[index];
            yaxis[index].max = yHighestValue[index];
          });
        }
        if (toolbar) {
          const beforeZoomRange = toolbar.getBeforeZoomRange(xaxis, yaxis);
          if (beforeZoomRange) {
            xaxis = beforeZoomRange.xaxis ? beforeZoomRange.xaxis : xaxis;
            yaxis = beforeZoomRange.yaxis ? beforeZoomRange.yaxis : yaxis;
          }
        }
        const options2 = {
          xaxis
        };
        if (!w.config.chart.group) {
          options2.yaxis = yaxis;
        }
        me.ctx.updateHelpers._updateOptions(
          options2,
          false,
          me.w.config.chart.animations.dynamicAnimation.enabled
        );
        if (typeof w.config.chart.events.zoomed === "function") {
          toolbar.zoomCallback(xaxis, yaxis);
        }
      } else if (w.interact.selectionEnabled) {
        let yaxis = null;
        let xaxis = null;
        xaxis = {
          min: xLowestValue,
          max: xHighestValue
        };
        if (zoomtype === "xy" || zoomtype === "y") {
          const yaxisCopy = (
            /** @type {ApexYAxis[]} */
            Utils$1.clone(w.config.yaxis)
          );
          yaxis = yaxisCopy;
          yaxisCopy.forEach((yaxe, index) => {
            yaxisCopy[index].min = yLowestValue[index];
            yaxisCopy[index].max = yHighestValue[index];
          });
        }
        w.interact.selection = me.selection;
        if (typeof w.config.chart.events.selection === "function") {
          w.config.chart.events.selection(me.ctx, {
            xaxis,
            yaxis
          });
        }
      }
    }
  }
  /** @param {{ context?: any, zoomtype?: any, xyRatios?: any }} opts */
  panDragging({ context }) {
    var _a;
    const w = this.w;
    const me = context;
    if (typeof w.interact.lastClientPosition.x !== "undefined") {
      const deltaX = w.interact.lastClientPosition.x - me.clientX;
      const deltaY = ((_a = w.interact.lastClientPosition.y) != null ? _a : 0) - me.clientY;
      if (Math.abs(deltaX) > Math.abs(deltaY) && deltaX > 0) {
        this.moveDirection = "left";
      } else if (Math.abs(deltaX) > Math.abs(deltaY) && deltaX < 0) {
        this.moveDirection = "right";
      } else if (Math.abs(deltaY) > Math.abs(deltaX) && deltaY > 0) {
        this.moveDirection = "up";
      } else if (Math.abs(deltaY) > Math.abs(deltaX) && deltaY < 0) {
        this.moveDirection = "down";
      }
    }
    w.interact.lastClientPosition = {
      x: me.clientX,
      y: me.clientY
    };
    const xLowestValue = w.axisFlags.isRangeBar ? w.globals.minY : w.globals.minX;
    const xHighestValue = w.axisFlags.isRangeBar ? w.globals.maxY : w.globals.maxX;
    me.panScrolled(xLowestValue, xHighestValue);
  }
  // delayedPanScrolled() {
  //   const w = this.w
  //   let newMinX = w.globals.minX
  //   let newMaxX = w.globals.maxX
  //   const centerX = (w.globals.maxX - w.globals.minX) / 2
  //   if (this.moveDirection === 'left') {
  //     newMinX = w.globals.minX + centerX
  //     newMaxX = w.globals.maxX + centerX
  //   } else if (this.moveDirection === 'right') {
  //     newMinX = w.globals.minX - centerX
  //     newMaxX = w.globals.maxX - centerX
  //   }
  //   newMinX = Math.floor(newMinX)
  //   newMaxX = Math.floor(newMaxX)
  //   this.updateScrolledChart(
  //     { xaxis: { min: newMinX, max: newMaxX } },
  //     newMinX,
  //     newMaxX
  //   )
  // }
  /**
   * @param {number} xLowestValue
   * @param {number} xHighestValue
   */
  panScrolled(xLowestValue, xHighestValue) {
    const w = this.w;
    const xyRatios = this.xyRatios;
    if (!w.globals.initialConfig) return;
    const yaxis = Utils$1.clone(w.globals.initialConfig.yaxis);
    let xRatio = xyRatios.xRatio;
    let minX = w.globals.minX;
    let maxX = w.globals.maxX;
    if (w.axisFlags.isRangeBar) {
      xRatio = xyRatios.invertedYRatio;
      minX = w.globals.minY;
      maxX = w.globals.maxY;
    }
    if (this.moveDirection === "left") {
      xLowestValue = minX + w.layout.gridWidth / 15 * xRatio;
      xHighestValue = maxX + w.layout.gridWidth / 15 * xRatio;
    } else if (this.moveDirection === "right") {
      xLowestValue = minX - w.layout.gridWidth / 15 * xRatio;
      xHighestValue = maxX - w.layout.gridWidth / 15 * xRatio;
    }
    if (!w.axisFlags.isRangeBar) {
      if (xLowestValue < w.globals.initialMinX || xHighestValue > w.globals.initialMaxX) {
        xLowestValue = minX;
        xHighestValue = maxX;
      }
    }
    const xaxis = {
      min: xLowestValue,
      max: xHighestValue
    };
    const options2 = {
      xaxis
    };
    if (!w.config.chart.group) {
      options2.yaxis = yaxis;
    }
    this.updateScrolledChart(options2, xLowestValue, xHighestValue);
  }
  /**
   * @param {object} options
   * @param {number} xLowestValue
   * @param {number} xHighestValue
   */
  updateScrolledChart(options2, xLowestValue, xHighestValue) {
    const w = this.w;
    this.ctx.updateHelpers._updateOptions(options2, false, false);
    if (typeof w.config.chart.events.scrolled === "function") {
      const args = {
        xaxis: {
          min: xLowestValue,
          max: xHighestValue
        }
      };
      w.config.chart.events.scrolled(this.ctx, args);
      this.ctx.events.fireEvent("scrolled", args);
    }
  }
}
ApexCharts.registerFeatures({
  toolbar: Toolbar,
  zoomPanSelection: ZoomPanSelection
});
let Helpers$2 = class Helpers3 {
  /**
   * @param {import('./Annotations').default} annoCtx
   */
  constructor(annoCtx) {
    this.w = annoCtx.w;
    this.annoCtx = annoCtx;
  }
  /**
   * @param {Record<string, any>} anno
   * @param {number | null} [annoIndex]
   */
  setOrientations(anno, annoIndex = null) {
    var _a, _b;
    const w = this.w;
    if (anno.label.orientation === "vertical") {
      const i = annoIndex !== null ? annoIndex : 0;
      const xAnno = w.dom.baseEl.querySelector(
        `.apexcharts-xaxis-annotations .apexcharts-xaxis-annotation-label[rel='${i}']`
      );
      if (xAnno !== null) {
        const xAnnoCoord = (
          /** @type {SVGGraphicsElement} */
          xAnno.getBBox()
        );
        xAnno.setAttribute(
          "x",
          String(
            parseFloat((_a = xAnno.getAttribute("x")) != null ? _a : "0") - xAnnoCoord.height + 4
          )
        );
        const yOffset = anno.label.position === "top" ? xAnnoCoord.width : -xAnnoCoord.width;
        xAnno.setAttribute(
          "y",
          String(parseFloat((_b = xAnno.getAttribute("y")) != null ? _b : "0") + yOffset)
        );
        const { x, y } = this.annoCtx.graphics.rotateAroundCenter(xAnno);
        xAnno.setAttribute("transform", `rotate(-90 ${x} ${y})`);
      }
    }
  }
  /**
   * @param {any} annoEl
   * @param {Record<string, any>} anno
   */
  addBackgroundToAnno(annoEl, anno) {
    const w = this.w;
    if (!annoEl || !anno.label.text || !String(anno.label.text).trim()) {
      return null;
    }
    const gridEl = w.dom.baseEl.querySelector(".apexcharts-grid");
    if (!gridEl) return null;
    const elGridRect = gridEl.getBoundingClientRect();
    const gridBBox = (
      /** @type {SVGGraphicsElement} */
      gridEl.getBBox()
    );
    const zoom = elGridRect.width / gridBBox.width || 1;
    const coords = annoEl.getBoundingClientRect();
    let {
      left: pleft,
      right: pright,
      top: ptop,
      bottom: pbottom
    } = anno.label.style.padding;
    if (anno.label.orientation === "vertical") {
      [ptop, pbottom, pleft, pright] = [pleft, pright, ptop, pbottom];
    }
    const x1 = (coords.left - elGridRect.left) / zoom - pleft;
    const y1 = (coords.top - elGridRect.top) / zoom - ptop;
    const elRect = this.annoCtx.graphics.drawRect(
      x1 - w.globals.barPadForNumericAxis,
      y1,
      coords.width / zoom + pleft + pright,
      coords.height / zoom + ptop + pbottom,
      anno.label.borderRadius,
      anno.label.style.background,
      1,
      anno.label.borderWidth,
      anno.label.borderColor,
      0
    );
    if (anno.id) {
      elRect.node.classList.add(anno.id);
    }
    return elRect;
  }
  annotationsBackground() {
    const w = this.w;
    const add = (anno, i, type) => {
      const annoLabel = w.dom.baseEl.querySelector(
        `.apexcharts-${type}-annotations .apexcharts-${type}-annotation-label[rel='${i}']`
      );
      if (annoLabel) {
        const parent = annoLabel.parentNode;
        const elRect = this.addBackgroundToAnno(annoLabel, anno);
        if (elRect) {
          parent == null ? void 0 : parent.insertBefore(elRect.node, annoLabel);
          if (anno.label.mouseEnter) {
            elRect.node.addEventListener(
              "mouseenter",
              anno.label.mouseEnter.bind(this, anno)
            );
          }
          if (anno.label.mouseLeave) {
            elRect.node.addEventListener(
              "mouseleave",
              anno.label.mouseLeave.bind(this, anno)
            );
          }
          if (anno.label.click) {
            elRect.node.addEventListener(
              "click",
              anno.label.click.bind(this, anno)
            );
          }
        }
      }
    };
    w.config.annotations.xaxis.forEach(
      (anno, i) => add(anno, i, "xaxis")
    );
    w.config.annotations.yaxis.forEach(
      (anno, i) => add(anno, i, "yaxis")
    );
    w.config.annotations.points.forEach(
      (anno, i) => add(anno, i, "point")
    );
  }
  /**
   * @param {string} type
   * @param {Record<string, any>} anno
   */
  getY1Y2(type, anno) {
    var _a, _b;
    const w = this.w;
    const y = type === "y1" ? anno.y : anno.y2;
    let yP;
    let clipped = false;
    if (this.annoCtx.invertAxis) {
      const labels = w.config.xaxis.convertedCatToNumeric ? w.labelData.categoryLabels : w.labelData.labels;
      const catIndex = labels.indexOf(y);
      const xLabel = w.dom.baseEl.querySelector(
        `.apexcharts-yaxis-texts-g text:nth-child(${catIndex + 1})`
      );
      yP = xLabel ? parseFloat((_a = xLabel.getAttribute("y")) != null ? _a : "0") : (w.layout.gridHeight / labels.length - 1) * (catIndex + 1) - w.globals.barHeight;
      if (anno.seriesIndex !== void 0 && w.globals.barHeight) {
        yP -= w.globals.barHeight / 2 * (w.seriesData.series.length - 1) - w.globals.barHeight * anno.seriesIndex;
      }
    } else {
      const seriesIndex = w.globals.seriesYAxisMap[anno.yAxisIndex][0];
      const yPos = w.config.yaxis[anno.yAxisIndex].logarithmic ? new CoreUtils(this.w).getLogVal(
        w.config.yaxis[anno.yAxisIndex].logBase,
        y,
        seriesIndex
      ) / /** @type {any} */
      w.globals.yLogRatio[seriesIndex] : (y - w.globals.minYArr[seriesIndex]) / (w.globals.yRange[seriesIndex] / w.layout.gridHeight);
      yP = w.layout.gridHeight - Math.min(Math.max(yPos, 0), w.layout.gridHeight);
      clipped = yPos > w.layout.gridHeight || yPos < 0;
      if (anno.marker && (anno.y === void 0 || anno.y === null)) {
        yP = 0;
      }
      if ((_b = w.config.yaxis[anno.yAxisIndex]) == null ? void 0 : _b.reversed) {
        yP = yPos;
      }
    }
    if (typeof y === "string" && y.includes("px")) {
      yP = parseFloat(y);
    }
    return { yP, clipped };
  }
  /**
   * @param {string} type
   * @param {Record<string, any>} anno
   */
  getX1X2(type, anno) {
    const w = this.w;
    const x = type === "x1" ? anno.x : anno.x2;
    const min = this.annoCtx.invertAxis ? w.globals.minY : w.globals.minX;
    const max = this.annoCtx.invertAxis ? w.globals.maxY : w.globals.maxX;
    const range = this.annoCtx.invertAxis ? w.globals.yRange[0] : w.globals.xRange;
    let clipped = false;
    let xP = this.annoCtx.inversedReversedAxis ? (max - x) / (range / w.layout.gridWidth) : (x - min) / (range / w.layout.gridWidth);
    if ((w.config.xaxis.type === "category" || w.config.xaxis.convertedCatToNumeric) && !this.annoCtx.invertAxis && !w.axisFlags.dataFormatXNumeric) {
      if (!w.config.chart.sparkline.enabled) {
        xP = this.getStringX(x);
      }
    }
    if (typeof x === "string" && x.includes("px")) {
      xP = parseFloat(x);
    }
    if ((x === void 0 || x === null) && anno.marker) {
      xP = w.layout.gridWidth;
    }
    if (anno.seriesIndex !== void 0 && w.globals.barWidth && !this.annoCtx.invertAxis) {
      xP -= w.globals.barWidth / 2 * (w.seriesData.series.length - 1) - w.globals.barWidth * anno.seriesIndex;
    }
    if (typeof xP !== "number") {
      xP = 0;
      clipped = true;
    }
    if (parseFloat(xP.toFixed(10)) > parseFloat(w.layout.gridWidth.toFixed(10))) {
      xP = w.layout.gridWidth;
      clipped = true;
    } else if (xP < 0) {
      xP = 0;
      clipped = true;
    }
    return { x: xP, clipped };
  }
  /**
   * @param {number} x
   */
  getStringX(x) {
    var _a;
    const w = this.w;
    let rX = x;
    if (w.config.xaxis.convertedCatToNumeric && w.labelData.categoryLabels.length) {
      const strX = String(x);
      x = w.labelData.categoryLabels.findIndex(
        (l) => String(l) === strX
      ) + 1;
    }
    const catIndex = w.labelData.labels.map(
      (item) => Array.isArray(item) ? item.join(" ") : item
    ).indexOf(x);
    const xLabel = w.dom.baseEl.querySelector(
      `.apexcharts-xaxis-texts-g text:nth-child(${catIndex + 1})`
    );
    if (xLabel) {
      rX = parseFloat((_a = xLabel.getAttribute("x")) != null ? _a : "0");
    }
    return rX;
  }
};
class XAnnotations {
  /**
   * @param {import('./Annotations').default} annoCtx
   */
  constructor(annoCtx) {
    this.w = annoCtx.w;
    this.annoCtx = annoCtx;
    this.invertAxis = this.annoCtx.invertAxis;
    this.helpers = new Helpers$2(this.annoCtx);
  }
  /**
   * @param {XAxisAnnotations} anno
   * @param {Element} parent
   * @param {number} index
   */
  addXaxisAnnotation(anno, parent, index) {
    const w = this.w;
    const result = this.helpers.getX1X2("x1", anno);
    let x1 = result.x;
    const clipX1 = result.clipped;
    let clipX2 = true;
    let x2;
    const text = anno.label.text;
    const strokeDashArray = anno.strokeDashArray;
    if (!Utils$1.isNumber(x1)) return;
    if (anno.x2 === null || typeof anno.x2 === "undefined") {
      if (!clipX1) {
        const line = this.annoCtx.graphics.drawLine(
          x1 + anno.offsetX,
          // x1
          0 + anno.offsetY,
          // y1
          x1 + anno.offsetX,
          // x2
          w.layout.gridHeight + anno.offsetY,
          // y2
          anno.borderColor,
          // lineColor
          strokeDashArray,
          //dashArray
          anno.borderWidth
        );
        parent.appendChild(line.node);
        if (anno.id) {
          line.node.classList.add(anno.id);
        }
      }
    } else {
      const result2 = this.helpers.getX1X2("x2", anno);
      x2 = result2.x;
      clipX2 = result2.clipped;
      if (x2 < x1) {
        const temp = x1;
        x1 = x2;
        x2 = temp;
      }
      const rect = this.annoCtx.graphics.drawRect(
        x1 + anno.offsetX,
        // x1
        0 + anno.offsetY,
        // y1
        x2 - x1,
        // x2
        w.layout.gridHeight + anno.offsetY,
        // y2
        0,
        // radius
        anno.fillColor,
        // color
        anno.opacity,
        // opacity,
        1,
        // strokeWidth
        anno.borderColor,
        // strokeColor
        strokeDashArray
        // stokeDashArray
      );
      rect.node.classList.add("apexcharts-annotation-rect");
      rect.attr("clip-path", `url(#gridRectMask${w.globals.cuid})`);
      parent.appendChild(rect.node);
      if (anno.id) {
        rect.node.classList.add(anno.id);
      }
    }
    if (!(clipX1 && clipX2)) {
      const textRects = this.annoCtx.graphics.getTextRects(
        text,
        anno.label.style.fontSize
      );
      const textY = anno.label.position === "top" ? 4 : anno.label.position === "center" ? w.layout.gridHeight / 2 + (anno.label.orientation === "vertical" ? textRects.width / 2 : 0) : w.layout.gridHeight;
      const elText = this.annoCtx.graphics.drawText({
        x: x1 + anno.label.offsetX,
        y: textY + anno.label.offsetY - (anno.label.orientation === "vertical" ? anno.label.position === "top" ? textRects.width / 2 - 12 : -textRects.width / 2 : 0),
        text,
        textAnchor: anno.label.textAnchor,
        fontSize: anno.label.style.fontSize,
        fontFamily: anno.label.style.fontFamily,
        fontWeight: anno.label.style.fontWeight,
        foreColor: anno.label.style.color,
        cssClass: `apexcharts-xaxis-annotation-label ${anno.label.style.cssClass} ${anno.id ? anno.id : ""}`
      });
      elText.attr({
        rel: index
      });
      parent.appendChild(elText.node);
      this.annoCtx.helpers.setOrientations(anno, index);
    }
  }
  drawXAxisAnnotations() {
    const w = this.w;
    const elg = this.annoCtx.graphics.group({
      class: "apexcharts-xaxis-annotations"
    });
    w.config.annotations.xaxis.map(
      (anno, index) => {
        this.addXaxisAnnotation(anno, elg.node, index);
      }
    );
    return elg;
  }
}
class YAnnotations {
  /**
   * @param {import('./Annotations').default} annoCtx
   */
  constructor(annoCtx) {
    this.w = annoCtx.w;
    this.annoCtx = annoCtx;
    this.helpers = new Helpers$2(this.annoCtx);
    this.axesUtils = new AxesUtils(this.annoCtx.w, {
      theme: this.annoCtx.theme,
      timeScale: this.annoCtx.timeScale
    });
  }
  /**
   * @param {YAxisAnnotations} anno
   * @param {Element} parent
   * @param {number} index
   */
  addYaxisAnnotation(anno, parent, index) {
    const w = this.w;
    const strokeDashArray = anno.strokeDashArray;
    let result = this.helpers.getY1Y2("y1", anno);
    let y1 = result.yP;
    const clipY1 = result.clipped;
    let y2;
    let clipY2 = true;
    let drawn = false;
    const text = anno.label.text;
    if (anno.y2 === null || typeof anno.y2 === "undefined") {
      if (!clipY1) {
        drawn = true;
        const line = this.annoCtx.graphics.drawLine(
          0 + anno.offsetX,
          // x1
          y1 + anno.offsetY,
          // y1
          this._getYAxisAnnotationWidth(anno),
          // x2
          y1 + anno.offsetY,
          // y2
          anno.borderColor,
          // lineColor
          strokeDashArray,
          // dashArray
          anno.borderWidth
        );
        parent.appendChild(line.node);
        if (anno.id) {
          line.node.classList.add(anno.id);
        }
      }
    } else {
      result = this.helpers.getY1Y2("y2", anno);
      y2 = result.yP;
      clipY2 = result.clipped;
      if (y2 > y1) {
        const temp = y1;
        y1 = y2;
        y2 = temp;
      }
      if (!(clipY1 && clipY2)) {
        drawn = true;
        const rect = this.annoCtx.graphics.drawRect(
          0 + anno.offsetX,
          // x1
          y2 + anno.offsetY,
          // y1
          this._getYAxisAnnotationWidth(anno),
          // x2
          y1 - y2,
          // y2
          0,
          // radius
          anno.fillColor,
          // color
          anno.opacity,
          // opacity,
          1,
          // strokeWidth
          anno.borderColor,
          // strokeColor
          strokeDashArray
          // stokeDashArray
        );
        rect.node.classList.add("apexcharts-annotation-rect");
        rect.attr("clip-path", `url(#gridRectMask${w.globals.cuid})`);
        parent.appendChild(rect.node);
        if (anno.id) {
          rect.node.classList.add(anno.id);
        }
      }
    }
    if (drawn) {
      const textX = anno.label.position === "right" ? w.layout.gridWidth : anno.label.position === "center" ? w.layout.gridWidth / 2 : 0;
      const elText = this.annoCtx.graphics.drawText({
        x: textX + anno.label.offsetX,
        y: (y2 != null ? y2 : y1) + anno.label.offsetY - 3,
        text,
        textAnchor: anno.label.textAnchor,
        fontSize: anno.label.style.fontSize,
        fontFamily: anno.label.style.fontFamily,
        fontWeight: anno.label.style.fontWeight,
        foreColor: anno.label.style.color,
        cssClass: `apexcharts-yaxis-annotation-label ${anno.label.style.cssClass} ${anno.id ? anno.id : ""}`
      });
      elText.attr({
        rel: index
      });
      parent.appendChild(elText.node);
    }
  }
  /**
   * @param {YAxisAnnotations} anno
   */
  _getYAxisAnnotationWidth(anno) {
    const w = this.w;
    let width = w.layout.gridWidth;
    if (anno.width.indexOf("%") > -1) {
      width = w.layout.gridWidth * parseInt(anno.width, 10) / 100;
    } else {
      width = parseInt(anno.width, 10);
    }
    return width + anno.offsetX;
  }
  drawYAxisAnnotations() {
    const w = this.w;
    const elg = this.annoCtx.graphics.group({
      class: "apexcharts-yaxis-annotations"
    });
    w.config.annotations.yaxis.forEach(
      (anno, index) => {
        anno.yAxisIndex = this.axesUtils.translateYAxisIndex(anno.yAxisIndex);
        if (!(this.axesUtils.isYAxisHidden(anno.yAxisIndex) && this.axesUtils.yAxisAllSeriesCollapsed(anno.yAxisIndex))) {
          this.addYaxisAnnotation(anno, elg.node, index);
        }
      }
    );
    return elg;
  }
}
class PointAnnotations {
  /**
   * @param {import('./Annotations').default} annoCtx
   */
  constructor(annoCtx) {
    this.w = annoCtx.w;
    this.annoCtx = annoCtx;
    this.helpers = new Helpers$2(this.annoCtx);
  }
  /**
   * @param {Record<string, any>} anno
   * @param {Element} parent
   * @param {number} index
   */
  addPointAnnotation(anno, parent, index) {
    const w = this.w;
    if (w.globals.collapsedSeriesIndices.indexOf(anno.seriesIndex) > -1) {
      return;
    }
    const resultX = this.helpers.getX1X2("x1", anno);
    const x = resultX.x;
    const clipX = resultX.clipped;
    const resultY = this.helpers.getY1Y2("y1", anno);
    const y = resultY.yP;
    const clipY = resultY.clipped;
    if (!Utils$1.isNumber(x)) return;
    if (!(clipY || clipX)) {
      const optsPoints = {
        pSize: anno.marker.size,
        pointStrokeWidth: anno.marker.strokeWidth,
        pointFillColor: anno.marker.fillColor,
        pointStrokeColor: anno.marker.strokeColor,
        shape: anno.marker.shape,
        pRadius: anno.marker.radius,
        class: `apexcharts-point-annotation-marker ${anno.marker.cssClass} ${anno.id ? anno.id : ""}`
      };
      let point = this.annoCtx.graphics.drawMarker(
        x + anno.marker.offsetX,
        y + anno.marker.offsetY,
        optsPoints
      );
      parent.appendChild(point.node);
      const text = anno.label.text ? anno.label.text : "";
      const elText = this.annoCtx.graphics.drawText({
        x: x + anno.label.offsetX,
        y: y + anno.label.offsetY - anno.marker.size - parseFloat(anno.label.style.fontSize) / 1.6,
        text,
        textAnchor: anno.label.textAnchor,
        fontSize: anno.label.style.fontSize,
        fontFamily: anno.label.style.fontFamily,
        fontWeight: anno.label.style.fontWeight,
        foreColor: anno.label.style.color,
        cssClass: `apexcharts-point-annotation-label ${anno.label.style.cssClass} ${anno.id ? anno.id : ""}`
      });
      elText.attr({
        rel: index
      });
      parent.appendChild(elText.node);
      if (anno.customSVG.SVG) {
        const g = this.annoCtx.graphics.group({
          class: "apexcharts-point-annotations-custom-svg " + anno.customSVG.cssClass
        });
        g.attr({
          transform: `translate(${x + anno.customSVG.offsetX}, ${y + anno.customSVG.offsetY})`
        });
        g.node.innerHTML = anno.customSVG.SVG;
        parent.appendChild(g.node);
      }
      if (anno.image.path) {
        const imgWidth = anno.image.width ? anno.image.width : 20;
        const imgHeight = anno.image.height ? anno.image.height : 20;
        point = this.annoCtx.addImage({
          x: x + anno.image.offsetX - imgWidth / 2,
          y: y + anno.image.offsetY - imgHeight / 2,
          width: imgWidth,
          height: imgHeight,
          path: anno.image.path,
          appendTo: ".apexcharts-point-annotations"
        });
      }
      if (anno.mouseEnter) {
        point.node.addEventListener(
          "mouseenter",
          anno.mouseEnter.bind(this, anno)
        );
      }
      if (anno.mouseLeave) {
        point.node.addEventListener(
          "mouseleave",
          anno.mouseLeave.bind(this, anno)
        );
      }
      if (anno.click) {
        point.node.addEventListener("click", anno.click.bind(this, anno));
      }
    }
  }
  drawPointAnnotations() {
    const w = this.w;
    const elg = this.annoCtx.graphics.group({
      class: "apexcharts-point-annotations"
    });
    w.config.annotations.points.map(
      (anno, index) => {
        this.addPointAnnotation(anno, elg.node, index);
      }
    );
    return elg;
  }
}
class Annotations {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   */
  constructor(w, { theme = null, timeScale = null } = {}) {
    this.w = w;
    this.theme = theme;
    this.timeScale = timeScale;
    this.invertAxis = void 0;
    this.inversedReversedAxis = void 0;
    this.graphics = new Graphics(this.w);
    if (this.w.globals.isBarHorizontal) {
      this.invertAxis = true;
    }
    this.helpers = new Helpers$2(this);
    this.xAxisAnnotations = new XAnnotations(this);
    this.yAxisAnnotations = new YAnnotations(this);
    this.pointsAnnotations = new PointAnnotations(this);
    if (this.w.globals.isBarHorizontal && this.w.config.yaxis[0].reversed) {
      this.inversedReversedAxis = true;
    }
    this.xDivision = this.w.layout.gridWidth / this.w.globals.dataPoints;
  }
  drawAxesAnnotations() {
    const w = this.w;
    if (w.globals.axisCharts && w.globals.dataPoints) {
      const yAnnotations = this.yAxisAnnotations.drawYAxisAnnotations();
      const xAnnotations = this.xAxisAnnotations.drawXAxisAnnotations();
      const pointAnnotations = this.pointsAnnotations.drawPointAnnotations();
      const initialAnim = w.config.chart.animations.enabled;
      const annoArray = [yAnnotations, xAnnotations, pointAnnotations];
      const annoElArray = [
        xAnnotations.node,
        yAnnotations.node,
        pointAnnotations.node
      ];
      for (let i = 0; i < 3; i++) {
        w.dom.elGraphical.add(annoArray[i]);
        if (initialAnim && !w.globals.resized && !w.globals.dataChanged) {
          if (w.config.chart.type !== "scatter" && w.config.chart.type !== "bubble" && w.globals.dataPoints > 1) {
            annoElArray[i].classList.add("apexcharts-element-hidden");
          }
        }
        w.globals.delayedElements.push({ el: annoElArray[i], index: 0 });
      }
      this.helpers.annotationsBackground();
    }
  }
  drawImageAnnos() {
    const w = this.w;
    w.config.annotations.images.map((s) => {
      this.addImage(s);
    });
  }
  drawTextAnnos() {
    const w = this.w;
    w.config.annotations.texts.map((t) => {
      this.addText(t);
    });
  }
  /**
   * @param {Record<string, any>} anno
   * @param {Element} parent
   * @param {number} index
   */
  addXaxisAnnotation(anno, parent, index) {
    this.xAxisAnnotations.addXaxisAnnotation(anno, parent, index);
  }
  /**
   * @param {Record<string, any>} anno
   * @param {Element} parent
   * @param {number} index
   */
  addYaxisAnnotation(anno, parent, index) {
    this.yAxisAnnotations.addYaxisAnnotation(anno, parent, index);
  }
  /**
   * @param {Record<string, any>} anno
   * @param {Element} parent
   * @param {number} index
   */
  addPointAnnotation(anno, parent, index) {
    this.pointsAnnotations.addPointAnnotation(anno, parent, index);
  }
  /**
   * @param {Record<string, any>} params
   */
  addText(params) {
    const {
      x,
      y,
      text,
      textAnchor,
      foreColor,
      fontSize,
      fontFamily,
      fontWeight,
      cssClass,
      backgroundColor,
      borderWidth,
      strokeDashArray,
      borderRadius,
      borderColor,
      appendTo = ".apexcharts-svg",
      paddingLeft = 4,
      paddingRight = 4,
      paddingBottom = 2,
      paddingTop = 2
    } = params;
    const w = this.w;
    const elText = this.graphics.drawText({
      x,
      y,
      text,
      textAnchor: textAnchor || "start",
      fontSize: fontSize || "12px",
      fontWeight: fontWeight || "regular",
      fontFamily: fontFamily || w.config.chart.fontFamily,
      foreColor: foreColor || w.config.chart.foreColor,
      cssClass: "apexcharts-text " + cssClass ? cssClass : ""
    });
    const parent = w.dom.baseEl.querySelector(appendTo);
    if (parent) {
      parent.appendChild(elText.node);
    }
    const textRect = elText.bbox();
    if (text) {
      const elRect = this.graphics.drawRect(
        textRect.x - paddingLeft,
        textRect.y - paddingTop,
        textRect.width + paddingLeft + paddingRight,
        textRect.height + paddingBottom + paddingTop,
        borderRadius,
        backgroundColor ? backgroundColor : "transparent",
        1,
        borderWidth,
        borderColor,
        strokeDashArray
      );
      parent.insertBefore(elRect.node, elText.node);
    }
  }
  /**
   * @param {Record<string, any>} params
   */
  addImage(params) {
    const w = this.w;
    const {
      path,
      x = 0,
      y = 0,
      width = 20,
      height = 20,
      appendTo = ".apexcharts-svg"
    } = params;
    const img = w.dom.Paper.image(path);
    img.size(width, height).move(x, y);
    const parent = w.dom.baseEl.querySelector(appendTo);
    if (parent) {
      parent.appendChild(img.node);
    }
    return img;
  }
  // The addXaxisAnnotation method requires a parent class, and user calling this method externally on the chart instance may not specify parent, hence a different method
  /**
   * @param {Record<string, any>} params
   * @param {boolean} pushToMemory
   * @param {any} context
   */
  addXaxisAnnotationExternal(params, pushToMemory, context) {
    this.addAnnotationExternal({
      params,
      pushToMemory,
      context,
      type: "xaxis",
      contextMethod: context.addXaxisAnnotation
    });
    return context;
  }
  /**
   * @param {Record<string, any>} params
   * @param {boolean} pushToMemory
   * @param {any} context
   */
  addYaxisAnnotationExternal(params, pushToMemory, context) {
    this.addAnnotationExternal({
      params,
      pushToMemory,
      context,
      type: "yaxis",
      contextMethod: context.addYaxisAnnotation
    });
    return context;
  }
  /**
   * @param {Record<string, any>} params
   * @param {boolean} pushToMemory
   * @param {any} context
   */
  addPointAnnotationExternal(params, pushToMemory, context) {
    if (typeof this.invertAxis === "undefined") {
      this.invertAxis = context.w.globals.isBarHorizontal;
    }
    this.addAnnotationExternal({
      params,
      pushToMemory,
      context,
      type: "point",
      contextMethod: context.addPointAnnotation
    });
    return context;
  }
  /** @param {{params: any, pushToMemory: any, context: any, type: any, contextMethod: any}} opts */
  addAnnotationExternal({
    params,
    pushToMemory,
    context,
    type,
    contextMethod
  }) {
    const me = context;
    const w = me.w;
    const parent = w.dom.baseEl.querySelector(`.apexcharts-${type}-annotations`);
    const index = parent.childNodes.length + 1;
    const options2 = new Options();
    const axesAnno = Object.assign(
      {},
      type === "xaxis" ? options2.xAxisAnnotation : type === "yaxis" ? options2.yAxisAnnotation : options2.pointAnnotation
    );
    const anno = Utils$1.extend(axesAnno, params);
    switch (type) {
      case "xaxis":
        this.addXaxisAnnotation(anno, parent, index);
        break;
      case "yaxis":
        this.addYaxisAnnotation(anno, parent, index);
        break;
      case "point":
        this.addPointAnnotation(anno, parent, index);
        break;
    }
    const axesAnnoLabel = w.dom.baseEl.querySelector(
      `.apexcharts-${type}-annotations .apexcharts-${type}-annotation-label[rel='${index}']`
    );
    const elRect = this.helpers.addBackgroundToAnno(axesAnnoLabel, anno);
    if (elRect) {
      parent.insertBefore(elRect.node, axesAnnoLabel);
    }
    if (pushToMemory) {
      w.globals.memory.methodsToExec.push({
        context: me,
        id: anno.id ? anno.id : Utils$1.randomId(),
        method: contextMethod,
        label: "addAnnotation",
        params
      });
    }
    return context;
  }
  /**
   * @param {import('../../types/internal').ChartContext} ctx
   */
  clearAnnotations(ctx) {
    const w = ctx.w;
    const annos = w.dom.baseEl.querySelectorAll(
      ".apexcharts-yaxis-annotations, .apexcharts-xaxis-annotations, .apexcharts-point-annotations"
    );
    for (let i = w.globals.memory.methodsToExec.length - 1; i >= 0; i--) {
      if (w.globals.memory.methodsToExec[i].label === "addText" || w.globals.memory.methodsToExec[i].label === "addAnnotation") {
        w.globals.memory.methodsToExec.splice(i, 1);
      }
    }
    Array.prototype.forEach.call(annos, (a) => {
      while (a.firstChild) {
        a.removeChild(a.firstChild);
      }
    });
  }
  /**
   * @param {import('../../types/internal').ChartContext} ctx
   * @param {string} id
   */
  removeAnnotation(ctx, id) {
    const w = ctx.w;
    const annos = w.dom.baseEl.querySelectorAll(`.${id}`);
    if (annos) {
      w.globals.memory.methodsToExec.map((m, i) => {
        if (m.id === id) {
          w.globals.memory.methodsToExec.splice(i, 1);
        }
      });
      Object.keys(w.config.annotations).forEach((key) => {
        const annotationArray = w.config.annotations[key];
        if (Array.isArray(annotationArray)) {
          w.config.annotations[key] = annotationArray.filter((m) => m.id !== id);
        }
      });
      Array.prototype.forEach.call(annos, (a) => {
        a.parentElement.removeChild(a);
      });
    }
  }
}
ApexCharts.registerFeatures({ annotations: Annotations });
class KeyboardNavigation {
  /**
   * @param {import('../../types/internal').ChartStateW} w
   * @param {import('../../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.w = w;
    this.ctx = ctx;
    this.seriesIndex = 0;
    this.dataPointIndex = 0;
    this.active = false;
    this._tooltipDismissed = false;
    this._focusedEl = null;
    this._hoveredBarEl = null;
    this._enlargedScatterMarker = null;
    this._onKeyDown = this._onKeyDown.bind(this);
    this._onFocus = this._onFocus.bind(this);
    this._onBlur = this._onBlur.bind(this);
    this._onLegendClick = this._onLegendClick.bind(this);
  }
  // ─── Public API ───────────────────────────────────────────────────────────
  /**
   * Called after the chart and tooltip have been fully rendered.
   * Attaches event listeners and makes the SVG keyboard-focusable.
   */
  init() {
    const w = this.w;
    const svgEl = w.dom.Paper.node;
    if (!svgEl) return;
    svgEl.setAttribute("tabindex", "0");
    svgEl.addEventListener("focus", this._onFocus);
    svgEl.addEventListener("blur", this._onBlur);
    svgEl.addEventListener("keydown", this._onKeyDown, { passive: false });
    this.ctx.events.addEventListener("legendClick", this._onLegendClick);
  }
  /**
   * Removes all event listeners. Called from chart.destroy().
   */
  destroy() {
    const w = this.w;
    const svgEl = w.dom.Paper && w.dom.Paper.node;
    if (!svgEl) return;
    svgEl.removeEventListener("focus", this._onFocus);
    svgEl.removeEventListener("blur", this._onBlur);
    svgEl.removeEventListener("keydown", this._onKeyDown);
    this.ctx.events.removeEventListener("legendClick", this._onLegendClick);
  }
  /**
   * Called from Events.js keydown handler. Navigation keys are already handled
   * by the direct SVG listener (which can call preventDefault). This entry
   * point is intentionally a no-op — Events.js still fires the public keyDown
   * callback and fireEvent('keydown') independently.
   * @param {Event} _e
   */
  handleKey(_e) {
  }
  // ─── Focus / blur ─────────────────────────────────────────────────────────
  _onFocus() {
    if (!this._isNavEnabled()) return;
    this.active = true;
    this._clampCursor();
    this._snapToVisibleRange();
    this._showCurrentPoint();
  }
  _onBlur() {
    this.active = false;
    this._tooltipDismissed = false;
    this._hideFocus();
  }
  // Called when the user clicks a legend item (collapse/expand a series).
  // Hide the keyboard-nav tooltip — the chart is about to re-render and the
  // current position may no longer be valid.
  _onLegendClick() {
    if (!this.active) return;
    this.active = false;
    this._hideFocus();
  }
  // ─── Key handler ──────────────────────────────────────────────────────────
  /**
   * @param {KeyboardEvent} e
   */
  _onKeyDown(e) {
    var _a, _b, _c;
    if (!this._isNavEnabled() || !this.active) return;
    if (e.shiftKey && (e.key === "ArrowRight" || e.key === "ArrowLeft") && this._canPan()) {
      e.preventDefault();
      this._panBy(e.key === "ArrowRight" ? 1 : -1);
      return;
    }
    switch (e.key) {
      case "ArrowRight":
        e.preventDefault();
        this._move(0, 1);
        break;
      case "ArrowLeft":
        e.preventDefault();
        this._move(0, -1);
        break;
      case "ArrowUp":
        e.preventDefault();
        this._move(-1, 0);
        break;
      case "ArrowDown":
        e.preventDefault();
        this._move(1, 0);
        break;
      case "Home":
        e.preventDefault();
        this.dataPointIndex = 0;
        this._skipNullForward();
        this._showCurrentPoint();
        break;
      case "End":
        e.preventDefault();
        this.dataPointIndex = this._getDataPointCount(this.seriesIndex) - 1;
        this._skipNullBackward();
        this._showCurrentPoint();
        break;
      case "Enter":
      case " ":
        e.preventDefault();
        this._fireClick();
        break;
      case "+":
      case "=":
        if (this._canZoom()) {
          e.preventDefault();
          (_a = this.ctx.toolbar) == null ? void 0 : _a.handleZoomIn();
          this._announce("Zoomed in");
        }
        break;
      case "-":
      case "_":
        if (this._canZoom()) {
          e.preventDefault();
          (_b = this.ctx.toolbar) == null ? void 0 : _b.handleZoomOut();
          this._announce("Zoomed out");
        }
        break;
      case "0":
        if (this._canZoom() && this.w.interact.zoomed) {
          e.preventDefault();
          (_c = this.ctx.toolbar) == null ? void 0 : _c.handleZoomReset();
          this._announce("Zoom reset");
        }
        break;
      case "Escape":
        e.preventDefault();
        if (!this._tooltipDismissed) {
          this._tooltipDismissed = true;
          this._hideFocus();
        } else {
          this.active = false;
          this._tooltipDismissed = false;
          this._hideFocus();
        }
        break;
    }
  }
  // ─── Zoom / pan (keyboard alternatives for drag gestures) ─────────────────
  _canZoom() {
    const w = this.w;
    return Boolean(
      w.globals.axisCharts && w.config.chart.zoom && w.config.chart.zoom.enabled
    );
  }
  _canPan() {
    return this._canZoom();
  }
  /**
   * Shift the visible x-range by ~10% in the given direction.
   * @param {number} direction +1 = right, -1 = left
   */
  _panBy(direction) {
    const w = this.w;
    const toolbar = this.ctx.toolbar;
    if (!toolbar) return;
    const minX = Number(w.globals.minX);
    const maxX = Number(w.globals.maxX);
    if (!isFinite(minX) || !isFinite(maxX) || minX === maxX) return;
    const span = maxX - minX;
    const step = span * 0.1 * direction;
    toolbar.zoomUpdateOptions(minX + step, maxX + step);
    this._announce(direction > 0 ? "Panned right" : "Panned left");
  }
  // ─── Navigation ───────────────────────────────────────────────────────────
  /**
   * @param {number} dSeries
   * @param {number} dPoint
   */
  _move(dSeries, dPoint) {
    const w = this.w;
    const wrapAround = w.config.chart.accessibility.keyboard.navigation.wrapAround;
    if (dSeries !== 0) {
      const ttCtx = this.w.globals.tooltip;
      if (ttCtx && ttCtx.tConfig && ttCtx.tConfig.shared) {
        const j = this.dataPointIndex;
        const isActuallyShared = ttCtx.tooltipUtil && ttCtx.tooltipUtil.isXoverlap(j) && ttCtx.tooltipUtil.isInitialSeriesSameLen();
        if (isActuallyShared) return;
      }
      const total = this._getSeriesCount();
      let si = this.seriesIndex + dSeries;
      let attempts = 0;
      while (attempts < total) {
        if (si < 0) si = wrapAround ? total - 1 : 0;
        if (si >= total) si = wrapAround ? 0 : total - 1;
        if (!w.globals.collapsedSeriesIndices.includes(si)) break;
        si += dSeries;
        attempts++;
      }
      this.seriesIndex = si;
      const dpCount = this._getDataPointCount(si);
      if (this.dataPointIndex >= dpCount) {
        this.dataPointIndex = dpCount - 1;
      }
    }
    if (dPoint !== 0) {
      const dpCount = this._getDataPointCount(this.seriesIndex);
      let di = this.dataPointIndex + dPoint;
      if (di < 0) di = wrapAround ? dpCount - 1 : 0;
      if (di >= dpCount) di = wrapAround ? 0 : dpCount - 1;
      this.dataPointIndex = di;
      if (dPoint > 0) {
        this._skipNullForward();
      } else {
        this._skipNullBackward();
      }
      if (!this._isDataPointVisible(this.seriesIndex, this.dataPointIndex)) {
        this._snapToVisibleRangeInDirection(dPoint);
      }
    }
    this._showCurrentPoint();
  }
  /** Advance dataPointIndex forward past any nulls */
  _skipNullForward() {
    const w = this.w;
    const si = this.seriesIndex;
    const dpCount = this._getDataPointCount(si);
    let di = this.dataPointIndex;
    let attempts = 0;
    if (!Array.isArray(w.seriesData.series[si])) return;
    while (attempts < dpCount && w.seriesData.series[si][di] === null) {
      di = (di + 1) % dpCount;
      attempts++;
    }
    this.dataPointIndex = di;
  }
  /** Retreat dataPointIndex backward past any nulls */
  _skipNullBackward() {
    const w = this.w;
    const si = this.seriesIndex;
    const dpCount = this._getDataPointCount(si);
    let di = this.dataPointIndex;
    let attempts = 0;
    if (!Array.isArray(w.seriesData.series[si])) return;
    while (attempts < dpCount && w.seriesData.series[si][di] === null) {
      di = (di - 1 + dpCount) % dpCount;
      attempts++;
    }
    this.dataPointIndex = di;
  }
  // ─── Display ──────────────────────────────────────────────────────────────
  _showCurrentPoint() {
    const { seriesIndex: i, dataPointIndex: j } = this;
    const w = this.w;
    const ttCtx = w.globals.tooltip;
    if (!ttCtx || !ttCtx.ttItems) return;
    w.interact.capturedSeriesIndex = i;
    w.interact.capturedDataPointIndex = j;
    this._applyFocusClass(i, j);
    this._showTooltip(
      i,
      j,
      /** @type {any} */
      ttCtx
    );
  }
  _hideFocus() {
    const w = this.w;
    const ttCtx = (
      /** @type {any} */
      w.globals.tooltip
    );
    this._removeFocusClass();
    this._leaveHoveredBar();
    if (!ttCtx) return;
    if (ttCtx.marker) {
      ttCtx.marker.resetPointsSize();
    }
    this._enlargedScatterMarker = null;
    const tooltipEl = ttCtx.getElTooltip();
    if (tooltipEl) {
      tooltipEl.classList.remove("apexcharts-active");
      if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
        tooltipEl.setAttribute("aria-hidden", "true");
      }
    }
    w.dom.baseEl.classList.remove("apexcharts-tooltip-active");
    const xcrosshairs = ttCtx.getElXCrosshairs();
    if (xcrosshairs) xcrosshairs.classList.remove("apexcharts-active");
  }
  // ─── Tooltip display per chart type ───────────────────────────────────────
  /**
   * @param {number} i
   * @param {number} j
   * @param {import('../tooltip/Tooltip').default} ttCtx
   */
  _showTooltip(i, j, ttCtx) {
    const w = this.w;
    const type = w.config.chart.type;
    const tooltipEl = ttCtx.getElTooltip();
    if (!tooltipEl) return;
    const cachedDims = ttCtx.getCachedDimensions();
    ttCtx.tooltipRect = {
      x: 0,
      y: 0,
      ttWidth: cachedDims.ttWidth || 0,
      ttHeight: cachedDims.ttHeight || 0
    };
    this._setSyntheticEvent(i, j, ttCtx);
    w.dom.baseEl.classList.add("apexcharts-tooltip-active");
    tooltipEl.classList.add("apexcharts-active");
    if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
      tooltipEl.removeAttribute("aria-hidden");
    }
    if (type === "pie" || type === "donut" || type === "polarArea") {
      this._showTooltipNonAxis(i, j, ttCtx, tooltipEl);
    } else if (type === "radialBar") {
      this._showTooltipRadialBar(i, j, ttCtx, tooltipEl);
    } else if (type === "heatmap" || type === "treemap") {
      this._showTooltipHeatTree(i, j, ttCtx, tooltipEl, type);
    } else if (type === "bar" || type === "candlestick" || type === "boxPlot" || type === "rangeBar") {
      this._showTooltipBar(i, j, ttCtx);
    } else {
      this._showTooltipAxisLine(i, j, ttCtx);
    }
  }
  /**
   * Set ttCtx.e to a synthetic mouse-event-like object whose clientX/Y point
   * to the centre of the current data-point element.  This ensures that any
   * positioning helper that reads ttCtx.e (followCursor path in moveTooltip,
   * moveStickyTooltipOverBars, moveDynamicPointsOnHover, etc.) gets valid
   * coordinates rather than crashing on undefined.
   *
   * For chart types that don't have a concrete SVG element per data point
   * (pie, radialBar) we fall back to the SVG centre.
   * @param {number} i
   * @param {number} j
   * @param {import('../tooltip/Tooltip').default} ttCtx
   */
  _setSyntheticEvent(i, j, ttCtx) {
    const w = this.w;
    const type = w.config.chart.type;
    let clientX = 0;
    let clientY = 0;
    const el = this._getFocusableElement(i, j);
    if (el) {
      const rect = el.getBoundingClientRect();
      clientX = rect.left + rect.width / 2;
      clientY = rect.top + rect.height / 2;
    } else if (w.globals.pointsArray && w.globals.pointsArray[i] && w.globals.pointsArray[i][j]) {
      const pt = w.globals.pointsArray[i][j];
      const elGrid = ttCtx.getElGrid && ttCtx.getElGrid();
      if (elGrid) {
        const gridRect = elGrid.getBoundingClientRect();
        clientX = gridRect.left + (pt[0] || 0);
        clientY = gridRect.top + (pt[1] || 0);
      }
    } else {
      const svgEl = w.dom.Paper && w.dom.Paper.node;
      if (svgEl) {
        const svgRect = svgEl.getBoundingClientRect();
        clientX = svgRect.left + svgRect.width / 2;
        clientY = svgRect.top + svgRect.height / 2;
      }
    }
    if (type === "line" || type === "area" || type === "rangeArea" || type === "scatter" || type === "bubble" || type === "radar") {
      if (w.globals.pointsArray && w.globals.pointsArray[i] && w.globals.pointsArray[i][j]) {
        const pt = w.globals.pointsArray[i][j];
        const elGrid = ttCtx.getElGrid && ttCtx.getElGrid();
        if (elGrid) {
          const gridRect = elGrid.getBoundingClientRect();
          clientX = gridRect.left + (pt[0] || 0);
          clientY = gridRect.top + (pt[1] || 0);
        }
      }
    }
    ttCtx.e = { type: "mousemove", clientX, clientY };
  }
  /**
   * bar / column / candlestick / boxPlot / rangeBar
   * @param {number} i
   * @param {number} j
   * @param {import('../tooltip/Tooltip').default} ttCtx
   */
  _showTooltipBar(i, j, ttCtx) {
    var _a, _b, _c, _d;
    const w = this.w;
    const shared = ttCtx.tConfig.shared && (ttCtx.tooltipUtil.isXoverlap(j) || w.globals.isBarHorizontal) && ttCtx.tooltipUtil.isInitialSeriesSameLen();
    const rangeData = (
      /** @type {any} */
      (_d = (_c = (_b = (_a = w.rangeData.seriesRange) == null ? void 0 : _a[i]) == null ? void 0 : _b[j]) == null ? void 0 : _c.y) == null ? void 0 : _d[0]
    );
    ttCtx.tooltipLabels.drawSeriesTexts(__spreadProps(__spreadValues(__spreadValues({
      ttItems: ttCtx.ttItems,
      i,
      j
    }, (rangeData == null ? void 0 : rangeData.y1) !== void 0 && { y1: rangeData.y1 }), (rangeData == null ? void 0 : rangeData.y2) !== void 0 && { y2: rangeData.y2 }), {
      shared
    }));
    const parent = `.apexcharts-series[data\\:realIndex='${i}']`;
    const elPath = w.dom.Paper.findOne(
      `${parent} path[j='${j}'], ${parent} circle[j='${j}'], ${parent} rect[j='${j}']`
    );
    if (elPath) {
      this._leaveHoveredBar();
      const graphics = new Graphics(this.w, this.ctx);
      graphics.pathMouseEnter(elPath, null);
      this._hoveredBarEl = elPath;
    }
    if (w.globals.isBarHorizontal) {
      const barDomEl = elPath && elPath.node;
      if (barDomEl) {
        const wrapRect = w.dom.elWrap.getBoundingClientRect();
        const barRect = barDomEl.getBoundingClientRect();
        const barCx = barRect.left - wrapRect.left;
        const barCy = barRect.top - wrapRect.top;
        const bh = barRect.height;
        const bw = barRect.width;
        const ttWidth = ttCtx.tooltipRect.ttWidth || 0;
        const ttHeight = ttCtx.tooltipRect.ttHeight || 0;
        const y = barCy + bh / 2 - ttHeight / 2;
        let x = barCx + bw;
        const baselineX = ttCtx.xyRatios && ttCtx.xyRatios.baseLineInvertedY != null ? ttCtx.xyRatios.baseLineInvertedY : wrapRect.width / 2;
        if (barCx < baselineX) {
          x = barCx - ttWidth;
        }
        const tooltipEl = ttCtx.getElTooltip();
        if (tooltipEl) {
          tooltipEl.style.left = x + "px";
          tooltipEl.style.top = y + "px";
        }
      }
    } else {
      ttCtx.tooltipPosition.moveStickyTooltipOverBars(j, i);
    }
  }
  /**
   * line / area / scatter / bubble / radar / rangeArea
   * @param {number} i
   * @param {number} j
   * @param {import('../tooltip/Tooltip').default} ttCtx
   */
  _showTooltipAxisLine(i, j, ttCtx) {
    const w = this.w;
    const type = w.config.chart.type;
    const sharedConfigured = ttCtx.tConfig.shared;
    const shared = sharedConfigured && ttCtx.tooltipUtil.isXoverlap(j) && ttCtx.tooltipUtil.isInitialSeriesSameLen();
    ttCtx.tooltipLabels.drawSeriesTexts({
      ttItems: ttCtx.ttItems,
      i,
      j,
      shared
    });
    const isScatterLike = type === "scatter" || type === "bubble";
    const hasVisibleMarkers = w.globals.markers.largestSize > 0;
    if (isScatterLike) {
      this._showScatterBubblePoint(i, j, ttCtx);
    } else if (hasVisibleMarkers) {
      if (shared) {
        ttCtx.marker.enlargePoints(j);
      } else {
        ttCtx.tooltipPosition.moveDynamicPointOnHover(j, i);
      }
    } else if (shared) {
      ttCtx.tooltipPosition.moveDynamicPointsOnHover(j);
    } else {
      ttCtx.tooltipPosition.moveDynamicPointOnHover(j, i);
    }
  }
  /**
   * Scatter / bubble: find the specific marker element for (seriesIndex i,
   * dataPointIndex j), resize only that element, and position the tooltip at
   * its coordinates — mirroring what Position.moveMarkers does for mouse hover.
   *
   * Unlike enlargePoints(j) which queries ALL series for rel===j (causing
   * multiple bubbles to enlarge and tooltip to land on the wrong one), this
   * method queries by both series index AND data-point index for precision.
   * @param {number} i
   * @param {number} j
   * @param {import('../tooltip/Tooltip').default} ttCtx
   */
  _showScatterBubblePoint(i, j, ttCtx) {
    const baseEl = this.w.dom.baseEl;
    if (this._enlargedScatterMarker) {
      ttCtx.marker.oldPointSize(this._enlargedScatterMarker);
      this._enlargedScatterMarker = null;
    }
    const seriesEl = baseEl.querySelector(
      `.apexcharts-series[data\\:realIndex='${i}']`
    );
    if (!seriesEl) return;
    const markerEl = seriesEl.querySelector(`.apexcharts-marker[rel='${j}']`);
    if (!markerEl) return;
    ttCtx.marker.enlargeCurrentPoint(j, markerEl);
    this._enlargedScatterMarker = markerEl;
  }
  /**
   * pie / donut / polarArea
   * @param {number} i
   * @param {number} j
   * @param {import('../tooltip/Tooltip').default} ttCtx
   * @param {HTMLElement} tooltipEl
   */
  _showTooltipNonAxis(i, j, ttCtx, tooltipEl) {
    var _a, _b;
    const w = this.w;
    ttCtx.tooltipLabels.drawSeriesTexts({
      ttItems: ttCtx.ttItems,
      i: j,
      shared: false
    });
    const tooltipBound = tooltipEl.getBoundingClientRect();
    const ttWidth = tooltipBound.width || ttCtx.tooltipRect.ttWidth || 0;
    const ttHeight = tooltipBound.height || ttCtx.tooltipRect.ttHeight || 0;
    const sliceEl = w.dom.baseEl.querySelector(`.apexcharts-pie-area[j='${j}']`);
    if (sliceEl) {
      const cx = parseFloat((_a = sliceEl.getAttribute("data:cx")) != null ? _a : "");
      const cy = parseFloat((_b = sliceEl.getAttribute("data:cy")) != null ? _b : "");
      if (!isNaN(cx) && !isNaN(cy)) {
        const svgBound = w.dom.Paper.node.getBoundingClientRect();
        const wrapBound = w.dom.elWrap.getBoundingClientRect();
        const offsetX = svgBound.left - wrapBound.left;
        const offsetY = svgBound.top - wrapBound.top;
        tooltipEl.style.left = offsetX + cx - ttWidth / 2 + "px";
        tooltipEl.style.top = offsetY + cy - ttHeight - 10 + "px";
      }
    }
  }
  /**
   * radialBar — one ring per series, single value each
   * @param {number} i
   * @param {any} _j
   * @param {import('../tooltip/Tooltip').default} ttCtx
   * @param {HTMLElement} tooltipEl
   */
  _showTooltipRadialBar(i, _j, ttCtx, tooltipEl) {
    var _a;
    const w = this.w;
    ttCtx.tooltipLabels.drawSeriesTexts({
      ttItems: ttCtx.ttItems,
      i,
      shared: false
    });
    const { ttWidth = 0, ttHeight = 0 } = ttCtx.getCachedDimensions();
    const arcEl = w.dom.baseEl.querySelector(
      `.apexcharts-radialbar-series[data\\:realIndex='${i}'] path`
    );
    if (arcEl) {
      const angle = parseFloat((_a = arcEl.getAttribute("data:angle")) != null ? _a : "") || 0;
      const initialAngle = w.config.plotOptions.radialBar.startAngle || 0;
      const midAngle = initialAngle + angle / 2;
      const centerX = w.layout.gridWidth / 2;
      const centerY = w.layout.gridHeight / 2;
      const radialSize = w.globals.radialSize || Math.min(w.layout.gridWidth, w.layout.gridHeight) / 2;
      const seriesCount = w.seriesData.series.length;
      const trackSize = radialSize / Math.max(seriesCount, 1);
      const outerRadius = radialSize - i * trackSize;
      const innerRadius = outerRadius - trackSize;
      const ringRadius = (outerRadius + innerRadius) / 2;
      const centroid = Utils$1.polarToCartesian(
        centerX,
        centerY,
        ringRadius,
        midAngle
      );
      const x = centroid.x + (w.layout.translateX || 0);
      const y = centroid.y + (w.layout.translateY || 0);
      tooltipEl.style.left = x - ttWidth / 2 + "px";
      tooltipEl.style.top = y - ttHeight - 10 + "px";
    }
  }
  /**
   * heatmap / treemap — position tooltip using element bounding rect
   * @param {number} i
   * @param {number} j
   * @param {import('../tooltip/Tooltip').default} ttCtx
   * @param {HTMLElement} tooltipEl
   * @param {string} type
   */
  _showTooltipHeatTree(i, j, ttCtx, tooltipEl, type) {
    var _a, _b;
    const w = this.w;
    ttCtx.tooltipLabels.drawSeriesTexts({
      ttItems: ttCtx.ttItems,
      i,
      j,
      shared: false
    });
    const tooltipRect = tooltipEl.getBoundingClientRect();
    const ttWidth = tooltipRect.width || ttCtx.tooltipRect.ttWidth || 0;
    const ttHeight = tooltipRect.height || ttCtx.tooltipRect.ttHeight || 0;
    const rectClass = type === "heatmap" ? "apexcharts-heatmap-rect" : "apexcharts-treemap-rect";
    const cell = w.dom.baseEl.querySelector(`.${rectClass}[i='${i}'][j='${j}']`);
    if (cell) {
      const wrapRect = w.dom.elWrap.getBoundingClientRect();
      const cellRect = cell.getBoundingClientRect();
      const cellCx = cellRect.left - wrapRect.left;
      const cellCy = cellRect.top - wrapRect.top;
      const cellWidth = cellRect.width;
      const cellHeight = cellRect.height;
      const cx = parseFloat((_a = cell.getAttribute("cx")) != null ? _a : "");
      const cellWidthAttr = parseFloat((_b = cell.getAttribute("width")) != null ? _b : "");
      ttCtx.tooltipPosition.moveXCrosshairs(cx + cellWidthAttr / 2);
      let x = cellCx + cellWidth + ttWidth / 2;
      const y = cellCy + cellHeight / 2 - ttHeight / 2;
      if (cellCx + cellWidth > w.layout.gridWidth / 2) {
        x = cellCx - ttWidth / 2;
      }
      tooltipEl.style.left = x + "px";
      tooltipEl.style.top = y + "px";
    }
  }
  // ─── Focus class management ───────────────────────────────────────────────
  /**
   * @param {number} i
   * @param {number} j
   */
  _applyFocusClass(i, j) {
    this._removeFocusClass();
    const el = this._getFocusableElement(i, j);
    if (el) {
      el.classList.add("apexcharts-keyboard-focused");
      el.setAttribute("role", "img");
      const label = this._buildPointLabel(i, j);
      if (label) el.setAttribute("aria-label", label);
      this._focusedEl = el;
    }
  }
  _removeFocusClass() {
    if (this._focusedEl) {
      this._focusedEl.classList.remove("apexcharts-keyboard-focused");
      this._focusedEl.removeAttribute("role");
      this._focusedEl.removeAttribute("aria-label");
      this._focusedEl = null;
    }
  }
  /**
   * Build an accessible label for the data point at (i, j) using the same
   * formatters the visible tooltip / axis labels use, so SR output matches
   * the visual presentation.
   * @param {number} i
   * @param {number} j
   * @returns {string}
   */
  _buildPointLabel(i, j) {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const w = this.w;
    const type = w.config.chart.type;
    const seriesNames = w.seriesData.seriesNames || [];
    const series = w.seriesData.series || [];
    if (type === "pie" || type === "donut" || type === "polarArea") {
      const sliceLabel = (_b = ((_a = w.labelData) == null ? void 0 : _a.labels) && w.labelData.labels[j]) != null ? _b : "";
      const value = Array.isArray(series) ? series[j] : "";
      return sliceLabel ? `${sliceLabel}: ${value}` : `${value}`;
    }
    if (type === "radialBar") {
      const seriesName2 = seriesNames[i] || `Series ${i + 1}`;
      const value = Array.isArray(series) ? series[i] : "";
      return `${seriesName2}: ${value}`;
    }
    const seriesName = seriesNames[i] || `Series ${i + 1}`;
    const row = Array.isArray(series[i]) ? series[i] : [];
    const rawValue = row[j];
    let formattedValue = rawValue == null ? "" : String(rawValue);
    const yFormatter = (_d = (_c = w.formatters) == null ? void 0 : _c.yLabelFormatters) == null ? void 0 : _d[i];
    if (typeof yFormatter === "function") {
      try {
        formattedValue = yFormatter(rawValue, {
          seriesIndex: i,
          dataPointIndex: j,
          w
        });
      } catch (e) {
      }
    }
    let category = "";
    const categoryLabels = (_e = w.labelData) == null ? void 0 : _e.categoryLabels;
    const seriesX = (_g = (_f = w.seriesData) == null ? void 0 : _f.seriesX) == null ? void 0 : _g[i];
    if (Array.isArray(categoryLabels) && categoryLabels[j] != null) {
      category = String(categoryLabels[j]);
    } else if (Array.isArray(seriesX) && seriesX[j] != null) {
      const xFormatter = (_h = w.formatters) == null ? void 0 : _h.xLabelFormatter;
      if (typeof xFormatter === "function") {
        try {
          category = String(
            xFormatter(seriesX[j], { seriesIndex: i, dataPointIndex: j, w })
          );
        } catch (e) {
          category = String(seriesX[j]);
        }
      } else {
        category = String(seriesX[j]);
      }
    }
    return category ? `${seriesName}: ${formattedValue}, ${category}` : `${seriesName}: ${formattedValue}`;
  }
  _leaveHoveredBar() {
    if (this._hoveredBarEl) {
      const graphics = new Graphics(this.w, this.ctx);
      graphics.pathMouseLeave(this._hoveredBarEl, null);
      this._hoveredBarEl = null;
    }
  }
  /**
   * @param {number} i
   * @param {number} j
   */
  _getFocusableElement(i, j) {
    const w = this.w;
    const type = w.config.chart.type;
    const baseEl = w.dom.baseEl;
    if (type === "pie" || type === "donut" || type === "polarArea") {
      return baseEl.querySelector(`.apexcharts-pie-area[j='${j}']`);
    }
    if (type === "heatmap") {
      return baseEl.querySelector(
        `.apexcharts-heatmap-rect[i='${i}'][j='${j}']`
      );
    }
    if (type === "treemap") {
      return baseEl.querySelector(
        `.apexcharts-treemap-rect[i='${i}'][j='${j}']`
      );
    }
    if (type === "radialBar") {
      return baseEl.querySelector(
        `.apexcharts-radialbar-series[data\\:realIndex='${i}'] path`
      );
    }
    if (type === "bar" || type === "candlestick" || type === "boxPlot" || type === "rangeBar") {
      return baseEl.querySelector(
        `.apexcharts-series[data\\:realIndex='${i}'] path[j='${j}']`
      );
    }
    const marker = baseEl.querySelector(
      `.apexcharts-series[data\\:realIndex='${i}'] .apexcharts-marker[rel='${j}']`
    );
    return marker || null;
  }
  // ─── Click / Enter ────────────────────────────────────────────────────────
  _fireClick() {
    const w = this.w;
    const ttCtx = w.globals.tooltip;
    if (!ttCtx) return;
    const syntheticEvent = {
      type: "mouseup",
      clientX: 0,
      clientY: 0
    };
    ttCtx.markerClick(syntheticEvent, this.seriesIndex, this.dataPointIndex);
  }
  // ─── Helpers ──────────────────────────────────────────────────────────────
  _isNavEnabled() {
    const a11y = this.w.config.chart.accessibility;
    return a11y.enabled && a11y.keyboard.enabled && a11y.keyboard.navigation.enabled;
  }
  _getSeriesCount() {
    const w = this.w;
    const type = w.config.chart.type;
    if (type === "pie" || type === "donut" || type === "polarArea") {
      return 1;
    }
    return w.seriesData.series.length;
  }
  /**
   * @param {number} si
   */
  _getDataPointCount(si) {
    const w = this.w;
    const type = w.config.chart.type;
    if (type === "pie" || type === "donut" || type === "polarArea") {
      return w.seriesData.series.length;
    }
    const series = w.seriesData.series;
    return series[si] && Array.isArray(series[si]) ? series[si].length : 0;
  }
  _clampCursor() {
    const seriesCount = this._getSeriesCount();
    if (this.seriesIndex >= seriesCount) this.seriesIndex = seriesCount - 1;
    if (this.seriesIndex < 0) this.seriesIndex = 0;
    const dpCount = this._getDataPointCount(this.seriesIndex);
    if (this.dataPointIndex >= dpCount) this.dataPointIndex = dpCount - 1;
    if (this.dataPointIndex < 0) this.dataPointIndex = 0;
  }
  /**
   * When the chart is zoomed in, the current dataPointIndex may point to a
   * data point that is outside the visible viewport. Snap the cursor to the
   * first data point whose x-value falls within [minX, maxX].
   *
   * Only adjusts when w.seriesData.seriesX is populated (numeric/datetime axes).
   * Category-only charts (seriesX entries are strings or auto-indices) are
   * unaffected — all points are always visible.
   */
  _snapToVisibleRange() {
    const w = this.w;
    const gl = w.globals;
    const si = this.seriesIndex;
    if (!w.interact.zoomed) return;
    const seriesX = w.seriesData.seriesX && w.seriesData.seriesX[si];
    if (!seriesX || !seriesX.length) return;
    const minX = gl.minX;
    const maxX = gl.maxX;
    if (minX === void 0 || maxX === void 0) return;
    const currentX = seriesX[this.dataPointIndex];
    if (currentX >= minX && currentX <= maxX) return;
    const dpCount = seriesX.length;
    for (let di = 0; di < dpCount; di++) {
      if (seriesX[di] >= minX && seriesX[di] <= maxX) {
        this.dataPointIndex = di;
        return;
      }
    }
  }
  /**
   * Snap to the nearest visible data point in the given navigation direction.
   * direction > 0 → find the first visible point (left boundary of zoomed range)
   * direction < 0 → find the last visible point (right boundary of zoomed range)
   * @param {number} direction
   */
  _snapToVisibleRangeInDirection(direction) {
    const w = this.w;
    const gl = w.globals;
    const si = this.seriesIndex;
    const seriesX = w.seriesData.seriesX && w.seriesData.seriesX[si];
    if (!seriesX || !seriesX.length) return;
    const minX = gl.minX;
    const maxX = gl.maxX;
    if (minX === void 0 || maxX === void 0) return;
    const dpCount = seriesX.length;
    if (direction >= 0) {
      for (let di = 0; di < dpCount; di++) {
        if (seriesX[di] >= minX && seriesX[di] <= maxX) {
          this.dataPointIndex = di;
          return;
        }
      }
    } else {
      for (let di = dpCount - 1; di >= 0; di--) {
        if (seriesX[di] >= minX && seriesX[di] <= maxX) {
          this.dataPointIndex = di;
          return;
        }
      }
    }
  }
  /**
   * Check whether the data point at (si, di) is within the current visible
   * x-axis range. Used to skip out-of-viewport points during keyboard nav.
   * @param {number} si
   * @param {number} di
   */
  _isDataPointVisible(si, di) {
    const w = this.w;
    const gl = w.globals;
    if (!w.interact.zoomed) return true;
    const seriesX = w.seriesData.seriesX && w.seriesData.seriesX[si];
    if (!seriesX) return true;
    const x = seriesX[di];
    if (x === void 0) return true;
    return x >= gl.minX && x <= gl.maxX;
  }
  /**
   * Push a short status message to the visually-hidden aria-live region so
   * screen readers announce zoom / pan / reset events that have no inherent
   * tooltip update. Silently no-op if the region is missing or announcements
   * are disabled.
   * @param {string} message
   */
  _announce(message) {
    const w = this.w;
    if (!w.config.chart.accessibility.announcements.enabled) return;
    const baseEl = w.dom.baseEl;
    if (!baseEl) return;
    const region = baseEl.querySelector(".apexcharts-sr-status");
    if (!region) return;
    region.textContent = "";
    setTimeout(() => {
      region.textContent = message;
    }, 0);
  }
}
ApexCharts.registerFeatures({ keyboardNavigation: KeyboardNavigation });
class BarDataLabels {
  /**
   * @param {import('../../../charts/Bar').default} barCtx
   */
  constructor(barCtx) {
    this.w = barCtx.w;
    this.barCtx = barCtx;
    this.totalFormatter = this.w.config.plotOptions.bar.dataLabels.total.formatter;
    if (!this.totalFormatter) {
      this.totalFormatter = this.w.config.dataLabels.formatter;
    }
  }
  /** handleBarDataLabels is used to calculate the positions for the data-labels
   * It also sets the element's data attr for bars and calls drawCalculatedBarDataLabels()
   * After calculating, it also calls the function to draw data labels
   * @memberof Bar
   * @param {Record<string, any>} opts - bar properties used throughout the bar drawing function
   * @return {object} dataLabels node-element which you can append later
   **/
  handleBarDataLabels(opts) {
    const {
      x,
      y,
      y1,
      y2,
      i,
      j,
      realIndex,
      columnGroupIndex,
      series,
      barHeight,
      barWidth,
      barXPosition,
      barYPosition,
      visibleSeries
    } = opts;
    const w = this.w;
    const graphics = new Graphics(this.barCtx.w);
    const strokeWidth = Array.isArray(this.barCtx.strokeWidth) ? this.barCtx.strokeWidth[realIndex] : this.barCtx.strokeWidth;
    let bcx;
    let bcy;
    if (w.axisFlags.isXNumeric && !w.globals.isBarHorizontal) {
      bcx = x + barWidth * (visibleSeries + 1);
      bcy = y + barHeight * (visibleSeries + 1) - strokeWidth;
    } else {
      bcx = x + barWidth * visibleSeries;
      bcy = y + barHeight * visibleSeries;
    }
    let dataLabels = null;
    let totalDataLabels = null;
    let dataLabelsX = x;
    let dataLabelsY = y;
    let dataLabelsPos = (
      /** @type {any} */
      {}
    );
    const dataLabelsConfig = w.config.dataLabels;
    const barDataLabelsConfig = this.barCtx.barOptions.dataLabels;
    const barTotalDataLabelsConfig = this.barCtx.barOptions.dataLabels.total;
    if (typeof barYPosition !== "undefined" && this.barCtx.isRangeBar) {
      bcy = barYPosition;
      dataLabelsY = barYPosition;
    }
    if (typeof barXPosition !== "undefined" && this.barCtx.isVerticalGroupedRangeBar) {
      bcx = barXPosition;
      dataLabelsX = barXPosition;
    }
    const offX = dataLabelsConfig.offsetX;
    const offY = dataLabelsConfig.offsetY;
    let textRects = {
      width: 0,
      height: 0
    };
    if (w.config.dataLabels.enabled) {
      const yLabel = w.seriesData.series[i][j];
      textRects = graphics.getTextRects(
        w.config.dataLabels.formatter ? w.config.dataLabels.formatter(yLabel, __spreadProps(__spreadValues({}, w), {
          seriesIndex: i,
          dataPointIndex: j,
          w
        })) : w.formatters.yLabelFormatters[0](yLabel),
        parseFloat(dataLabelsConfig.style.fontSize).toString()
      );
    }
    const params = {
      x,
      y,
      i,
      j,
      realIndex,
      columnGroupIndex,
      bcx,
      bcy,
      barHeight,
      barWidth,
      textRects,
      strokeWidth,
      dataLabelsX,
      dataLabelsY,
      dataLabelsConfig,
      barDataLabelsConfig,
      barTotalDataLabelsConfig,
      offX,
      offY
    };
    if (this.barCtx.isHorizontal) {
      dataLabelsPos = this.calculateBarsDataLabelsPosition(params);
    } else {
      dataLabelsPos = this.calculateColumnsDataLabelsPosition(params);
    }
    dataLabels = this.drawCalculatedDataLabels({
      x: dataLabelsPos.dataLabelsX,
      y: dataLabelsPos.dataLabelsY,
      val: this.barCtx.isRangeBar ? [y1, y2] : w.config.chart.stackType === "100%" ? series[realIndex][j] : w.seriesData.series[realIndex][j],
      i: realIndex,
      j,
      barWidth,
      barHeight,
      textRects,
      dataLabelsConfig
    });
    if (w.config.chart.stacked && barTotalDataLabelsConfig.enabled) {
      totalDataLabels = this.drawTotalDataLabels({
        x: dataLabelsPos.totalDataLabelsX,
        y: dataLabelsPos.totalDataLabelsY,
        barWidth,
        barHeight,
        realIndex,
        textAnchor: dataLabelsPos.totalDataLabelsAnchor,
        val: this.getStackedTotalDataLabel({ realIndex, j }),
        dataLabelsConfig,
        barTotalDataLabelsConfig
      });
    }
    return {
      dataLabelsPos,
      dataLabels,
      totalDataLabels
    };
  }
  /** @param {{realIndex: any, j: any}} opts */
  getStackedTotalDataLabel({ realIndex, j }) {
    const w = this.w;
    let val = this.barCtx.stackedSeriesTotals[j];
    if (this.totalFormatter) {
      val = this.totalFormatter(val, __spreadProps(__spreadValues({}, w), {
        seriesIndex: realIndex,
        dataPointIndex: j,
        w
      }));
    }
    return val;
  }
  /**
   * @param {Record<string, any>} opts
   */
  calculateColumnsDataLabelsPosition(opts) {
    const w = this.w;
    let {
      i,
      j,
      realIndex,
      y,
      bcx,
      barWidth,
      barHeight,
      textRects,
      dataLabelsX,
      dataLabelsY,
      dataLabelsConfig,
      barDataLabelsConfig,
      barTotalDataLabelsConfig,
      strokeWidth,
      offX,
      offY
    } = opts;
    let totalDataLabelsY;
    let totalDataLabelsX;
    const totalDataLabelsAnchor = "middle";
    const totalDataLabelsBcx = bcx;
    barHeight = Math.abs(barHeight);
    const vertical = w.config.plotOptions.bar.dataLabels.orientation === "vertical";
    const { zeroEncounters } = this.barCtx.barHelpers.getZeroValueEncounters({
      i,
      j
    });
    bcx = bcx - strokeWidth / 2;
    const dataPointsDividedWidth = w.layout.gridWidth / w.globals.dataPoints;
    if (this.barCtx.isVerticalGroupedRangeBar) {
      dataLabelsX += barWidth / 2;
    } else {
      if (w.axisFlags.isXNumeric) {
        dataLabelsX = bcx - barWidth / 2 + offX;
      } else {
        dataLabelsX = bcx - dataPointsDividedWidth + barWidth / 2 + offX;
      }
      if (!w.config.chart.stacked && zeroEncounters > 0 && w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
        dataLabelsX -= barWidth * zeroEncounters;
      }
    }
    if (vertical) {
      const offsetDLX = 2;
      dataLabelsX = dataLabelsX + textRects.height / 2 - strokeWidth / 2 - offsetDLX;
    }
    const valIsNegative = w.seriesData.series[i][j] < 0;
    let newY = y;
    if (this.barCtx.isReversed) {
      newY = y + (valIsNegative ? barHeight : -barHeight);
    }
    switch (barDataLabelsConfig.position) {
      case "center":
        if (vertical) {
          if (valIsNegative) {
            dataLabelsY = newY - barHeight / 2 + offY;
          } else {
            dataLabelsY = newY + barHeight / 2 - offY;
          }
        } else {
          if (valIsNegative) {
            dataLabelsY = newY - barHeight / 2 + textRects.height / 2 + offY;
          } else {
            dataLabelsY = newY + barHeight / 2 + textRects.height / 2 - offY;
          }
        }
        break;
      case "bottom":
        if (vertical) {
          if (valIsNegative) {
            dataLabelsY = newY - barHeight + offY;
          } else {
            dataLabelsY = newY + barHeight - offY;
          }
        } else {
          if (valIsNegative) {
            dataLabelsY = newY - barHeight + textRects.height + strokeWidth + offY;
          } else {
            dataLabelsY = newY + barHeight - textRects.height / 2 + strokeWidth - offY;
          }
        }
        break;
      case "top":
        if (vertical) {
          if (valIsNegative) {
            dataLabelsY = newY + offY;
          } else {
            dataLabelsY = newY - offY;
          }
        } else {
          if (valIsNegative) {
            dataLabelsY = newY - textRects.height / 2 - offY;
          } else {
            dataLabelsY = newY + textRects.height + offY;
          }
        }
        break;
    }
    let lowestPrevY = newY;
    w.labelData.seriesGroups.forEach((sg) => {
      var _a;
      (_a = this.barCtx[sg.join(",")]) == null ? void 0 : _a.prevY.forEach(
        (arr) => {
          if (valIsNegative) {
            lowestPrevY = Math.max(arr[j], lowestPrevY);
          } else {
            lowestPrevY = Math.min(arr[j], lowestPrevY);
          }
        }
      );
    });
    if (this.barCtx.lastActiveBarSerieIndex === realIndex && barTotalDataLabelsConfig.enabled) {
      const ADDITIONAL_OFFY = 18;
      const graphics = new Graphics(this.barCtx.w);
      const totalLabeltextRects = graphics.getTextRects(
        this.getStackedTotalDataLabel({ realIndex, j }),
        dataLabelsConfig.fontSize
      );
      if (valIsNegative) {
        totalDataLabelsY = lowestPrevY - totalLabeltextRects.height / 2 - offY - barTotalDataLabelsConfig.offsetY + ADDITIONAL_OFFY;
      } else {
        totalDataLabelsY = lowestPrevY + totalLabeltextRects.height + offY + barTotalDataLabelsConfig.offsetY - ADDITIONAL_OFFY;
      }
      const xDivision = dataPointsDividedWidth;
      totalDataLabelsX = totalDataLabelsBcx + (w.axisFlags.isXNumeric ? -barWidth * w.globals.barGroups.length / 2 : w.globals.barGroups.length * barWidth / 2 - (w.globals.barGroups.length - 1) * barWidth - xDivision) + barTotalDataLabelsConfig.offsetX;
    }
    if (!w.config.chart.stacked) {
      if (dataLabelsY < 0) {
        dataLabelsY = 0 + strokeWidth;
      } else if (dataLabelsY + textRects.height / 3 > w.layout.gridHeight) {
        dataLabelsY = w.layout.gridHeight - strokeWidth;
      }
    }
    return {
      bcx,
      bcy: y,
      dataLabelsX,
      dataLabelsY,
      totalDataLabelsX,
      totalDataLabelsY,
      totalDataLabelsAnchor
    };
  }
  /**
   * @param {Record<string, any>} opts
   */
  calculateBarsDataLabelsPosition(opts) {
    const w = this.w;
    let {
      x,
      i,
      j,
      realIndex,
      bcy,
      barHeight,
      barWidth,
      textRects,
      dataLabelsX,
      strokeWidth,
      dataLabelsConfig,
      barDataLabelsConfig,
      barTotalDataLabelsConfig,
      offX,
      offY
    } = opts;
    const dataPointsDividedHeight = w.layout.gridHeight / w.globals.dataPoints;
    const { zeroEncounters } = this.barCtx.barHelpers.getZeroValueEncounters({
      i,
      j
    });
    barWidth = Math.abs(barWidth);
    let dataLabelsY = bcy - (this.barCtx.isRangeBar ? 0 : dataPointsDividedHeight) + barHeight / 2 + textRects.height / 2 + offY - 3;
    if (!w.config.chart.stacked && zeroEncounters > 0 && w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
      dataLabelsY -= barHeight * zeroEncounters;
    }
    let totalDataLabelsX;
    let totalDataLabelsY;
    let totalDataLabelsAnchor = "start";
    const valIsNegative = w.seriesData.series[i][j] < 0;
    let newX = x;
    if (this.barCtx.isReversed) {
      newX = x + (valIsNegative ? -barWidth : barWidth);
      totalDataLabelsAnchor = valIsNegative ? "start" : "end";
    }
    switch (barDataLabelsConfig.position) {
      case "center":
        if (valIsNegative) {
          dataLabelsX = newX + barWidth / 2 - offX;
        } else {
          dataLabelsX = Math.max(textRects.width / 2, newX - barWidth / 2) + offX;
        }
        break;
      case "bottom":
        if (valIsNegative) {
          dataLabelsX = newX + barWidth - strokeWidth - offX;
        } else {
          dataLabelsX = newX - barWidth + strokeWidth + offX;
        }
        break;
      case "top":
        if (valIsNegative) {
          dataLabelsX = newX - strokeWidth - offX;
        } else {
          dataLabelsX = newX - strokeWidth + offX;
        }
        break;
    }
    let lowestPrevX = newX;
    w.labelData.seriesGroups.forEach((sg) => {
      var _a;
      (_a = this.barCtx[sg.join(",")]) == null ? void 0 : _a.prevX.forEach(
        (arr) => {
          if (valIsNegative) {
            lowestPrevX = Math.min(arr[j], lowestPrevX);
          } else {
            lowestPrevX = Math.max(arr[j], lowestPrevX);
          }
        }
      );
    });
    if (this.barCtx.lastActiveBarSerieIndex === realIndex && barTotalDataLabelsConfig.enabled) {
      const graphics = new Graphics(this.barCtx.w);
      const totalLabeltextRects = graphics.getTextRects(
        this.getStackedTotalDataLabel({ realIndex, j }),
        dataLabelsConfig.fontSize
      );
      if (valIsNegative) {
        totalDataLabelsX = lowestPrevX - strokeWidth - offX - barTotalDataLabelsConfig.offsetX;
        totalDataLabelsAnchor = "end";
      } else {
        totalDataLabelsX = lowestPrevX + offX + barTotalDataLabelsConfig.offsetX + (this.barCtx.isReversed ? -(barWidth + strokeWidth) : strokeWidth);
      }
      totalDataLabelsY = dataLabelsY - textRects.height / 2 + totalLabeltextRects.height / 2 + barTotalDataLabelsConfig.offsetY + strokeWidth;
      if (w.globals.barGroups.length > 1) {
        totalDataLabelsY = totalDataLabelsY - w.globals.barGroups.length / 2 * (barHeight / 2);
      }
    }
    if (!w.config.chart.stacked) {
      if (dataLabelsConfig.textAnchor === "start") {
        if (dataLabelsX - textRects.width < 0) {
          dataLabelsX = valIsNegative ? textRects.width + strokeWidth : strokeWidth;
        } else if (dataLabelsX + textRects.width > w.layout.gridWidth) {
          dataLabelsX = valIsNegative ? w.layout.gridWidth - strokeWidth : w.layout.gridWidth - textRects.width - strokeWidth;
        }
      } else if (dataLabelsConfig.textAnchor === "middle") {
        if (dataLabelsX - textRects.width / 2 < 0) {
          dataLabelsX = textRects.width / 2 + strokeWidth;
        } else if (dataLabelsX + textRects.width / 2 > w.layout.gridWidth) {
          dataLabelsX = w.layout.gridWidth - textRects.width / 2 - strokeWidth;
        }
      } else if (dataLabelsConfig.textAnchor === "end") {
        if (dataLabelsX < 1) {
          dataLabelsX = textRects.width + strokeWidth;
        } else if (dataLabelsX + 1 > w.layout.gridWidth) {
          dataLabelsX = w.layout.gridWidth - textRects.width - strokeWidth;
        }
      }
    }
    return {
      bcx: x,
      bcy,
      dataLabelsX,
      dataLabelsY,
      totalDataLabelsX,
      totalDataLabelsY,
      totalDataLabelsAnchor
    };
  }
  /** @param {{x: any, y: any, val: any, i: any, j: any, textRects: any, barHeight: any, barWidth: any, dataLabelsConfig: any}} opts */
  drawCalculatedDataLabels({
    x,
    y,
    val,
    i,
    // = realIndex
    j,
    textRects,
    barHeight,
    barWidth,
    dataLabelsConfig
  }) {
    const w = this.w;
    let rotate = "rotate(0)";
    if (w.config.plotOptions.bar.dataLabels.orientation === "vertical")
      rotate = `rotate(-90, ${x}, ${y})`;
    const dataLabels = new DataLabels(this.barCtx.w, this.barCtx.ctx);
    const graphics = new Graphics(this.barCtx.w);
    const formatter = dataLabelsConfig.formatter;
    let elDataLabelsWrap = null;
    const isSeriesNotCollapsed = w.globals.collapsedSeriesIndices.indexOf(i) > -1;
    if (dataLabelsConfig.enabled && !isSeriesNotCollapsed) {
      elDataLabelsWrap = graphics.group({
        class: "apexcharts-data-labels",
        transform: rotate
      });
      let text = "";
      if (typeof val !== "undefined") {
        text = formatter(val, __spreadProps(__spreadValues({}, w), {
          seriesIndex: i,
          dataPointIndex: j,
          w
        }));
      }
      if (!val && w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
        text = "";
      }
      const valIsNegative = w.seriesData.series[i][j] < 0;
      const position = w.config.plotOptions.bar.dataLabels.position;
      if (w.config.plotOptions.bar.dataLabels.orientation === "vertical") {
        if (position === "top") {
          if (valIsNegative) dataLabelsConfig.textAnchor = "end";
          else dataLabelsConfig.textAnchor = "start";
        }
        if (position === "center") {
          dataLabelsConfig.textAnchor = "middle";
        }
        if (position === "bottom") {
          if (valIsNegative) dataLabelsConfig.textAnchor = "end";
          else dataLabelsConfig.textAnchor = "start";
        }
      }
      if (this.barCtx.isRangeBar && this.barCtx.barOptions.dataLabels.hideOverflowingLabels) {
        const txRect = graphics.getTextRects(
          text,
          parseFloat(dataLabelsConfig.style.fontSize).toString()
        );
        if (barWidth < txRect.width) {
          text = "";
        }
      }
      if (w.config.chart.stacked && this.barCtx.barOptions.dataLabels.hideOverflowingLabels) {
        if (this.barCtx.isHorizontal) {
          if (textRects.width / 1.6 > Math.abs(barWidth)) {
            text = "";
          }
        } else {
          if (textRects.height / 1.6 > Math.abs(barHeight)) {
            text = "";
          }
        }
      }
      const modifiedDataLabelsConfig = __spreadValues({}, dataLabelsConfig);
      if (this.barCtx.isHorizontal) {
        if (val < 0) {
          if (dataLabelsConfig.textAnchor === "start") {
            modifiedDataLabelsConfig.textAnchor = "end";
          } else if (dataLabelsConfig.textAnchor === "end") {
            modifiedDataLabelsConfig.textAnchor = "start";
          }
        }
      }
      dataLabels.plotDataLabelsText({
        x,
        y,
        text,
        i,
        j,
        parent: elDataLabelsWrap,
        dataLabelsConfig: modifiedDataLabelsConfig,
        alwaysDrawDataLabel: true,
        offsetCorrection: true
      });
    }
    return elDataLabelsWrap;
  }
  /** @param {{ x?: any, y?: any, val?: any, realIndex?: any, textAnchor?: any, barWidth?: any, barHeight?: any, dataLabelsConfig?: any, barTotalDataLabelsConfig?: any }} opts */
  drawTotalDataLabels({
    x,
    y,
    val,
    realIndex,
    textAnchor,
    barTotalDataLabelsConfig
  }) {
    const graphics = new Graphics(this.barCtx.w);
    let totalDataLabelText;
    if (barTotalDataLabelsConfig.enabled && typeof x !== "undefined" && typeof y !== "undefined" && this.barCtx.lastActiveBarSerieIndex === realIndex) {
      totalDataLabelText = graphics.drawText({
        x,
        y,
        foreColor: barTotalDataLabelsConfig.style.color,
        text: val,
        textAnchor,
        fontFamily: barTotalDataLabelsConfig.style.fontFamily,
        fontSize: barTotalDataLabelsConfig.style.fontSize,
        fontWeight: barTotalDataLabelsConfig.style.fontWeight
      });
    }
    return totalDataLabelText;
  }
}
let Helpers$1 = class Helpers4 {
  /**
   * @param {Record<string, any>} barCtx
   */
  constructor(barCtx) {
    this.w = barCtx.w;
    this.barCtx = barCtx;
  }
  /**
   * @param {any[]} series
   */
  initVariables(series) {
    const w = this.w;
    this.barCtx.series = series;
    this.barCtx.totalItems = 0;
    this.barCtx.seriesLen = 0;
    this.barCtx.visibleI = -1;
    this.barCtx.visibleItems = 1;
    for (let sl = 0; sl < series.length; sl++) {
      if (series[sl].length > 0) {
        this.barCtx.seriesLen = this.barCtx.seriesLen + 1;
        this.barCtx.totalItems += series[sl].length;
      }
      if (w.axisFlags.isXNumeric) {
        for (let j = 0; j < series[sl].length; j++) {
          if (w.seriesData.seriesX[sl][j] > w.globals.minX && w.seriesData.seriesX[sl][j] < w.globals.maxX) {
            this.barCtx.visibleItems++;
          }
        }
      } else {
        this.barCtx.visibleItems = w.globals.dataPoints;
      }
    }
    this.arrBorderRadius = this.createBorderRadiusArr(w.seriesData.series);
    if (Utils$1.isSafari()) {
      this.arrBorderRadius = this.arrBorderRadius.map(
        (brArr) => (
          /**
           * @param {any} _
           */
          brArr.map((_) => "none")
        )
      );
    }
    if (this.barCtx.seriesLen === 0) {
      this.barCtx.seriesLen = 1;
    }
    this.barCtx.zeroSerieses = [];
    if (!w.globals.comboCharts) {
      this.checkZeroSeries({ series });
    }
  }
  /**
   * @param {number} realIndex
   */
  initialPositions(realIndex) {
    const w = this.w;
    let x, y, yDivision, xDivision, barHeight, barWidth, zeroH, zeroW;
    let dataPoints = w.globals.dataPoints;
    if (this.barCtx.isRangeBar) {
      dataPoints = w.labelData.labels.length;
    }
    let seriesLen = this.barCtx.seriesLen;
    if (w.config.plotOptions.bar.rangeBarGroupRows) {
      seriesLen = 1;
    }
    if (this.barCtx.isHorizontal) {
      yDivision = w.layout.gridHeight / dataPoints;
      barHeight = yDivision / seriesLen;
      if (w.axisFlags.isXNumeric) {
        yDivision = w.layout.gridHeight / this.barCtx.totalItems;
        barHeight = yDivision / this.barCtx.seriesLen;
      }
      barHeight = barHeight * parseInt(this.barCtx.barOptions.barHeight, 10) / 100;
      if (String(this.barCtx.barOptions.barHeight).indexOf("%") === -1) {
        barHeight = parseInt(this.barCtx.barOptions.barHeight, 10);
      }
      zeroW = this.barCtx.baseLineInvertedY + w.globals.padHorizontal + (this.barCtx.isReversed ? w.layout.gridWidth : 0) - (this.barCtx.isReversed ? this.barCtx.baseLineInvertedY * 2 : 0);
      if (this.barCtx.isFunnel) {
        zeroW = w.layout.gridWidth / 2;
      }
      y = (yDivision - barHeight * this.barCtx.seriesLen) / 2;
    } else {
      xDivision = w.layout.gridWidth / this.barCtx.visibleItems;
      if (w.config.xaxis.convertedCatToNumeric) {
        xDivision = w.layout.gridWidth / w.globals.dataPoints;
      }
      barWidth = xDivision / seriesLen * parseInt(this.barCtx.barOptions.columnWidth, 10) / 100;
      if (w.axisFlags.isXNumeric) {
        const xRatio = this.barCtx.xRatio;
        if (w.globals.minXDiff && w.globals.minXDiff !== 0.5 && w.globals.minXDiff / xRatio > 0) {
          xDivision = w.globals.minXDiff / xRatio;
        }
        barWidth = xDivision / seriesLen * parseInt(this.barCtx.barOptions.columnWidth, 10) / 100;
        if (barWidth < 1) {
          barWidth = 1;
        }
      }
      if (String(this.barCtx.barOptions.columnWidth).indexOf("%") === -1) {
        barWidth = parseInt(this.barCtx.barOptions.columnWidth, 10);
      }
      zeroH = w.layout.gridHeight - this.barCtx.baseLineY[this.barCtx.translationsIndex] - (this.barCtx.isReversed ? w.layout.gridHeight : 0) + (this.barCtx.isReversed ? this.barCtx.baseLineY[this.barCtx.translationsIndex] * 2 : 0);
      if (w.axisFlags.isXNumeric) {
        const xForNumericX = this.barCtx.getBarXForNumericXAxis({
          x,
          j: 0,
          realIndex,
          barWidth
        });
        x = xForNumericX.x;
      } else {
        x = w.globals.padHorizontal + Utils$1.noExponents(xDivision - barWidth * this.barCtx.seriesLen) / 2;
      }
    }
    w.globals.barHeight = barHeight;
    w.globals.barWidth = barWidth;
    return {
      x,
      y,
      yDivision,
      xDivision,
      barHeight,
      barWidth,
      zeroH,
      zeroW
    };
  }
  /**
   * @param {Record<string, any>} ctx
   */
  initializeStackedPrevVars(ctx) {
    const w = ctx.w;
    w.labelData.seriesGroups.forEach((group) => {
      if (!ctx[group]) ctx[group] = {};
      ctx[group].prevY = [];
      ctx[group].prevX = [];
      ctx[group].prevYF = [];
      ctx[group].prevXF = [];
      ctx[group].prevYVal = [];
      ctx[group].prevXVal = [];
    });
  }
  /**
   * @param {Record<string, any>} ctx
   */
  initializeStackedXYVars(ctx) {
    const w = ctx.w;
    w.labelData.seriesGroups.forEach((group) => {
      if (!ctx[group]) ctx[group] = {};
      ctx[group].xArrj = [];
      ctx[group].xArrjF = [];
      ctx[group].xArrjVal = [];
      ctx[group].yArrj = [];
      ctx[group].yArrjF = [];
      ctx[group].yArrjVal = [];
    });
  }
  /**
   * @param {any[]} series
   * @param {number} i
   * @param {number} j
   * @param {number} realIndex
   */
  getPathFillColor(series, i, j, realIndex) {
    var _a, _b, _c, _d;
    const w = this.w;
    const fill = new Fill(this.barCtx.w);
    let fillColor = null;
    const seriesNumber = this.barCtx.barOptions.distributed ? j : i;
    let useRangeColor = false;
    if (this.barCtx.barOptions.colors.ranges.length > 0) {
      const colorRange = this.barCtx.barOptions.colors.ranges;
      colorRange.map((range) => {
        if (series[i][j] >= range.from && series[i][j] <= range.to) {
          fillColor = range.color;
          useRangeColor = true;
        }
      });
    }
    const pathFill = fill.fillPath({
      seriesNumber: this.barCtx.barOptions.distributed ? seriesNumber : realIndex,
      dataPointIndex: j,
      color: fillColor,
      value: series[i][j],
      fillConfig: (_a = w.config.series[i].data[j]) == null ? void 0 : _a.fill,
      fillType: ((_c = (_b = w.config.series[i].data[j]) == null ? void 0 : _b.fill) == null ? void 0 : _c.type) ? (_d = w.config.series[i].data[j]) == null ? void 0 : _d.fill.type : Array.isArray(w.config.fill.type) ? w.config.fill.type[realIndex] : w.config.fill.type
    });
    return {
      color: pathFill,
      useRangeColor
    };
  }
  /**
   * @param {number} i
   * @param {number} j
   * @param {number} realIndex
   */
  getStrokeWidth(i, j, realIndex) {
    let strokeWidth = 0;
    const w = this.w;
    if (typeof this.barCtx.series[i][j] === "undefined" || this.barCtx.series[i][j] === null || w.config.chart.type === "bar" && !this.barCtx.series[i][j]) {
      this.barCtx.isNullValue = true;
    } else {
      this.barCtx.isNullValue = false;
    }
    if (w.config.stroke.show) {
      if (!this.barCtx.isNullValue) {
        strokeWidth = Array.isArray(this.barCtx.strokeWidth) ? this.barCtx.strokeWidth[realIndex] : this.barCtx.strokeWidth;
      }
    }
    return strokeWidth;
  }
  /**
   * @param {any[]} series
   */
  createBorderRadiusArr(series) {
    var _a;
    const w = this.w;
    const alwaysApplyRadius = !this.w.config.chart.stacked || w.config.plotOptions.bar.borderRadius <= 0;
    const numSeries = series.length;
    const numColumns = ((_a = series[0]) == null ? void 0 : _a.length) | 0;
    const output = Array.from(
      { length: numSeries },
      () => Array(numColumns).fill(alwaysApplyRadius ? "top" : "none")
    );
    if (alwaysApplyRadius) return output;
    const chartType = this.w.config.chart.type;
    for (let j = 0; j < numColumns; j++) {
      const positiveIndices = [];
      const negativeIndices = [];
      let nonZeroCount = 0;
      for (let i = 0; i < numSeries; i++) {
        const value = series[i][j];
        if (value > 0) {
          positiveIndices.push(i);
          nonZeroCount++;
        } else if (value < 0) {
          negativeIndices.push(i);
          nonZeroCount++;
        }
      }
      if (positiveIndices.length > 0 && negativeIndices.length === 0) {
        if (positiveIndices.length === 1) {
          output[positiveIndices[0]][j] = chartType === "bar" && numColumns === 1 ? "top" : "both";
        } else {
          const firstPositiveIndex = positiveIndices[0];
          const lastPositiveIndex = positiveIndices[positiveIndices.length - 1];
          for (const i of positiveIndices) {
            if (i === firstPositiveIndex) {
              output[i][j] = chartType === "bar" && numColumns === 1 ? "top" : "bottom";
            } else if (i === lastPositiveIndex) {
              output[i][j] = "top";
            } else {
              output[i][j] = "none";
            }
          }
        }
      } else if (negativeIndices.length > 0 && positiveIndices.length === 0) {
        if (negativeIndices.length === 1) {
          output[negativeIndices[0]][j] = "both";
        } else {
          const highestNegativeIndex = Math.max(...negativeIndices);
          const lowestNegativeIndex = Math.min(...negativeIndices);
          for (const i of negativeIndices) {
            if (i === highestNegativeIndex) {
              output[i][j] = "bottom";
            } else if (i === lowestNegativeIndex) {
              output[i][j] = "top";
            } else {
              output[i][j] = "none";
            }
          }
        }
      } else if (positiveIndices.length > 0 && negativeIndices.length > 0) {
        const lastPositiveIndex = positiveIndices[positiveIndices.length - 1];
        for (const i of positiveIndices) {
          if (i === lastPositiveIndex) {
            output[i][j] = "top";
          } else {
            output[i][j] = "none";
          }
        }
        const highestNegativeIndex = Math.max(...negativeIndices);
        for (const i of negativeIndices) {
          if (i === highestNegativeIndex) {
            output[i][j] = "bottom";
          } else {
            output[i][j] = "none";
          }
        }
      } else if (nonZeroCount === 1) {
        const index = positiveIndices[0] || negativeIndices[0];
        output[index][j] = "both";
      }
    }
    return output;
  }
  /** @param {{ j?: any, i?: any, x1?: any, x2?: any, y1?: any, y2?: any, bc?: any, elSeries?: any }} opts */
  barBackground({ j, i, x1, x2, y1, y2, elSeries }) {
    const w = this.w;
    const graphics = new Graphics(this.barCtx.w);
    const sr = new Series(this.barCtx.w);
    const activeSeriesIndex = sr.getActiveConfigSeriesIndex();
    if (this.barCtx.barOptions.colors.backgroundBarColors.length > 0 && activeSeriesIndex === i) {
      if (j >= this.barCtx.barOptions.colors.backgroundBarColors.length) {
        j %= this.barCtx.barOptions.colors.backgroundBarColors.length;
      }
      const bcolor = this.barCtx.barOptions.colors.backgroundBarColors[j];
      const rect = graphics.drawRect(
        typeof x1 !== "undefined" ? x1 : 0,
        typeof y1 !== "undefined" ? y1 : 0,
        typeof x2 !== "undefined" ? x2 : w.layout.gridWidth,
        typeof y2 !== "undefined" ? y2 : w.layout.gridHeight,
        this.barCtx.barOptions.colors.backgroundBarRadius,
        bcolor,
        this.barCtx.barOptions.colors.backgroundBarOpacity
      );
      elSeries.add(rect);
      rect.node.classList.add("apexcharts-backgroundBar");
    }
  }
  /** @param {{ barWidth?: any, barXPosition?: any, y1?: any, y2?: any, yRatio?: any, strokeWidth?: any, isReversed?: any, series?: any, seriesGroup?: any, realIndex?: any, i?: any, j?: any, w?: any }} opts */
  getColumnPaths({
    barWidth,
    barXPosition,
    y1,
    y2,
    strokeWidth,
    isReversed,
    series,
    seriesGroup,
    realIndex,
    i,
    j,
    w
  }) {
    var _a;
    const graphics = new Graphics(this.barCtx.w);
    strokeWidth = Array.isArray(strokeWidth) ? strokeWidth[realIndex] : strokeWidth;
    if (!strokeWidth) strokeWidth = 0;
    let bW = barWidth;
    let bXP = barXPosition;
    if ((_a = w.config.series[realIndex].data[j]) == null ? void 0 : _a.columnWidthOffset) {
      bXP = barXPosition - w.config.series[realIndex].data[j].columnWidthOffset / 2;
      bW = barWidth + w.config.series[realIndex].data[j].columnWidthOffset;
    }
    const strokeCenter = strokeWidth / 2;
    const x1 = bXP + strokeCenter;
    const x2 = bXP + bW - strokeCenter;
    const direction = (series[i][j] >= 0 ? 1 : -1) * (isReversed ? -1 : 1);
    y1 += 1e-3 - strokeCenter * direction;
    y2 += 1e-3 + strokeCenter * direction;
    let pathTo = graphics.move(x1, y1);
    let pathFrom = graphics.move(x1, y1);
    const sl = graphics.line(x2, y1);
    if (w.globals.previousPaths.length > 0) {
      pathFrom = this.barCtx.getPreviousPath(realIndex, j, false);
    }
    pathTo = pathTo + graphics.line(x1, y2) + graphics.line(x2, y2) + sl + (w.config.plotOptions.bar.borderRadiusApplication === "around" || this.arrBorderRadius[realIndex][j] === "both" ? " Z" : " z");
    pathFrom = pathFrom + graphics.line(x1, y1) + sl + sl + sl + sl + sl + graphics.line(x1, y1) + (w.config.plotOptions.bar.borderRadiusApplication === "around" || this.arrBorderRadius[realIndex][j] === "both" ? " Z" : " z");
    if (this.arrBorderRadius[realIndex][j] !== "none") {
      pathTo = graphics.roundPathCorners(
        pathTo,
        w.config.plotOptions.bar.borderRadius
      );
    }
    if (w.config.chart.stacked) {
      let _ctx = this.barCtx;
      _ctx = this.barCtx[seriesGroup];
      _ctx.yArrj.push(y2 - strokeCenter * direction);
      _ctx.yArrjF.push(Math.abs(y1 - y2 + strokeWidth * direction));
      _ctx.yArrjVal.push(this.barCtx.series[i][j]);
    }
    return {
      pathTo,
      pathFrom
    };
  }
  /** @param {{ barYPosition?: any, barHeight?: any, x1?: any, x2?: any, strokeWidth?: any, isReversed?: any, series?: any, seriesGroup?: any, realIndex?: any, i?: any, j?: any, w?: any }} opts */
  getBarpaths({
    barYPosition,
    barHeight,
    x1,
    x2,
    strokeWidth,
    isReversed,
    series,
    seriesGroup,
    realIndex,
    i,
    j,
    w
  }) {
    var _a;
    const graphics = new Graphics(this.barCtx.w);
    strokeWidth = Array.isArray(strokeWidth) ? strokeWidth[realIndex] : strokeWidth;
    if (!strokeWidth) strokeWidth = 0;
    let bYP = barYPosition;
    let bH = barHeight;
    if ((_a = w.config.series[realIndex].data[j]) == null ? void 0 : _a.barHeightOffset) {
      bYP = barYPosition - w.config.series[realIndex].data[j].barHeightOffset / 2;
      bH = barHeight + w.config.series[realIndex].data[j].barHeightOffset;
    }
    const strokeCenter = strokeWidth / 2;
    const y1 = bYP + strokeCenter;
    const y2 = bYP + bH - strokeCenter;
    const direction = (series[i][j] >= 0 ? 1 : -1) * (isReversed ? -1 : 1);
    x1 += 1e-3 + strokeCenter * direction;
    x2 += 1e-3 - strokeCenter * direction;
    let pathTo = graphics.move(x1, y1);
    let pathFrom = graphics.move(x1, y1);
    if (w.globals.previousPaths.length > 0) {
      pathFrom = this.barCtx.getPreviousPath(realIndex, j, false);
    }
    const sl = graphics.line(x1, y2);
    pathTo = pathTo + graphics.line(x2, y1) + graphics.line(x2, y2) + sl + (w.config.plotOptions.bar.borderRadiusApplication === "around" || this.arrBorderRadius[realIndex][j] === "both" ? " Z" : " z");
    pathFrom = pathFrom + graphics.line(x1, y1) + sl + sl + sl + sl + sl + graphics.line(x1, y1) + (w.config.plotOptions.bar.borderRadiusApplication === "around" || this.arrBorderRadius[realIndex][j] === "both" ? " Z" : " z");
    if (this.arrBorderRadius[realIndex][j] !== "none") {
      pathTo = graphics.roundPathCorners(
        pathTo,
        w.config.plotOptions.bar.borderRadius
      );
    }
    if (w.config.chart.stacked) {
      let _ctx = this.barCtx;
      _ctx = this.barCtx[seriesGroup];
      _ctx.xArrj.push(x2 + strokeCenter * direction);
      _ctx.xArrjF.push(Math.abs(x1 - x2 - strokeWidth * direction));
      _ctx.xArrjVal.push(this.barCtx.series[i][j]);
    }
    return {
      pathTo,
      pathFrom
    };
  }
  /** @param {{series: any}} opts */
  checkZeroSeries({ series }) {
    const w = this.w;
    for (let zs = 0; zs < series.length; zs++) {
      let total = 0;
      for (let zsj = 0; zsj < series[w.globals.maxValsInArrayIndex].length; zsj++) {
        total += series[zs][zsj];
      }
      if (total === 0) {
        this.barCtx.zeroSerieses.push(zs);
      }
    }
  }
  /**
   * @param {number} value
   * @param {number} zeroW
   */
  getXForValue(value, zeroW, zeroPositionForNull = true) {
    let xForVal = zeroPositionForNull ? zeroW : null;
    if (typeof value !== "undefined" && value !== null) {
      xForVal = zeroW + value / this.barCtx.invertedYRatio - (this.barCtx.isReversed ? value / this.barCtx.invertedYRatio : 0) * 2;
    }
    return xForVal;
  }
  /**
   * @param {number} value
   * @param {number} zeroH
   * @param {number} translationsIndex
   */
  getYForValue(value, zeroH, translationsIndex, zeroPositionForNull = true) {
    let yForVal = zeroPositionForNull ? zeroH : null;
    if (typeof value !== "undefined" && value !== null) {
      yForVal = zeroH - value / this.barCtx.yRatio[translationsIndex] + (this.barCtx.isReversed ? value / this.barCtx.yRatio[translationsIndex] : 0) * 2;
    }
    return yForVal;
  }
  /**
   * @param {string} type
   * @param {number} zeroW
   * @param {number} zeroH
   * @param {number} i
   * @param {number} j
   * @param {number} translationsIndex
   */
  getGoalValues(type, zeroW, zeroH, i, j, translationsIndex) {
    const w = this.w;
    const goals = [];
    const pushGoal = (value, attrs) => {
      goals.push({
        [type]: type === "x" ? this.getXForValue(value, zeroW, false) : this.getYForValue(value, zeroH, translationsIndex, false),
        attrs
      });
    };
    if (w.seriesData.seriesGoals[i] && w.seriesData.seriesGoals[i][j] && Array.isArray(w.seriesData.seriesGoals[i][j])) {
      w.seriesData.seriesGoals[i][j].forEach((goal) => {
        pushGoal(goal.value, goal);
      });
    }
    if (this.barCtx.barOptions.isDumbbell && w.rangeData.seriesRange.length) {
      const colors = this.barCtx.barOptions.dumbbellColors ? this.barCtx.barOptions.dumbbellColors : w.globals.colors;
      const commonAttrs = {
        strokeHeight: type === "x" ? 0 : w.globals.markers.size[i],
        strokeWidth: type === "x" ? w.globals.markers.size[i] : 0,
        strokeDashArray: 0,
        strokeLineCap: "round",
        strokeColor: Array.isArray(colors[i]) ? colors[i][0] : colors[i]
      };
      pushGoal(w.rangeData.seriesRangeStart[i][j], commonAttrs);
      pushGoal(w.rangeData.seriesRangeEnd[i][j], __spreadProps(__spreadValues({}, commonAttrs), {
        strokeColor: Array.isArray(colors[i]) ? colors[i][1] : colors[i]
      }));
    }
    return goals;
  }
  /** @param {{barXPosition: any, barYPosition: any, goalX: any, goalY: any, barWidth: any, barHeight: any}} opts */
  drawGoalLine({
    barXPosition,
    barYPosition,
    goalX,
    goalY,
    barWidth,
    barHeight
  }) {
    const graphics = new Graphics(this.barCtx.w);
    const lineGroup = graphics.group({
      className: "apexcharts-bar-goals-groups"
    });
    lineGroup.node.classList.add("apexcharts-element-hidden");
    this.barCtx.w.globals.delayedElements.push({
      el: lineGroup.node
    });
    lineGroup.attr(
      "clip-path",
      `url(#gridRectMarkerMask${this.barCtx.w.globals.cuid})`
    );
    let line = null;
    if (this.barCtx.isHorizontal) {
      if (Array.isArray(goalX)) {
        goalX.forEach((goal) => {
          if (goal.x >= -1 && goal.x <= graphics.w.layout.gridWidth + 1) {
            const sHeight = typeof goal.attrs.strokeHeight !== "undefined" ? goal.attrs.strokeHeight : barHeight / 2;
            const y = barYPosition + sHeight + barHeight / 2;
            line = graphics.drawLine(
              goal.x,
              y - sHeight * 2,
              goal.x,
              y,
              goal.attrs.strokeColor ? goal.attrs.strokeColor : void 0,
              goal.attrs.strokeDashArray,
              goal.attrs.strokeWidth ? goal.attrs.strokeWidth : 2,
              goal.attrs.strokeLineCap
            );
            lineGroup.add(line);
          }
        });
      }
    } else {
      if (Array.isArray(goalY)) {
        goalY.forEach((goal) => {
          if (goal.y >= -1 && goal.y <= graphics.w.layout.gridHeight + 1) {
            const sWidth = typeof goal.attrs.strokeWidth !== "undefined" ? goal.attrs.strokeWidth : barWidth / 2;
            const x = barXPosition + sWidth + barWidth / 2;
            line = graphics.drawLine(
              x - sWidth * 2,
              goal.y,
              x,
              goal.y,
              goal.attrs.strokeColor ? goal.attrs.strokeColor : void 0,
              goal.attrs.strokeDashArray,
              goal.attrs.strokeHeight ? goal.attrs.strokeHeight : 2,
              goal.attrs.strokeLineCap
            );
            lineGroup.add(line);
          }
        });
      }
    }
    return lineGroup;
  }
  /** @param {{prevPaths: any, currPaths: any, color: any, realIndex: any, j: any}} opts */
  drawBarShadow({ prevPaths, currPaths, color, realIndex, j }) {
    const w = this.w;
    const { x: prevX2, x1: prevX1, barYPosition: prevY1 } = prevPaths;
    const { x: currX2, x1: currX1, barYPosition: currY1 } = currPaths;
    const prevY2 = prevY1 + currPaths.barHeight;
    const graphics = new Graphics(this.barCtx.w);
    const utils = new Utils$1();
    const shadowPath = graphics.move(prevX1, prevY2) + graphics.line(prevX2, prevY2) + graphics.line(currX2, currY1) + graphics.line(currX1, currY1) + graphics.line(prevX1, prevY2) + (w.config.plotOptions.bar.borderRadiusApplication === "around" || this.arrBorderRadius[realIndex][j] === "both" ? " Z" : " z");
    return graphics.drawPath({
      d: shadowPath,
      fill: utils.shadeColor(0.5, Utils$1.rgb2hex(color)),
      stroke: "none",
      strokeWidth: 0,
      fillOpacity: 1,
      classes: "apexcharts-bar-shadow apexcharts-decoration-element"
    });
  }
  /** @param {{i: any, j: any}} opts */
  getZeroValueEncounters({ i, j }) {
    var _a;
    const w = this.w;
    let nonZeroColumns = 0;
    let zeroEncounters = 0;
    const seriesIndices = w.config.plotOptions.bar.horizontal ? w.seriesData.series.map((_, _i) => _i) : ((_a = w.globals.columnSeries) == null ? void 0 : _a.i.map((_i) => _i)) || [];
    seriesIndices.forEach((_si) => {
      const val = w.globals.seriesPercent[_si][j];
      if (val) {
        nonZeroColumns++;
      }
      if (_si < i && val === 0) {
        zeroEncounters++;
      }
    });
    return {
      nonZeroColumns,
      zeroEncounters
    };
  }
  /**
   * @param {number} seriesIndex
   */
  getGroupIndex(seriesIndex) {
    const w = this.w;
    const groupIndex = w.labelData.seriesGroups.findIndex(
      (group) => (
        // w.config.series[i].name may be undefined, so use
        // w.seriesData.seriesNames[i], which has default names for those
        // series. w.labelData.seriesGroups[] uses the same default naming.
        group.indexOf(w.seriesData.seriesNames[seriesIndex]) > -1
      )
    );
    const cGI = this.barCtx.columnGroupIndices;
    let columnGroupIndex = cGI.indexOf(groupIndex);
    if (columnGroupIndex < 0) {
      cGI.push(groupIndex);
      columnGroupIndex = cGI.length - 1;
    }
    return { groupIndex, columnGroupIndex };
  }
};
class Bar {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   * @param {import('../types/internal').XYRatios} xyRatios
   */
  constructor(w, ctx, xyRatios) {
    this.ctx = ctx;
    this.w = w;
    this.barOptions = w.config.plotOptions.bar;
    this.isHorizontal = this.barOptions.horizontal;
    this.strokeWidth = w.config.stroke.width;
    this.isNullValue = false;
    this.isRangeBar = w.rangeData.seriesRange.length && this.isHorizontal;
    this.isVerticalGroupedRangeBar = !w.globals.isBarHorizontal && w.rangeData.seriesRange.length && w.config.plotOptions.bar.rangeBarGroupRows;
    this.isFunnel = this.barOptions.isFunnel;
    this.xyRatios = xyRatios;
    this.xRatio = 0;
    this.yRatio = [];
    this.invertedXRatio = 0;
    this.invertedYRatio = 0;
    this.baseLineY = [];
    this.baseLineInvertedY = 0;
    if (this.xyRatios !== null) {
      this.xRatio = xyRatios.xRatio;
      this.yRatio = xyRatios.yRatio;
      this.invertedXRatio = xyRatios.invertedXRatio;
      this.invertedYRatio = xyRatios.invertedYRatio;
      this.baseLineY = xyRatios.baseLineY;
      this.baseLineInvertedY = xyRatios.baseLineInvertedY;
    }
    this.yaxisIndex = 0;
    this.translationsIndex = 0;
    this.seriesLen = 0;
    this.pathArr = [];
    this.series = [];
    this.elSeries = null;
    this.visibleI = 0;
    this.isReversed = false;
    const ser = new Series(this.w);
    this.lastActiveBarSerieIndex = ser.getActiveConfigSeriesIndex("desc", [
      "bar",
      "column"
    ]);
    this.columnGroupIndices = [];
    const barSeriesIndices = ser.getBarSeriesIndices();
    const coreUtils = new CoreUtils(this.w);
    this.stackedSeriesTotals = coreUtils.getStackedSeriesTotals(
      this.w.config.series.map((s, i) => {
        return barSeriesIndices.indexOf(i) === -1 ? i : -1;
      }).filter((s) => {
        return s !== -1;
      })
    );
    this.barHelpers = new Helpers$1(this);
  }
  /** primary draw method which is called on bar object
   * @memberof Bar
   * @param {any[]} series - user supplied series values
   * @param {number} seriesIndex - the index by which series will be drawn on the svg
   * @return {Element} element which is supplied to parent chart draw method for appending
   **/
  draw(series, seriesIndex) {
    var _a;
    const w = this.w;
    const graphics = new Graphics(this.w);
    const coreUtils = new CoreUtils(this.w);
    series = coreUtils.getLogSeries(series);
    this.series = series;
    this.yRatio = coreUtils.getLogYRatios(this.yRatio);
    this.barHelpers.initVariables(series);
    const ret = graphics.group({
      class: "apexcharts-bar-series apexcharts-plot-series"
    });
    if (w.config.dataLabels.enabled) {
      if (this.totalItems > this.barOptions.dataLabels.maxItems) {
        console.warn(
          "WARNING: DataLabels are enabled but there are too many to display. This may cause performance issue when rendering - ApexCharts"
        );
      }
    }
    for (let i = 0, bc = 0; i < series.length; i++, bc++) {
      let x, y;
      const yArrj = [];
      const xArrj = [];
      const realIndex = w.globals.comboCharts ? (
        /** @type {any} */
        seriesIndex[i]
      ) : i;
      const { columnGroupIndex } = this.barHelpers.getGroupIndex(realIndex);
      const elSeries = graphics.group({
        class: `apexcharts-series`,
        rel: i + 1,
        seriesName: Utils$1.escapeString(w.seriesData.seriesNames[realIndex]),
        "data:realIndex": realIndex
      });
      Series.addCollapsedClassToSeries(this.w, elSeries, realIndex);
      if (series[i].length > 0) {
        this.visibleI = this.visibleI + 1;
      }
      if (this.yRatio.length > 1) {
        this.yaxisIndex = w.globals.seriesYAxisReverseMap[realIndex];
        this.translationsIndex = realIndex;
      }
      const translationsIndex = this.translationsIndex;
      this.isReversed = w.config.yaxis[this.yaxisIndex] && w.config.yaxis[this.yaxisIndex].reversed;
      const initPositions = this.barHelpers.initialPositions(realIndex);
      const {
        y: initY,
        yDivision,
        // yDivision is the GRIDHEIGHT divided by number of datapoints (bars)
        zeroW,
        // zeroW is the baseline where 0 meets x axis
        x: initX,
        xDivision,
        // xDivision is the GRIDWIDTH divided by number of datapoints (columns)
        zeroH
        // zeroH is the baseline where 0 meets y axis
      } = initPositions;
      let barHeight = initPositions.barHeight;
      let barWidth = initPositions.barWidth;
      y = initY;
      x = initX;
      if (!this.isHorizontal) {
        xArrj.push(x + (barWidth != null ? barWidth : 0) / 2);
      }
      const elDataLabelsWrap = graphics.group({
        class: "apexcharts-datalabels",
        "data:realIndex": realIndex
      });
      w.globals.delayedElements.push({
        el: elDataLabelsWrap.node
      });
      elDataLabelsWrap.node.classList.add("apexcharts-element-hidden");
      const elGoalsMarkers = graphics.group({
        class: "apexcharts-bar-goals-markers"
      });
      const elBarShadows = graphics.group({
        class: "apexcharts-bar-shadows"
      });
      w.globals.delayedElements.push({
        el: elBarShadows.node
      });
      elBarShadows.node.classList.add("apexcharts-element-hidden");
      for (let j = 0; j < series[i].length; j++) {
        const strokeWidth = this.barHelpers.getStrokeWidth(i, j, realIndex);
        let paths = (
          /** @type {any} */
          null
        );
        const pathsParams = {
          indexes: {
            i,
            j,
            realIndex,
            translationsIndex,
            bc
          },
          x,
          y,
          strokeWidth,
          elSeries
        };
        if (this.isHorizontal) {
          paths = this.drawBarPaths(__spreadProps(__spreadValues({}, pathsParams), {
            barHeight,
            zeroW,
            yDivision
          }));
          barWidth = this.series[i][j] / this.invertedYRatio;
        } else {
          paths = this.drawColumnPaths(__spreadProps(__spreadValues({}, pathsParams), {
            xDivision,
            barWidth,
            zeroH
          }));
          barHeight = this.series[i][j] / this.yRatio[translationsIndex];
        }
        const pathFill = this.barHelpers.getPathFillColor(
          series,
          i,
          j,
          realIndex
        );
        if (this.isFunnel && this.barOptions.isFunnel3d && this.pathArr.length && j > 0) {
          const barShadow = this.barHelpers.drawBarShadow({
            color: typeof pathFill.color === "string" && ((_a = pathFill.color) == null ? void 0 : _a.indexOf("url")) === -1 ? pathFill.color : Utils$1.hexToRgba(w.globals.colors[i]),
            prevPaths: this.pathArr[this.pathArr.length - 1],
            currPaths: paths,
            realIndex,
            j
          });
          elBarShadows.add(barShadow);
          if (w.config.chart.dropShadow.enabled) {
            const filters = new Filters(this.w);
            filters.dropShadow(barShadow, w.config.chart.dropShadow, realIndex);
          }
        }
        this.pathArr.push(paths);
        const barGoalLine = this.barHelpers.drawGoalLine({
          barXPosition: paths.barXPosition,
          barYPosition: paths.barYPosition,
          goalX: paths.goalX,
          goalY: paths.goalY,
          barHeight,
          barWidth
        });
        if (barGoalLine) {
          elGoalsMarkers.add(barGoalLine);
        }
        y = paths.y;
        x = paths.x;
        if (j > 0) {
          xArrj.push(x + (barWidth != null ? barWidth : 0) / 2);
        }
        yArrj.push(y);
        this.renderSeries(__spreadProps(__spreadValues({
          realIndex,
          pathFill: pathFill.color
        }, pathFill.useRangeColor ? { lineFill: pathFill.color } : {}), {
          j,
          i,
          columnGroupIndex,
          pathFrom: paths.pathFrom,
          pathTo: paths.pathTo,
          strokeWidth,
          elSeries,
          x,
          y,
          series,
          barHeight: Math.abs(paths.barHeight ? paths.barHeight : barHeight),
          barWidth: Math.abs(paths.barWidth ? paths.barWidth : barWidth),
          elDataLabelsWrap,
          elGoalsMarkers,
          elBarShadows,
          visibleSeries: this.visibleI,
          type: "bar"
        }));
      }
      w.globals.seriesXvalues[realIndex] = xArrj;
      w.globals.seriesYvalues[realIndex] = yArrj;
      ret.add(elSeries);
    }
    return ret;
  }
  /** @param {{ realIndex?: any, pathFill?: any, lineFill?: any, j?: any, i?: any, columnGroupIndex?: any, pathFrom?: any, pathTo?: any, strokeWidth?: any, elSeries?: any, x?: any, y?: any, y1?: any, y2?: any, series?: any, barHeight?: any, barWidth?: any, barXPosition?: any, barYPosition?: any, elDataLabelsWrap?: any, elGoalsMarkers?: any, elBarShadows?: any, visibleSeries?: any, type?: any, classes?: any }} opts */
  renderSeries({
    realIndex,
    pathFill,
    lineFill,
    j,
    i,
    columnGroupIndex,
    pathFrom,
    pathTo,
    strokeWidth,
    elSeries,
    x,
    // x pos
    y,
    // y pos
    y1,
    // absolute value
    y2,
    // absolute value
    series,
    barHeight,
    barWidth,
    barXPosition,
    barYPosition,
    elDataLabelsWrap,
    elGoalsMarkers,
    elBarShadows,
    visibleSeries,
    type,
    classes
  }) {
    const w = this.w;
    const graphics = new Graphics(this.w, this.ctx);
    let skipDrawing = false;
    if (!elSeries._bindingsDelegated) {
      elSeries._bindingsDelegated = true;
      graphics.setupEventDelegation(elSeries, `.apexcharts-${type}-area`);
    }
    if (!lineFill) {
      let fetchColor = function(i2) {
        const exp = w.config.stroke.colors;
        let c;
        if (Array.isArray(exp) && exp.length > 0) {
          c = exp[i2];
          if (!c) c = "";
          if (typeof c === "function") {
            return c({
              value: w.seriesData.series[i2][j],
              dataPointIndex: j,
              w
            });
          }
        }
        return c;
      };
      const checkAvailableColor = typeof w.globals.stroke.colors[realIndex] === "function" ? fetchColor(realIndex) : w.globals.stroke.colors[realIndex];
      lineFill = this.barOptions.distributed ? w.globals.stroke.colors[j] : checkAvailableColor;
    }
    const barDataLabels = new BarDataLabels(this);
    const dataLabelsObj = (
      /** @type {any} */
      barDataLabels.handleBarDataLabels({
        x,
        y,
        y1,
        y2,
        i,
        j,
        series,
        realIndex,
        columnGroupIndex,
        barHeight,
        barWidth,
        barXPosition,
        barYPosition,
        visibleSeries
      })
    );
    if (!w.globals.isBarHorizontal) {
      if (dataLabelsObj.dataLabelsPos.dataLabelsX + Math.max(barWidth, w.globals.barPadForNumericAxis) < 0 || dataLabelsObj.dataLabelsPos.dataLabelsX - Math.max(barWidth, w.globals.barPadForNumericAxis) > w.layout.gridWidth) {
        skipDrawing = true;
      }
    }
    if (
      /** @type {Record<string,any>} */
      w.config.series[i].data[j] && /** @type {Record<string,any>} */
      w.config.series[i].data[j].strokeColor
    ) {
      lineFill = /** @type {Record<string,any>} */
      w.config.series[i].data[j].strokeColor;
    }
    if (this.isNullValue) {
      pathFill = "none";
    }
    const delay = j / w.config.chart.animations.animateGradually.delay * (w.config.chart.animations.speed / w.globals.dataPoints) / 2.4;
    if (!skipDrawing) {
      const renderedPath = (
        /** @type {any} */
        graphics.renderPaths({
          i,
          j,
          realIndex,
          pathFrom,
          pathTo,
          stroke: lineFill,
          strokeWidth,
          strokeLineCap: w.config.stroke.lineCap,
          fill: pathFill,
          animationDelay: delay,
          initialSpeed: w.config.chart.animations.speed,
          dataChangeSpeed: w.config.chart.animations.dynamicAnimation.speed,
          className: `apexcharts-${type}-area ${classes}`,
          chartType: type,
          bindEventsOnPaths: false
        })
      );
      renderedPath.attr("clip-path", `url(#gridRectBarMask${w.globals.cuid})`);
      const forecast = w.config.forecastDataPoints;
      if (forecast.count > 0) {
        if (j >= w.globals.dataPoints - forecast.count) {
          renderedPath.node.setAttribute("stroke-dasharray", forecast.dashArray);
          renderedPath.node.setAttribute("stroke-width", forecast.strokeWidth);
          renderedPath.node.setAttribute("fill-opacity", forecast.fillOpacity);
        }
      }
      if (typeof y1 !== "undefined" && typeof y2 !== "undefined") {
        renderedPath.attr("data-range-y1", y1);
        renderedPath.attr("data-range-y2", y2);
      }
      const filters = new Filters(this.w);
      filters.setSelectionFilter(renderedPath, realIndex, j);
      elSeries.add(renderedPath);
      renderedPath.attr({
        cy: dataLabelsObj.dataLabelsPos.bcy,
        cx: dataLabelsObj.dataLabelsPos.bcx,
        j,
        val: w.seriesData.series[i][j],
        barHeight,
        barWidth
      });
      if (dataLabelsObj.dataLabels !== null) {
        elDataLabelsWrap.add(dataLabelsObj.dataLabels);
      }
      if (dataLabelsObj.totalDataLabels) {
        elDataLabelsWrap.add(dataLabelsObj.totalDataLabels);
      }
      elSeries.add(elDataLabelsWrap);
      if (elGoalsMarkers) {
        elSeries.add(elGoalsMarkers);
      }
      if (elBarShadows) {
        elSeries.add(elBarShadows);
      }
    }
    return elSeries;
  }
  /** @param {{indexes: any, barHeight: any, strokeWidth: any, zeroW: any, x: any, y: any, yDivision: any, elSeries: any}} opts */
  drawBarPaths({
    indexes,
    barHeight,
    strokeWidth,
    zeroW,
    x,
    y,
    yDivision,
    elSeries
  }) {
    const w = this.w;
    const i = indexes.i;
    const j = indexes.j;
    let barYPosition;
    if (w.axisFlags.isXNumeric) {
      y = (w.seriesData.seriesX[i][j] - w.globals.minX) / this.invertedXRatio - barHeight;
      barYPosition = y + barHeight * this.visibleI;
    } else {
      if (w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
        const { nonZeroColumns, zeroEncounters } = this.barHelpers.getZeroValueEncounters({ i, j });
        if (nonZeroColumns > 0) {
          barHeight = this.seriesLen * barHeight / nonZeroColumns;
        }
        barYPosition = y + barHeight * this.visibleI;
        barYPosition -= barHeight * zeroEncounters;
      } else {
        barYPosition = y + barHeight * this.visibleI;
      }
    }
    if (this.isFunnel) {
      const _zeroW = zeroW != null ? zeroW : 0;
      zeroW = _zeroW - /** @type {number} */
      /** @type {any} */
      (this.barHelpers.getXForValue(
        /** @type {any} */
        this.series[i][j],
        _zeroW
      ) - _zeroW) / 2;
    }
    x = this.barHelpers.getXForValue(
      /** @type {any} */
      this.series[i][j],
      zeroW != null ? zeroW : 0
    );
    const paths = (
      /** @type {any} */
      this.barHelpers.getBarpaths({
        barYPosition,
        barHeight,
        x1: zeroW,
        x2: x,
        strokeWidth,
        isReversed: this.isReversed,
        series: this.series,
        realIndex: indexes.realIndex,
        i,
        j,
        w
      })
    );
    if (!w.axisFlags.isXNumeric) {
      y = y + yDivision;
    }
    this.barHelpers.barBackground({
      j,
      i,
      y1: barYPosition - barHeight * this.visibleI,
      y2: barHeight * this.seriesLen,
      elSeries
    });
    return {
      pathTo: paths.pathTo,
      pathFrom: paths.pathFrom,
      x1: zeroW,
      x,
      y,
      goalX: this.barHelpers.getGoalValues(
        "x",
        zeroW,
        /** @type {any} */
        null,
        i,
        j,
        0
      ),
      barYPosition,
      barHeight
    };
  }
  /** @param {{indexes: any, x: any, y: any, xDivision: any, barWidth: any, zeroH: any, strokeWidth: any, elSeries: any}} opts */
  drawColumnPaths({
    indexes,
    x,
    y,
    xDivision,
    barWidth,
    zeroH,
    strokeWidth,
    elSeries
  }) {
    const w = this.w;
    const realIndex = indexes.realIndex;
    const translationsIndex = indexes.translationsIndex;
    const i = indexes.i;
    const j = indexes.j;
    const bc = indexes.bc;
    let barXPosition;
    if (w.axisFlags.isXNumeric) {
      const xForNumericX = this.getBarXForNumericXAxis({
        x,
        j,
        realIndex,
        barWidth
      });
      x = xForNumericX.x;
      barXPosition = xForNumericX.barXPosition;
    } else {
      if (w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
        const { nonZeroColumns, zeroEncounters } = this.barHelpers.getZeroValueEncounters({ i, j });
        if (nonZeroColumns > 0) {
          barWidth = this.seriesLen * barWidth / nonZeroColumns;
        }
        barXPosition = x + barWidth * this.visibleI;
        barXPosition -= barWidth * zeroEncounters;
      } else {
        barXPosition = x + barWidth * this.visibleI;
      }
    }
    y = this.barHelpers.getYForValue(
      /** @type {any} */
      this.series[i][j],
      zeroH,
      translationsIndex
    );
    const paths = (
      /** @type {any} */
      this.barHelpers.getColumnPaths({
        barXPosition,
        barWidth,
        y1: zeroH,
        y2: y,
        strokeWidth,
        isReversed: this.isReversed,
        series: this.series,
        realIndex,
        i,
        j,
        w
      })
    );
    if (!w.axisFlags.isXNumeric) {
      x = x + xDivision;
    }
    this.barHelpers.barBackground({
      bc,
      j,
      i,
      x1: barXPosition - strokeWidth / 2 - barWidth * this.visibleI,
      x2: barWidth * this.seriesLen + strokeWidth / 2,
      elSeries
    });
    return {
      pathTo: paths.pathTo,
      pathFrom: paths.pathFrom,
      x,
      y,
      goalY: this.barHelpers.getGoalValues(
        "y",
        /** @type {any} */
        null,
        zeroH,
        i,
        j,
        translationsIndex
      ),
      barXPosition,
      barWidth
    };
  }
  /** @param {{x: any, barWidth: any, realIndex: any, j: any}} opts */
  getBarXForNumericXAxis({ x, barWidth, realIndex, j }) {
    const w = this.w;
    let sxI = realIndex;
    if (!w.seriesData.seriesX[realIndex].length) {
      sxI = w.globals.maxValsInArrayIndex;
    }
    if (Utils$1.isNumber(w.seriesData.seriesX[sxI][j])) {
      x = (w.seriesData.seriesX[sxI][j] - w.globals.minX) / this.xRatio - barWidth * this.seriesLen / 2;
    }
    return {
      barXPosition: x + barWidth * this.visibleI,
      x
    };
  }
  /** getPreviousPath is a common function for bars/columns which is used to get previous paths when data changes.
   * @memberof Bar
   * @param {number} realIndex - current iterating i
   * @param {number} j - current iterating series's j index
   * @return {string} pathFrom is the string which will be appended in animations
   **/
  getPreviousPath(realIndex, j) {
    const w = this.w;
    let pathFrom = "M 0 0";
    for (let pp = 0; pp < w.globals.previousPaths.length; pp++) {
      const gpp = w.globals.previousPaths[pp];
      if (gpp.paths && gpp.paths.length > 0 && parseInt(gpp.realIndex, 10) === parseInt(String(realIndex), 10)) {
        if (typeof w.globals.previousPaths[pp].paths[j] !== "undefined") {
          pathFrom = w.globals.previousPaths[pp].paths[j].d;
        }
      }
    }
    return pathFrom;
  }
}
class BarStacked extends Bar {
  /**
   * @param {any[]} series
   * @param {number} seriesIndex
   */
  draw(series, seriesIndex) {
    const w = this.w;
    this.graphics = new Graphics(this.w);
    this.bar = new Bar(this.w, this.ctx, this.xyRatios);
    const coreUtils = new CoreUtils(this.w);
    series = coreUtils.getLogSeries(series);
    this.yRatio = coreUtils.getLogYRatios(this.yRatio);
    this.barHelpers.initVariables(series);
    if (w.config.chart.stackType === "100%") {
      series = w.globals.comboCharts ? (
        /** @type {any} */
        seriesIndex.map(
          (_) => w.globals.seriesPercent[_]
        )
      ) : w.globals.seriesPercent.slice();
    }
    this.series = series;
    this.barHelpers.initializeStackedPrevVars(this);
    const ret = this.graphics.group({
      class: "apexcharts-bar-series apexcharts-plot-series"
    });
    let x = 0;
    let y = 0;
    for (let i = 0, bc = 0; i < series.length; i++, bc++) {
      const realIndex = w.globals.comboCharts ? (
        /** @type {any} */
        seriesIndex[i]
      ) : i;
      const { groupIndex, columnGroupIndex } = this.barHelpers.getGroupIndex(realIndex);
      this.groupCtx = /** @type {any} */
      this[
        /** @type {any} */
        w.labelData.seriesGroups[groupIndex]
      ];
      const xArrValues = [];
      const yArrValues = [];
      let translationsIndex = 0;
      if (this.yRatio.length > 1) {
        this.yaxisIndex = /** @type {any} */
        w.globals.seriesYAxisReverseMap[realIndex][0];
        translationsIndex = realIndex;
      }
      this.isReversed = w.config.yaxis[this.yaxisIndex] && w.config.yaxis[this.yaxisIndex].reversed;
      let elSeries = this.graphics.group({
        class: `apexcharts-series`,
        seriesName: Utils$1.escapeString(w.seriesData.seriesNames[realIndex]),
        rel: i + 1,
        "data:realIndex": realIndex
      });
      Series.addCollapsedClassToSeries(this.w, elSeries, realIndex);
      const elDataLabelsWrap = this.graphics.group({
        class: "apexcharts-datalabels",
        "data:realIndex": realIndex
      });
      const elGoalsMarkers = this.graphics.group({
        class: "apexcharts-bar-goals-markers"
      });
      const initPositions = this.initialPositions(
        x,
        y,
        void 0,
        void 0,
        void 0,
        void 0,
        translationsIndex
      );
      const {
        xDivision,
        // xDivision is the GRIDWIDTH divided by number of datapoints (columns)
        yDivision,
        // yDivision is the GRIDHEIGHT divided by number of datapoints (bars)
        zeroH,
        // zeroH is the baseline where 0 meets y axis
        zeroW
        // zeroW is the baseline where 0 meets x axis
      } = initPositions;
      let barHeight = initPositions.barHeight;
      let barWidth = initPositions.barWidth;
      y = initPositions.y;
      x = initPositions.x;
      w.globals.barHeight = barHeight;
      w.globals.barWidth = barWidth;
      this.barHelpers.initializeStackedXYVars(this);
      if (this.groupCtx.prevY.length === 1 && /**
       * @param {number} val
       */
      this.groupCtx.prevY[0].every((val) => isNaN(val))) {
        this.groupCtx.prevY[0] = this.groupCtx.prevY[0].map(() => zeroH);
        this.groupCtx.prevYF[0] = this.groupCtx.prevYF[0].map(() => 0);
      }
      for (let j = 0; j < w.globals.dataPoints; j++) {
        const strokeWidth = this.barHelpers.getStrokeWidth(i, j, realIndex);
        const commonPathOpts = {
          indexes: { i, j, realIndex, translationsIndex, bc },
          strokeWidth,
          x,
          y,
          elSeries,
          columnGroupIndex,
          seriesGroup: w.labelData.seriesGroups[groupIndex]
        };
        let paths = (
          /** @type {any} */
          null
        );
        if (this.isHorizontal) {
          paths = this.drawStackedBarPaths(__spreadProps(__spreadValues({}, commonPathOpts), {
            zeroW,
            barHeight,
            yDivision
          }));
          barWidth = this.series[i][j] / this.invertedYRatio;
        } else {
          paths = this.drawStackedColumnPaths(__spreadProps(__spreadValues({}, commonPathOpts), {
            xDivision,
            barWidth,
            zeroH
          }));
          barHeight = this.series[i][j] / this.yRatio[translationsIndex];
        }
        const barGoalLine = this.barHelpers.drawGoalLine({
          barXPosition: paths.barXPosition,
          barYPosition: paths.barYPosition,
          goalX: paths.goalX,
          goalY: paths.goalY,
          barHeight,
          barWidth
        });
        if (barGoalLine) {
          elGoalsMarkers.add(barGoalLine);
        }
        y = paths.y;
        x = paths.x;
        xArrValues.push(x);
        yArrValues.push(y);
        const pathFill = this.barHelpers.getPathFillColor(
          series,
          i,
          j,
          realIndex
        );
        let classes = "";
        const flipClass = w.globals.isBarHorizontal ? "apexcharts-flip-x" : "apexcharts-flip-y";
        if (this.barHelpers.arrBorderRadius[realIndex][j] === "bottom" && w.seriesData.series[realIndex][j] > 0 || this.barHelpers.arrBorderRadius[realIndex][j] === "top" && w.seriesData.series[realIndex][j] < 0) {
          classes = flipClass;
        }
        elSeries = this.renderSeries(__spreadProps(__spreadValues({
          realIndex,
          pathFill: pathFill.color
        }, pathFill.useRangeColor ? { lineFill: pathFill.color } : {}), {
          j,
          i,
          columnGroupIndex,
          pathFrom: paths.pathFrom,
          pathTo: paths.pathTo,
          strokeWidth,
          elSeries,
          x,
          y,
          series,
          barHeight,
          barWidth,
          elDataLabelsWrap,
          elGoalsMarkers,
          type: "bar",
          visibleSeries: columnGroupIndex,
          classes
        }));
      }
      w.globals.seriesXvalues[realIndex] = xArrValues;
      w.globals.seriesYvalues[realIndex] = yArrValues;
      this.groupCtx.prevY.push(this.groupCtx.yArrj);
      this.groupCtx.prevYF.push(this.groupCtx.yArrjF);
      this.groupCtx.prevYVal.push(this.groupCtx.yArrjVal);
      this.groupCtx.prevX.push(this.groupCtx.xArrj);
      this.groupCtx.prevXF.push(this.groupCtx.xArrjF);
      this.groupCtx.prevXVal.push(this.groupCtx.xArrjVal);
      ret.add(elSeries);
    }
    return ret;
  }
  /**
   * @param {number} x
   * @param {number} y
   * @param {number | undefined} xDivision
   * @param {number | undefined} yDivision
   * @param {number | undefined} zeroH
   * @param {number | undefined} zeroW
   * @param {number} translationsIndex
   */
  initialPositions(x, y, xDivision, yDivision, zeroH, zeroW, translationsIndex) {
    const w = this.w;
    let barHeight, barWidth;
    if (this.isHorizontal) {
      yDivision = w.layout.gridHeight / w.globals.dataPoints;
      const userBarHeight = w.config.plotOptions.bar.barHeight;
      if (String(userBarHeight).indexOf("%") === -1) {
        barHeight = parseInt(userBarHeight, 10);
      } else {
        barHeight = yDivision * parseInt(userBarHeight, 10) / 100;
      }
      zeroW = w.globals.padHorizontal + (this.isReversed ? w.layout.gridWidth - this.baseLineInvertedY : this.baseLineInvertedY);
      y = (yDivision - barHeight) / 2;
    } else {
      xDivision = w.layout.gridWidth / w.globals.dataPoints;
      barWidth = xDivision;
      const userColumnWidth = w.config.plotOptions.bar.columnWidth;
      if (w.axisFlags.isXNumeric && w.globals.dataPoints > 1) {
        xDivision = w.globals.minXDiff / this.xRatio;
        barWidth = xDivision * parseInt(this.barOptions.columnWidth, 10) / 100;
      } else if (String(userColumnWidth).indexOf("%") === -1) {
        barWidth = parseInt(userColumnWidth, 10);
      } else {
        barWidth *= parseInt(userColumnWidth, 10) / 100;
      }
      if (this.isReversed) {
        zeroH = this.baseLineY[translationsIndex];
      } else {
        zeroH = w.layout.gridHeight - this.baseLineY[translationsIndex];
      }
      x = w.globals.padHorizontal + (xDivision - barWidth) / 2;
    }
    const subDivisions = w.globals.barGroups.length || 1;
    return {
      x,
      y,
      yDivision,
      xDivision,
      barHeight: (barHeight != null ? barHeight : 0) / subDivisions,
      barWidth: (barWidth != null ? barWidth : 0) / subDivisions,
      zeroH,
      zeroW
    };
  }
  /** @param {{indexes: any, barHeight: any, strokeWidth: any, zeroW: any, x: any, y: any, columnGroupIndex: any, seriesGroup: any, yDivision: any, elSeries: any}} opts */
  drawStackedBarPaths({
    indexes,
    barHeight,
    strokeWidth,
    zeroW,
    x,
    y,
    columnGroupIndex,
    seriesGroup,
    yDivision,
    elSeries
  }) {
    var _a, _b, _c, _d, _e;
    const w = this.w;
    const barYPosition = y + columnGroupIndex * barHeight;
    let barXPosition;
    const i = indexes.i;
    const j = indexes.j;
    const realIndex = indexes.realIndex;
    const translationsIndex = indexes.translationsIndex;
    let prevBarW = 0;
    for (let k = 0; k < this.groupCtx.prevXF.length; k++) {
      prevBarW = prevBarW + this.groupCtx.prevXF[k][j];
    }
    let gsi = i;
    if (
      /** @type {Record<string,any>} */
      w.config.series[realIndex].name
    ) {
      gsi = seriesGroup.indexOf(
        /** @type {Record<string,any>} */
        w.config.series[realIndex].name
      );
    }
    if (gsi > 0) {
      let bXP = zeroW;
      if (this.groupCtx.prevXVal[gsi - 1][j] < 0) {
        bXP = /** @type {any} */
        ((_a = this.series[i]) == null ? void 0 : _a[j]) >= 0 ? this.groupCtx.prevX[gsi - 1][j] + prevBarW - (this.isReversed ? prevBarW : 0) * 2 : this.groupCtx.prevX[gsi - 1][j];
      } else if (this.groupCtx.prevXVal[gsi - 1][j] >= 0) {
        bXP = /** @type {any} */
        ((_b = this.series[i]) == null ? void 0 : _b[j]) >= 0 ? this.groupCtx.prevX[gsi - 1][j] : this.groupCtx.prevX[gsi - 1][j] - prevBarW + (this.isReversed ? prevBarW : 0) * 2;
      }
      barXPosition = bXP;
    } else {
      barXPosition = zeroW;
    }
    if (
      /** @type {any} */
      ((_c = this.series[i]) == null ? void 0 : _c[j]) === null
    ) {
      x = barXPosition;
    } else {
      x = barXPosition + /** @type {any} */
      ((_d = this.series[i]) == null ? void 0 : _d[j]) / this.invertedYRatio - (this.isReversed ? (
        /** @type {any} */
        ((_e = this.series[i]) == null ? void 0 : _e[j]) / this.invertedYRatio
      ) : 0) * 2;
    }
    const paths = this.barHelpers.getBarpaths({
      barYPosition,
      barHeight,
      x1: barXPosition,
      x2: x,
      strokeWidth,
      isReversed: this.isReversed,
      series: this.series,
      realIndex: indexes.realIndex,
      seriesGroup,
      i,
      j,
      w
    });
    this.barHelpers.barBackground({
      j,
      i,
      y1: barYPosition,
      y2: barHeight,
      elSeries
    });
    y = y + yDivision;
    return {
      pathTo: paths.pathTo,
      pathFrom: paths.pathFrom,
      goalX: this.barHelpers.getGoalValues(
        "x",
        zeroW,
        /** @type {any} */
        null,
        i,
        j,
        translationsIndex
      ),
      barXPosition,
      barYPosition,
      x,
      y
    };
  }
  /** @param {{indexes: any, x: any, y: any, xDivision: any, barWidth: any, zeroH: any, columnGroupIndex: any, seriesGroup: any, elSeries: any}} opts */
  drawStackedColumnPaths({
    indexes,
    x,
    y,
    xDivision,
    barWidth,
    zeroH,
    columnGroupIndex,
    seriesGroup,
    elSeries
  }) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i;
    const w = this.w;
    const i = indexes.i;
    const j = indexes.j;
    const bc = indexes.bc;
    const realIndex = indexes.realIndex;
    const translationsIndex = indexes.translationsIndex;
    if (w.axisFlags.isXNumeric) {
      let seriesVal = w.seriesData.seriesX[realIndex][j];
      if (!seriesVal) seriesVal = 0;
      x = (seriesVal - w.globals.minX) / this.xRatio - barWidth / 2 * w.globals.barGroups.length;
    }
    const barXPosition = x + columnGroupIndex * barWidth;
    let barYPosition;
    let prevBarH = 0;
    for (let k = 0; k < this.groupCtx.prevYF.length; k++) {
      prevBarH = prevBarH + (!isNaN(this.groupCtx.prevYF[k][j]) ? this.groupCtx.prevYF[k][j] : 0);
    }
    let gsi = i;
    if (seriesGroup) {
      gsi = seriesGroup.indexOf(w.seriesData.seriesNames[realIndex]);
    }
    if (gsi > 0 && !w.axisFlags.isXNumeric || gsi > 0 && w.axisFlags.isXNumeric && w.seriesData.seriesX[realIndex - 1][j] === w.seriesData.seriesX[realIndex][j]) {
      let bYP;
      let prevYValue;
      const p = Math.min(this.yRatio.length + 1, realIndex + 1);
      if (this.groupCtx.prevY[gsi - 1] !== void 0 && this.groupCtx.prevY[gsi - 1].length) {
        for (let ii = 1; ii < p; ii++) {
          if (!isNaN((_a = this.groupCtx.prevY[gsi - ii]) == null ? void 0 : _a[j])) {
            prevYValue = this.groupCtx.prevY[gsi - ii][j];
            break;
          }
        }
      }
      for (let ii = 1; ii < p; ii++) {
        if (((_b = this.groupCtx.prevYVal[gsi - ii]) == null ? void 0 : _b[j]) < 0) {
          bYP = /** @type {any} */
          ((_c = this.series[i]) == null ? void 0 : _c[j]) >= 0 ? prevYValue - prevBarH + (this.isReversed ? prevBarH : 0) * 2 : prevYValue;
          break;
        } else if (((_d = this.groupCtx.prevYVal[gsi - ii]) == null ? void 0 : _d[j]) >= 0) {
          bYP = /** @type {any} */
          ((_e = this.series[i]) == null ? void 0 : _e[j]) >= 0 ? prevYValue : prevYValue + prevBarH - (this.isReversed ? prevBarH : 0) * 2;
          break;
        }
      }
      if (typeof bYP === "undefined") bYP = w.layout.gridHeight;
      if (
        /**
         * @param {number} val
         */
        ((_f = this.groupCtx.prevYF[0]) == null ? void 0 : _f.every((val) => val === 0)) && this.groupCtx.prevYF.slice(1, gsi).every(
          (arr) => arr.every((val) => isNaN(val))
        )
      ) {
        barYPosition = zeroH;
      } else {
        barYPosition = bYP;
      }
    } else {
      barYPosition = zeroH;
    }
    if (
      /** @type {any} */
      (_g = this.series[i]) == null ? void 0 : _g[j]
    ) {
      y = barYPosition - /** @type {any} */
      ((_h = this.series[i]) == null ? void 0 : _h[j]) / this.yRatio[translationsIndex] + (this.isReversed ? (
        /** @type {any} */
        ((_i = this.series[i]) == null ? void 0 : _i[j]) / this.yRatio[translationsIndex]
      ) : 0) * 2;
    } else {
      y = barYPosition;
    }
    const paths = this.barHelpers.getColumnPaths({
      barXPosition,
      barWidth,
      y1: barYPosition,
      y2: y,
      yRatio: this.yRatio[translationsIndex],
      strokeWidth: this.strokeWidth,
      isReversed: this.isReversed,
      series: this.series,
      seriesGroup,
      realIndex: indexes.realIndex,
      i,
      j,
      w
    });
    this.barHelpers.barBackground({
      bc,
      j,
      i,
      x1: barXPosition,
      x2: barWidth,
      elSeries
    });
    return {
      pathTo: paths.pathTo,
      pathFrom: paths.pathFrom,
      goalY: this.barHelpers.getGoalValues(
        "y",
        /** @type {any} */
        null,
        zeroH,
        i,
        j,
        0
      ),
      barXPosition,
      x: w.axisFlags.isXNumeric ? x : x + xDivision,
      y
    };
  }
}
class BoxCandleStick extends Bar {
  /**
   * @param {any[]} series
   * @param {string} ctype
   * @param {number} seriesIndex
   */
  // @ts-ignore -- BoxCandleStick.draw has an extra ctype param compared to Bar.draw
  draw(series, ctype, seriesIndex) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const type = w.globals.comboCharts ? ctype : w.config.chart.type;
    const fill = new Fill(this.w);
    this.candlestickOptions = this.w.config.plotOptions.candlestick;
    this.boxOptions = this.w.config.plotOptions.boxPlot;
    this.isHorizontal = w.config.plotOptions.bar.horizontal;
    this.isOHLC = this.candlestickOptions && this.candlestickOptions.type === "ohlc";
    this.coreUtils = new CoreUtils(this.w);
    series = this.coreUtils.getLogSeries(series);
    this.series = series;
    this.yRatio = this.coreUtils.getLogYRatios(this.yRatio);
    this.barHelpers.initVariables(series);
    const ret = graphics.group({
      class: `apexcharts-${type}-series apexcharts-plot-series`
    });
    for (let i = 0; i < series.length; i++) {
      this.isBoxPlot = w.config.chart.type === "boxPlot" || /** @type {Record<string,any>} */
      w.config.series[i].type === "boxPlot";
      let x;
      let y;
      const yArrj = [];
      const xArrj = [];
      const realIndex = w.globals.comboCharts ? (
        /** @type {any} */
        seriesIndex[i]
      ) : i;
      const { columnGroupIndex } = this.barHelpers.getGroupIndex(realIndex);
      const elSeries = graphics.group({
        class: `apexcharts-series`,
        seriesName: Utils$1.escapeString(w.seriesData.seriesNames[realIndex]),
        rel: i + 1,
        "data:realIndex": realIndex
      });
      Series.addCollapsedClassToSeries(this.w, elSeries, realIndex);
      if (series[i].length > 0) {
        this.visibleI = this.visibleI + 1;
      }
      let translationsIndex = 0;
      if (this.yRatio.length > 1) {
        this.yaxisIndex = /** @type {any} */
        w.globals.seriesYAxisReverseMap[realIndex][0];
        translationsIndex = realIndex;
      }
      const initPositions = this.barHelpers.initialPositions(realIndex);
      const {
        y: initY,
        barHeight,
        yDivision,
        // yDivision is the GRIDHEIGHT divided by number of datapoints (bars)
        zeroW,
        // zeroW is the baseline where 0 meets x axis
        x: initX,
        barWidth,
        xDivision,
        // xDivision is the GRIDWIDTH divided by number of datapoints (columns)
        zeroH
        // zeroH is the baseline where 0 meets y axis
      } = initPositions;
      y = initY;
      x = initX;
      xArrj.push(x + (barWidth != null ? barWidth : 0) / 2);
      const elDataLabelsWrap = graphics.group({
        class: "apexcharts-datalabels",
        "data:realIndex": realIndex
      });
      const elGoalsMarkers = graphics.group({
        class: "apexcharts-bar-goals-markers"
      });
      for (let j = 0; j < w.globals.dataPoints; j++) {
        const strokeWidth = this.barHelpers.getStrokeWidth(i, j, realIndex);
        let paths = (
          /** @type {any} */
          null
        );
        const pathsParams = {
          indexes: {
            i,
            j,
            realIndex,
            translationsIndex
          },
          x,
          y,
          strokeWidth,
          elSeries
        };
        if (this.isHorizontal) {
          paths = this.drawHorizontalBoxPaths(__spreadProps(__spreadValues({}, pathsParams), {
            yDivision,
            barHeight,
            zeroW
          }));
        } else {
          paths = this.drawVerticalBoxPaths(__spreadProps(__spreadValues({}, pathsParams), {
            xDivision,
            barWidth,
            zeroH
          }));
        }
        y = paths.y;
        x = paths.x;
        const barGoalLine = this.barHelpers.drawGoalLine({
          barXPosition: paths.barXPosition,
          barYPosition: paths.barYPosition,
          goalX: paths.goalX,
          goalY: paths.goalY,
          barHeight,
          barWidth
        });
        if (barGoalLine) {
          elGoalsMarkers.add(barGoalLine);
        }
        if (j > 0) {
          xArrj.push(x + (barWidth != null ? barWidth : 0) / 2);
        }
        yArrj.push(y);
        paths.pathTo.forEach(
          (pathTo, pi) => {
            const lineFill = !this.isBoxPlot && this.candlestickOptions.wick.useFillColor ? paths.color[pi] : w.globals.stroke.colors[i];
            const pathFill = fill.fillPath({
              seriesNumber: realIndex,
              dataPointIndex: j,
              color: paths.color[pi],
              value: series[i][j]
            });
            this.renderSeries({
              realIndex,
              pathFill,
              lineFill,
              j,
              i,
              pathFrom: paths.pathFrom,
              pathTo,
              strokeWidth,
              elSeries,
              x,
              y,
              series,
              columnGroupIndex,
              barHeight,
              barWidth,
              elDataLabelsWrap,
              elGoalsMarkers,
              visibleSeries: this.visibleI,
              type: w.config.chart.type
            });
          }
        );
      }
      w.globals.seriesXvalues[realIndex] = xArrj;
      w.globals.seriesYvalues[realIndex] = yArrj;
      ret.add(elSeries);
    }
    return ret;
  }
  /** @param {{indexes: any, x: any, xDivision: any, barWidth: any, zeroH: any, strokeWidth: any}} opts */
  drawVerticalBoxPaths({
    indexes,
    x,
    xDivision,
    barWidth,
    zeroH,
    strokeWidth
  }) {
    var _a, _b;
    const w = this.w;
    const graphics = new Graphics(this.w);
    const i = indexes.i;
    const j = indexes.j;
    const { colors: candleColors } = w.config.plotOptions.candlestick;
    const { colors: boxColors } = this.boxOptions;
    const realIndex = indexes.realIndex;
    const getColor = (color2) => Array.isArray(color2) ? color2[realIndex] : color2;
    const colorPos = getColor(candleColors.upward);
    const colorNeg = getColor(candleColors.downward);
    const yRatio = this.yRatio[indexes.translationsIndex];
    const ohlc = this.getOHLCValue(realIndex, j);
    let l1 = zeroH;
    let l2 = zeroH;
    let color = ohlc.o < ohlc.c ? [colorPos] : [colorNeg];
    if (this.isBoxPlot) {
      color = [getColor(boxColors.lower), getColor(boxColors.upper)];
    }
    let y1 = Math.min(ohlc.o, ohlc.c);
    let y2 = Math.max(ohlc.o, ohlc.c);
    let m = ohlc.m;
    if (w.axisFlags.isXNumeric) {
      x = (w.seriesData.seriesX[realIndex][j] - w.globals.minX) / this.xRatio - barWidth / 2;
    }
    const barXPosition = x + barWidth * this.visibleI;
    if (typeof /** @type {any} */
    ((_a = this.series[i]) == null ? void 0 : _a[j]) === "undefined" || /** @type {any} */
    ((_b = this.series[i]) == null ? void 0 : _b[j]) === null) {
      y1 = zeroH;
      y2 = zeroH;
    } else {
      y1 = zeroH - y1 / yRatio;
      y2 = zeroH - y2 / yRatio;
      l1 = zeroH - ohlc.h / yRatio;
      l2 = zeroH - ohlc.l / yRatio;
      m = zeroH - ohlc.m / yRatio;
    }
    let pathTo;
    let pathFrom = graphics.move(barXPosition + barWidth / 2, y1);
    if (w.globals.previousPaths.length > 0) {
      pathFrom = this.getPreviousPath(realIndex, j);
    }
    if (this.isOHLC) {
      const centerX = barXPosition + barWidth / 2;
      const openY = zeroH - ohlc.o / yRatio;
      const closeY = zeroH - ohlc.c / yRatio;
      pathTo = [
        graphics.move(centerX, l1) + graphics.line(centerX, l2) + graphics.move(centerX, openY) + graphics.line(barXPosition, openY) + graphics.move(centerX, closeY) + graphics.line(barXPosition + barWidth, closeY)
      ];
    } else if (this.isBoxPlot) {
      pathTo = [
        graphics.move(barXPosition, y1) + graphics.line(barXPosition + barWidth / 2, y1) + graphics.line(barXPosition + barWidth / 2, l1) + graphics.line(barXPosition + barWidth / 4, l1) + graphics.line(barXPosition + barWidth - barWidth / 4, l1) + graphics.line(barXPosition + barWidth / 2, l1) + graphics.line(barXPosition + barWidth / 2, y1) + graphics.line(barXPosition + barWidth, y1) + graphics.line(barXPosition + barWidth, m) + graphics.line(barXPosition, m) + graphics.line(barXPosition, y1 + strokeWidth / 2),
        graphics.move(barXPosition, m) + graphics.line(barXPosition + barWidth, m) + graphics.line(barXPosition + barWidth, y2) + graphics.line(barXPosition + barWidth / 2, y2) + graphics.line(barXPosition + barWidth / 2, l2) + graphics.line(barXPosition + barWidth - barWidth / 4, l2) + graphics.line(barXPosition + barWidth / 4, l2) + graphics.line(barXPosition + barWidth / 2, l2) + graphics.line(barXPosition + barWidth / 2, y2) + graphics.line(barXPosition, y2) + graphics.line(barXPosition, m) + "z"
      ];
    } else {
      pathTo = [
        graphics.move(barXPosition, y2) + graphics.line(barXPosition + barWidth / 2, y2) + graphics.line(barXPosition + barWidth / 2, l1) + graphics.line(barXPosition + barWidth / 2, y2) + graphics.line(barXPosition + barWidth, y2) + graphics.line(barXPosition + barWidth, y1) + graphics.line(barXPosition + barWidth / 2, y1) + graphics.line(barXPosition + barWidth / 2, l2) + graphics.line(barXPosition + barWidth / 2, y1) + graphics.line(barXPosition, y1) + graphics.line(barXPosition, y2 - strokeWidth / 2)
      ];
    }
    pathFrom = pathFrom + graphics.move(barXPosition, y1);
    if (!w.axisFlags.isXNumeric) {
      x = x + xDivision;
    }
    return {
      pathTo,
      pathFrom,
      x,
      y: y2,
      goalY: this.barHelpers.getGoalValues(
        "y",
        /** @type {any} */
        null,
        zeroH,
        i,
        j,
        indexes.translationsIndex
      ),
      barXPosition,
      color
    };
  }
  /** @param {{indexes: any, y: any, yDivision: any, barHeight: any, zeroW: any, strokeWidth: any}} opts */
  drawHorizontalBoxPaths({
    indexes,
    y,
    yDivision,
    barHeight,
    zeroW,
    strokeWidth
  }) {
    var _a, _b;
    const w = this.w;
    const graphics = new Graphics(this.w);
    const i = indexes.i;
    const j = indexes.j;
    const realIndex = indexes.realIndex;
    const { colors: candleColors } = w.config.plotOptions.candlestick;
    const { colors: boxColors } = this.boxOptions;
    const getColor = (color2) => Array.isArray(color2) ? color2[realIndex] : color2;
    const yRatio = this.invertedYRatio;
    const ohlc = this.getOHLCValue(realIndex, j);
    let color = ohlc.o < ohlc.c ? [getColor(candleColors.upward)] : [getColor(candleColors.downward)];
    if (this.isBoxPlot) {
      color = [getColor(boxColors.lower), getColor(boxColors.upper)];
    }
    let l1 = zeroW;
    let l2 = zeroW;
    let x1 = Math.min(ohlc.o, ohlc.c);
    let x2 = Math.max(ohlc.o, ohlc.c);
    let m = ohlc.m;
    if (w.axisFlags.isXNumeric) {
      y = (w.seriesData.seriesX[realIndex][j] - w.globals.minX) / this.invertedXRatio - barHeight / 2;
    }
    const barYPosition = y + barHeight * this.visibleI;
    if (typeof /** @type {any} */
    ((_a = this.series[i]) == null ? void 0 : _a[j]) === "undefined" || /** @type {any} */
    ((_b = this.series[i]) == null ? void 0 : _b[j]) === null) {
      x1 = zeroW;
      x2 = zeroW;
    } else {
      x1 = zeroW + x1 / yRatio;
      x2 = zeroW + x2 / yRatio;
      l1 = zeroW + ohlc.h / yRatio;
      l2 = zeroW + ohlc.l / yRatio;
      m = zeroW + ohlc.m / yRatio;
    }
    let pathFrom = graphics.move(x1, barYPosition + barHeight / 2);
    if (w.globals.previousPaths.length > 0) {
      pathFrom = this.getPreviousPath(realIndex, j);
    }
    const pathTo = [
      graphics.move(x1, barYPosition) + graphics.line(x1, barYPosition + barHeight / 2) + graphics.line(l1, barYPosition + barHeight / 2) + graphics.line(l1, barYPosition + barHeight / 2 - barHeight / 4) + graphics.line(l1, barYPosition + barHeight / 2 + barHeight / 4) + graphics.line(l1, barYPosition + barHeight / 2) + graphics.line(x1, barYPosition + barHeight / 2) + graphics.line(x1, barYPosition + barHeight) + graphics.line(m, barYPosition + barHeight) + graphics.line(m, barYPosition) + graphics.line(x1 + strokeWidth / 2, barYPosition),
      graphics.move(m, barYPosition) + graphics.line(m, barYPosition + barHeight) + graphics.line(x2, barYPosition + barHeight) + graphics.line(x2, barYPosition + barHeight / 2) + graphics.line(l2, barYPosition + barHeight / 2) + graphics.line(l2, barYPosition + barHeight - barHeight / 4) + graphics.line(l2, barYPosition + barHeight / 4) + graphics.line(l2, barYPosition + barHeight / 2) + graphics.line(x2, barYPosition + barHeight / 2) + graphics.line(x2, barYPosition) + graphics.line(m, barYPosition) + "z"
    ];
    pathFrom = pathFrom + graphics.move(x1, barYPosition);
    if (!w.axisFlags.isXNumeric) {
      y = y + yDivision;
    }
    return {
      pathTo,
      pathFrom,
      x: x2,
      y,
      goalX: this.barHelpers.getGoalValues(
        "x",
        zeroW,
        /** @type {any} */
        null,
        i,
        j,
        0
      ),
      barYPosition,
      color
    };
  }
  /**
   * @param {number} i
   * @param {number} j
   */
  getOHLCValue(i, j) {
    const w = this.w;
    const coreUtils = this.coreUtils;
    const getCandleVal = (arr) => arr[i] && arr[i][j] != null ? (
      /** @type {any} */
      coreUtils.getLogValAtSeriesIndex(arr[i][j], i)
    ) : 0;
    const h = getCandleVal(w.candleData.seriesCandleH);
    const o = getCandleVal(w.candleData.seriesCandleO);
    const m = getCandleVal(w.candleData.seriesCandleM);
    const c = getCandleVal(w.candleData.seriesCandleC);
    const l = getCandleVal(w.candleData.seriesCandleL);
    return {
      o: this.isBoxPlot ? h : o,
      h: this.isBoxPlot ? o : h,
      m,
      l: this.isBoxPlot ? c : l,
      c: this.isBoxPlot ? l : c
    };
  }
}
class TreemapHelpers {
  /**
   * @param {import('../../../types/internal').ChartStateW} w
   * @param {import('../../../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.ctx = ctx;
    this.w = w;
  }
  checkColorRange() {
    const w = this.w;
    let negRange = false;
    const chartOpts = w.config.plotOptions[w.config.chart.type];
    if (chartOpts.colorScale.ranges.length > 0) {
      chartOpts.colorScale.ranges.map((range) => {
        if (range.from <= 0) {
          negRange = true;
        }
      });
    }
    return negRange;
  }
  /**
   * @param {string} chartType
   * @param {number} i
   * @param {number} j
   * @param {any} negRange
   */
  getShadeColor(chartType, i, j, negRange) {
    const w = this.w;
    let colorShadePercent = 1;
    const shadeIntensity = w.config.plotOptions[chartType].shadeIntensity;
    const colorProps = this.determineColor(chartType, i, j);
    if (
      /** @type {any} */
      w.globals.hasNegs || negRange
    ) {
      if (w.config.plotOptions[chartType].reverseNegativeShade) {
        if (colorProps.percent < 0) {
          colorShadePercent = colorProps.percent / 100 * (shadeIntensity * 1.25);
        } else {
          colorShadePercent = (1 - colorProps.percent / 100) * (shadeIntensity * 1.25);
        }
      } else {
        if (colorProps.percent <= 0) {
          colorShadePercent = 1 - (1 + colorProps.percent / 100) * shadeIntensity;
        } else {
          colorShadePercent = (1 - colorProps.percent / 100) * shadeIntensity;
        }
      }
    } else {
      colorShadePercent = 1 - colorProps.percent / 100;
      if (chartType === "treemap") {
        colorShadePercent = (1 - colorProps.percent / 100) * (shadeIntensity * 1.25);
      }
    }
    let color = colorProps.color;
    const utils = new Utils$1();
    if (w.config.plotOptions[chartType].enableShades) {
      if (this.w.config.theme.mode === "dark") {
        const shadeColor = utils.shadeColor(
          colorShadePercent * -1,
          colorProps.color
        );
        color = Utils$1.hexToRgba(
          Utils$1.isColorHex(shadeColor) ? shadeColor : Utils$1.rgb2hex(shadeColor),
          w.config.fill.opacity
        );
      } else {
        const shadeColor = utils.shadeColor(colorShadePercent, colorProps.color);
        color = Utils$1.hexToRgba(
          Utils$1.isColorHex(shadeColor) ? shadeColor : Utils$1.rgb2hex(shadeColor),
          w.config.fill.opacity
        );
      }
    }
    return { color, colorProps };
  }
  /**
   * @param {string} chartType
   * @param {number} i
   * @param {number} j
   */
  determineColor(chartType, i, j) {
    const w = this.w;
    const val = w.seriesData.series[i][j];
    const chartOpts = w.config.plotOptions[chartType];
    let seriesNumber = chartOpts.colorScale.inverse ? j : i;
    if (chartOpts.distributed && w.config.chart.type === "treemap") {
      seriesNumber = j;
    }
    let color = w.globals.colors[seriesNumber];
    let foreColor = null;
    let min = Math.min(...w.seriesData.series[i]);
    let max = Math.max(...w.seriesData.series[i]);
    if (!chartOpts.distributed && chartType === "heatmap") {
      min = w.globals.minY;
      max = w.globals.maxY;
    }
    if (typeof chartOpts.colorScale.min !== "undefined") {
      min = chartOpts.colorScale.min < w.globals.minY ? chartOpts.colorScale.min : w.globals.minY;
      max = chartOpts.colorScale.max > w.globals.maxY ? chartOpts.colorScale.max : w.globals.maxY;
    }
    const total = Math.abs(max) + Math.abs(min);
    let percent = 100 * val / (total === 0 ? total - 1e-6 : total);
    if (chartOpts.colorScale.ranges.length > 0) {
      const colorRange = chartOpts.colorScale.ranges;
      colorRange.map((range) => {
        if (val >= range.from && val <= range.to) {
          color = range.color;
          foreColor = range.foreColor ? range.foreColor : null;
          min = range.from;
          max = range.to;
          const rTotal = Math.abs(max) + Math.abs(min);
          percent = 100 * val / (rTotal === 0 ? rTotal - 1e-6 : rTotal);
        }
      });
    }
    return {
      color,
      foreColor,
      percent
    };
  }
  /** @param {{ text?: any, x?: any, y?: any, i?: any, j?: any, colorProps?: any, fontSize?: any, series?: any }} opts */
  calculateDataLabels({ text, x, y, i, j, colorProps, fontSize }) {
    const w = this.w;
    const dataLabelsConfig = w.config.dataLabels;
    const graphics = new Graphics(this.w);
    const dataLabels = new DataLabels(this.w, this.ctx);
    let elDataLabelsWrap = null;
    if (dataLabelsConfig.enabled) {
      elDataLabelsWrap = graphics.group({
        class: "apexcharts-data-labels"
      });
      const offX = dataLabelsConfig.offsetX;
      const offY = dataLabelsConfig.offsetY;
      const dataLabelsX = x + offX;
      const dataLabelsY = y + parseFloat(dataLabelsConfig.style.fontSize) / 3 + offY;
      dataLabels.plotDataLabelsText({
        x: dataLabelsX,
        y: dataLabelsY,
        text,
        i,
        j,
        color: colorProps.foreColor,
        parent: elDataLabelsWrap,
        fontSize,
        dataLabelsConfig
      });
    }
    return elDataLabelsWrap;
  }
}
class HeatMap {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   * @param {import('../types/internal').XYRatios} xyRatios
   */
  constructor(w, ctx, xyRatios) {
    this.ctx = ctx;
    this.w = w;
    this.xRatio = xyRatios.xRatio;
    this.yRatio = xyRatios.yRatio;
    this.dynamicAnim = this.w.config.chart.animations.dynamicAnimation;
    this.helpers = new TreemapHelpers(w, ctx);
    this.rectRadius = this.w.config.plotOptions.heatmap.radius;
    this.strokeWidth = this.w.config.stroke.show ? this.w.config.stroke.width : 0;
  }
  /**
   * @param {any[]} series
   */
  draw(series) {
    const w = this.w;
    const graphics = new Graphics(this.w, this.ctx);
    const ret = graphics.group({
      class: "apexcharts-heatmap"
    });
    ret.attr("clip-path", `url(#gridRectMask${w.globals.cuid})`);
    const xDivision = w.layout.gridWidth / w.globals.dataPoints;
    const yDivision = w.layout.gridHeight / w.seriesData.series.length;
    let y1 = 0;
    let rev = false;
    this.negRange = this.helpers.checkColorRange();
    const heatSeries = series.slice();
    if (w.config.yaxis[0].reversed) {
      rev = true;
      heatSeries.reverse();
    }
    for (let i = rev ? 0 : heatSeries.length - 1; rev ? i < heatSeries.length : i >= 0; rev ? i++ : i--) {
      const elSeries = graphics.group({
        class: `apexcharts-series apexcharts-heatmap-series`,
        seriesName: Utils$1.escapeString(w.seriesData.seriesNames[i]),
        rel: i + 1,
        "data:realIndex": i
      });
      Series.addCollapsedClassToSeries(this.w, elSeries, i);
      graphics.setupEventDelegation(elSeries, ".apexcharts-heatmap-rect");
      if (w.config.chart.dropShadow.enabled) {
        const shadow = w.config.chart.dropShadow;
        const filters = new Filters(this.w);
        filters.dropShadow(elSeries, shadow, i);
      }
      let x1 = 0;
      const shadeIntensity = w.config.plotOptions.heatmap.shadeIntensity;
      let j = 0;
      for (let dIndex = 0; dIndex < w.globals.dataPoints; dIndex++) {
        if (w.seriesData.seriesX.length && !w.globals.allSeriesHasEqualX) {
          if (w.globals.minX + w.globals.minXDiff * dIndex < w.seriesData.seriesX[i][j]) {
            x1 = x1 + xDivision;
            continue;
          }
        }
        if (j >= heatSeries[i].length) break;
        const heatColor = this.helpers.getShadeColor(
          w.config.chart.type,
          i,
          j,
          this.negRange
        );
        let color = heatColor.color;
        const heatColorProps = heatColor.colorProps;
        if (w.config.fill.type === "image") {
          const fill = new Fill(this.w);
          color = fill.fillPath({
            seriesNumber: i,
            dataPointIndex: j,
            opacity: (
              /** @type {any} */
              w.globals.hasNegs ? heatColorProps.percent < 0 ? 1 - (1 + heatColorProps.percent / 100) : shadeIntensity + heatColorProps.percent / 100 : heatColorProps.percent / 100
            ),
            patternID: Utils$1.randomId(),
            width: w.config.fill.image.width ? w.config.fill.image.width : xDivision,
            height: w.config.fill.image.height ? w.config.fill.image.height : yDivision
          });
        }
        const radius = this.rectRadius;
        const rect = graphics.drawRect(x1, y1, xDivision, yDivision, radius);
        rect.attr({
          cx: x1,
          cy: y1
        });
        rect.node.classList.add("apexcharts-heatmap-rect");
        elSeries.add(rect);
        rect.attr({
          fill: color,
          i,
          index: i,
          j,
          val: series[i][j],
          "stroke-width": this.strokeWidth,
          stroke: w.config.plotOptions.heatmap.useFillColorAsStroke ? color : w.globals.stroke.colors[0],
          color
        });
        if (w.config.chart.animations.enabled && !w.globals.dataChanged) {
          let speed = 1;
          if (!w.globals.resized) {
            speed = w.config.chart.animations.speed;
          }
          this.animateHeatMap(rect, x1, y1, xDivision, yDivision, speed);
        }
        if (w.globals.dataChanged) {
          let speed = 1;
          if (this.dynamicAnim.enabled && w.globals.shouldAnimate) {
            speed = this.dynamicAnim.speed;
            let colorFrom = w.globals.previousPaths[i] && w.globals.previousPaths[i][j] && w.globals.previousPaths[i][j].color;
            if (!colorFrom) colorFrom = "rgba(255, 255, 255, 0)";
            this.animateHeatColor(
              rect,
              Utils$1.isColorHex(colorFrom) ? colorFrom : Utils$1.rgb2hex(colorFrom),
              Utils$1.isColorHex(color) ? color : Utils$1.rgb2hex(color),
              speed
            );
          }
        }
        const formatter = w.config.dataLabels.formatter;
        const formattedText = formatter(w.seriesData.series[i][j], {
          value: w.seriesData.series[i][j],
          seriesIndex: i,
          dataPointIndex: j,
          w
        });
        const dataLabels = this.helpers.calculateDataLabels({
          text: formattedText,
          x: x1 + xDivision / 2,
          y: y1 + yDivision / 2,
          i,
          j,
          colorProps: heatColorProps,
          series: heatSeries
        });
        if (dataLabels !== null) {
          elSeries.add(dataLabels);
        }
        x1 = x1 + xDivision;
        j++;
      }
      y1 = y1 + yDivision;
      ret.add(elSeries);
    }
    const yAxisScale = (
      /** @type {any[]} */
      w.globals.yAxisScale[0].result.slice()
    );
    if (w.config.yaxis[0].reversed) {
      yAxisScale.unshift("");
    } else {
      yAxisScale.push("");
    }
    w.globals.yAxisScale[0].result = yAxisScale;
    return ret;
  }
  /**
   * @param {any} el
   * @param {number} x
   * @param {number} y
   * @param {number} width
   * @param {number} height
   * @param {number} speed
   */
  animateHeatMap(el, x, y, width, height, speed) {
    const animations = new Animations(this.w);
    animations.animateRect(
      el,
      {
        x: x + width / 2,
        y: y + height / 2,
        width: 0,
        height: 0
      },
      {
        x,
        y,
        width,
        height
      },
      speed,
      () => {
        animations.animationCompleted(el);
      }
    );
  }
  /**
   * @param {any} el
   * @param {string} colorFrom
   * @param {string} colorTo
   * @param {number} speed
   */
  animateHeatColor(el, colorFrom, colorTo, speed) {
    el.attr({
      fill: colorFrom
    }).animate(speed).attr({
      fill: colorTo
    });
  }
}
class Helpers5 {
  /**
   * @param {import('../../../charts/Line').default} lineCtx
   */
  constructor(lineCtx) {
    this.w = lineCtx.w;
    this.lineCtx = lineCtx;
  }
  /**
   * @param {number} i
   * @param {any[]} series
   */
  sameValueSeriesFix(i, series) {
    const w = this.w;
    if (w.config.fill.type === "gradient" || w.config.fill.type[i] === "gradient") {
      const coreUtils = new CoreUtils(this.lineCtx.w);
      if (coreUtils.seriesHaveSameValues(i)) {
        const gSeries = series[i].slice();
        gSeries[gSeries.length - 1] = gSeries[gSeries.length - 1] + 1e-6;
        series[i] = gSeries;
      }
    }
    return series;
  }
  /** @param {{series: any, realIndex: any, x: any, y: any, i: any, j: any, prevY: any}} opts */
  calculatePoints({ series, realIndex, x, y, i, j, prevY }) {
    const w = this.w;
    const ptX = [];
    const ptY = [];
    let xPT1st = this.lineCtx.categoryAxisCorrection + w.config.markers.offsetX;
    if (w.axisFlags.isXNumeric) {
      xPT1st = (w.seriesData.seriesX[realIndex][0] - w.globals.minX) / this.lineCtx.xRatio + w.config.markers.offsetX;
    }
    if (j === 0) {
      ptX.push(xPT1st);
      ptY.push(
        Utils$1.isNumber(series[i][0]) ? prevY + w.config.markers.offsetY : null
      );
    }
    ptX.push(x + w.config.markers.offsetX);
    ptY.push(
      Utils$1.isNumber(series[i][j + 1]) ? y + w.config.markers.offsetY : null
    );
    return {
      x: ptX,
      y: ptY
    };
  }
  /** @param {{pathFromLine: any, pathFromArea: any, realIndex: any}} opts */
  checkPreviousPaths({ pathFromLine, pathFromArea, realIndex }) {
    const w = this.w;
    for (let pp = 0; pp < w.globals.previousPaths.length; pp++) {
      const gpp = w.globals.previousPaths[pp];
      if ((gpp.type === "line" || gpp.type === "area") && gpp.paths.length > 0 && parseInt(gpp.realIndex, 10) === parseInt(realIndex, 10)) {
        if (gpp.type === "line") {
          this.lineCtx.appendPathFrom = false;
          pathFromLine = w.globals.previousPaths[pp].paths[0].d;
        } else if (gpp.type === "area") {
          this.lineCtx.appendPathFrom = false;
          pathFromArea = w.globals.previousPaths[pp].paths[0].d;
          if (w.config.stroke.show && w.globals.previousPaths[pp].paths[1]) {
            pathFromLine = w.globals.previousPaths[pp].paths[1].d;
          }
        }
      }
    }
    return {
      pathFromLine,
      pathFromArea
    };
  }
  /** @param {{i: any, realIndex: any, series: any, prevY: any, lineYPosition: any, translationsIndex: any}} opts */
  determineFirstPrevY({
    i,
    realIndex,
    series,
    prevY,
    lineYPosition,
    translationsIndex
  }) {
    var _a, _b, _c;
    const w = this.w;
    const stackSeries = w.config.chart.stacked && !w.globals.comboCharts || w.config.chart.stacked && w.globals.comboCharts && (!this.w.config.chart.stackOnlyBar || /** @type {any} */
    ((_a = this.w.config.series[realIndex]) == null ? void 0 : _a.type) === "bar" || /** @type {any} */
    ((_b = this.w.config.series[realIndex]) == null ? void 0 : _b.type) === "column");
    if (typeof ((_c = series[i]) == null ? void 0 : _c[0]) !== "undefined") {
      if (stackSeries) {
        if (i > 0) {
          lineYPosition = this.lineCtx.prevSeriesY[i - 1][0];
        } else {
          lineYPosition = this.lineCtx.zeroY;
        }
      } else {
        lineYPosition = this.lineCtx.zeroY;
      }
      prevY = lineYPosition - series[i][0] / this.lineCtx.yRatio[translationsIndex] + (this.lineCtx.isReversed ? series[i][0] / this.lineCtx.yRatio[translationsIndex] : 0) * 2;
    } else {
      if (stackSeries && i > 0 && typeof series[i][0] === "undefined") {
        for (let s = i - 1; s >= 0; s--) {
          if (series[s][0] !== null && typeof series[s][0] !== "undefined") {
            lineYPosition = this.lineCtx.prevSeriesY[s][0];
            prevY = lineYPosition;
            break;
          }
        }
      }
    }
    return {
      prevY,
      lineYPosition
    };
  }
}
const tangents = (points) => {
  const m = finiteDifferences(points);
  const n = points.length - 1;
  const ε = 1e-6;
  const tgts = [];
  let a, b, d, s;
  for (let i = 0; i < n; i++) {
    d = slope(points[i], points[i + 1]);
    if (Math.abs(d) < ε) {
      m[i] = m[i + 1] = 0;
    } else {
      a = m[i] / d;
      b = m[i + 1] / d;
      s = a * a + b * b;
      if (s > 9) {
        s = d * 3 / Math.sqrt(s);
        m[i] = s * a;
        m[i + 1] = s * b;
      }
    }
  }
  for (let i = 0; i <= n; i++) {
    s = (points[Math.min(n, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i]));
    tgts.push([s || 0, m[i] * s || 0]);
  }
  return tgts;
};
const svgPath = (points) => {
  let p = "";
  for (let i = 0; i < points.length; i++) {
    const point = points[i];
    const n = point.length;
    if (n > 4) {
      p += `C${point[0]}, ${point[1]}`;
      p += `, ${point[2]}, ${point[3]}`;
      p += `, ${point[4]}, ${point[5]}`;
    } else if (n > 2) {
      p += `S${point[0]}, ${point[1]}`;
      p += `, ${point[2]}, ${point[3]}`;
    }
  }
  return p;
};
const spline = {
  /**
   * Convert 'points' to bezier
   * @param {any[]} points
   * @returns {any[]}
   */
  points(points) {
    const tgts = tangents(points);
    const p = points[1];
    const p0 = points[0];
    const pts = [];
    const t = tgts[1];
    const t0 = tgts[0];
    pts.push(p0, [
      p0[0] + t0[0],
      p0[1] + t0[1],
      p[0] - t[0],
      p[1] - t[1],
      p[0],
      p[1]
    ]);
    for (let i = 2, n = tgts.length; i < n; i++) {
      const p2 = points[i];
      const t2 = tgts[i];
      pts.push([p2[0] - t2[0], p2[1] - t2[1], p2[0], p2[1]]);
    }
    return pts;
  },
  /**
   * Slice out a segment of 'points'
   * @param {any[]} points
   * @param {Number} start
   * @param {Number} end
   * @returns {any[]}
   */
  slice(points, start, end) {
    const pts = points.slice(start, end);
    if (start) {
      if (end - start > 1 && pts[1].length < 6) {
        const n = pts[0].length;
        pts[1] = [
          pts[0][n - 2] * 2 - pts[0][n - 4],
          pts[0][n - 1] * 2 - pts[0][n - 3]
        ].concat(pts[1]);
      }
      pts[0] = pts[0].slice(-2);
    }
    return pts;
  }
};
function slope(p0, p1) {
  return (p1[1] - p0[1]) / (p1[0] - p0[0]);
}
function finiteDifferences(points) {
  const m = [];
  let p0 = points[0];
  let p1 = points[1];
  let d = m[0] = slope(p0, p1);
  let i = 1;
  for (let n = points.length - 1; i < n; i++) {
    p0 = p1;
    p1 = points[i + 1];
    m[i] = (d + (d = slope(p0, p1))) * 0.5;
  }
  m[i] = d;
  return m;
}
class Line {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   * @param {import('../types/internal').XYRatios} xyRatios
   * @param {boolean} isPointsChart
   */
  constructor(w, ctx, xyRatios, isPointsChart) {
    this.ctx = ctx;
    this.w = w;
    this.xyRatios = xyRatios;
    this.xRatio = 0;
    this.yRatio = [];
    this.zRatio = 0;
    this.baseLineY = [];
    this.pointsChart = !(this.w.config.chart.type !== "bubble" && this.w.config.chart.type !== "scatter") || isPointsChart;
    this.scatter = new Scatter(this.w, this.ctx);
    this.noNegatives = this.w.globals.minX === Number.MAX_VALUE;
    this.lineHelpers = new Helpers5(this);
    this.markers = new Markers(this.w, this.ctx);
    this.prevSeriesY = [];
    this.categoryAxisCorrection = 0;
    this.yaxisIndex = 0;
    this.xDivision = 0;
    this.zeroY = 0;
    this.areaBottomY = 0;
    this.strokeWidth = 0;
    this.isReversed = false;
    this.appendPathFrom = false;
    this.elSeries = null;
    this.elPointsMain = null;
    this.elDataLabelsWrap = null;
  }
  /**
   * @param {any[]} series
   * @param {string} ctype
   * @param {number} seriesIndex
   * @param {any} seriesRangeEnd
   */
  draw(series, ctype, seriesIndex, seriesRangeEnd) {
    var _a;
    const w = this.w;
    const graphics = new Graphics(this.w);
    const type = w.globals.comboCharts ? ctype : w.config.chart.type;
    const ret = graphics.group({
      class: `apexcharts-${type}-series apexcharts-plot-series`
    });
    const coreUtils = new CoreUtils(this.w);
    this.yRatio = this.xyRatios.yRatio;
    this.zRatio = this.xyRatios.zRatio;
    this.xRatio = this.xyRatios.xRatio;
    this.baseLineY = this.xyRatios.baseLineY;
    series = coreUtils.getLogSeries(series);
    this.yRatio = coreUtils.getLogYRatios(this.yRatio);
    this.prevSeriesY = [];
    const allSeries = [];
    for (let i = 0; i < series.length; i++) {
      series = this.lineHelpers.sameValueSeriesFix(i, series);
      const realIndex = w.globals.comboCharts ? (
        /** @type {any} */
        seriesIndex[i]
      ) : i;
      const translationsIndex = this.yRatio.length > 1 ? realIndex : 0;
      this._initSerieVariables(series, i, realIndex);
      const yArrj = [];
      const y2Arrj = [];
      const xArrj = [];
      let x = w.globals.padHorizontal + this.categoryAxisCorrection;
      const y = 1;
      const linePaths = [];
      const areaPaths = [];
      Series.addCollapsedClassToSeries(this.w, this.elSeries, realIndex);
      if (w.axisFlags.isXNumeric && w.seriesData.seriesX.length > 0) {
        x = (w.seriesData.seriesX[realIndex][0] - w.globals.minX) / this.xRatio;
      }
      xArrj.push(x);
      const pX = x;
      let pY2;
      const prevX = pX;
      let prevY = this.zeroY;
      let prevY2 = this.zeroY;
      const lineYPosition = 0;
      const firstPrevY = this.lineHelpers.determineFirstPrevY({
        i,
        realIndex,
        series,
        prevY,
        lineYPosition,
        translationsIndex
      });
      prevY = firstPrevY.prevY;
      if (w.config.stroke.curve === "monotoneCubic" && series[i][0] === null) {
        yArrj.push(null);
      } else {
        yArrj.push(prevY);
      }
      const pY = prevY;
      let firstPrevY2;
      if (type === "rangeArea") {
        firstPrevY2 = this.lineHelpers.determineFirstPrevY({
          i,
          realIndex,
          series: seriesRangeEnd,
          prevY: prevY2,
          lineYPosition,
          translationsIndex
        });
        prevY2 = firstPrevY2.prevY;
        pY2 = prevY2;
        y2Arrj.push(yArrj[0] !== null ? prevY2 : null);
      }
      const pathsFrom = this._calculatePathsFrom({
        type,
        series,
        i,
        realIndex,
        translationsIndex,
        prevX,
        prevY,
        prevY2
      });
      const rYArrj = [yArrj[0]];
      const rY2Arrj = [y2Arrj[0]];
      const iteratingOpts = {
        type,
        series,
        realIndex,
        translationsIndex,
        i,
        x,
        y,
        pX,
        pY,
        pathsFrom,
        linePaths,
        areaPaths,
        seriesIndex,
        lineYPosition,
        xArrj,
        yArrj,
        y2Arrj,
        seriesRangeEnd
      };
      const paths = this._iterateOverDataPoints(__spreadProps(__spreadValues({}, iteratingOpts), {
        iterations: type === "rangeArea" ? series[i].length - 1 : void 0,
        isRangeStart: true
      }));
      if (type === "rangeArea") {
        const pathsFrom2 = this._calculatePathsFrom({
          series: seriesRangeEnd,
          i,
          realIndex,
          prevX,
          prevY: prevY2
        });
        const rangePaths = this._iterateOverDataPoints(__spreadProps(__spreadValues({}, iteratingOpts), {
          series: seriesRangeEnd,
          xArrj: [x],
          yArrj: rYArrj,
          y2Arrj: rY2Arrj,
          pY: pY2,
          areaPaths: paths.areaPaths,
          pathsFrom: pathsFrom2,
          iterations: seriesRangeEnd[i].length - 1,
          isRangeStart: false
        }));
        const segments = paths.linePaths.length / 2;
        for (let s = 0; s < segments; s++) {
          paths.linePaths[s] = rangePaths.linePaths[s + segments] + paths.linePaths[s];
        }
        paths.linePaths.splice(segments);
        paths.pathFromLine = rangePaths.pathFromLine + paths.pathFromLine;
      } else {
        paths.pathFromArea += "z";
      }
      this._handlePaths({ type, realIndex, i, paths });
      this.elSeries.add(this.elPointsMain);
      this.elSeries.add(this.elDataLabelsWrap);
      allSeries.push(this.elSeries);
    }
    if (typeof /** @type {Record<string,any>} */
    ((_a = w.config.series[0]) == null ? void 0 : _a.zIndex) !== "undefined") {
      allSeries.sort(
        (a, b) => Number(a.node.getAttribute("zIndex")) - Number(b.node.getAttribute("zIndex"))
      );
    }
    if (w.config.chart.stacked) {
      for (let s = allSeries.length - 1; s >= 0; s--) {
        ret.add(allSeries[s]);
      }
    } else {
      for (let s = 0; s < allSeries.length; s++) {
        ret.add(allSeries[s]);
      }
    }
    return ret;
  }
  /**
   * @param {any[]} series
   * @param {number} i
   * @param {number} realIndex
   */
  _initSerieVariables(series, i, realIndex) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    this.xDivision = w.layout.gridWidth / (w.globals.dataPoints - (w.config.xaxis.tickPlacement === "on" ? 1 : 0));
    this.strokeWidth = Array.isArray(w.config.stroke.width) ? w.config.stroke.width[realIndex] : w.config.stroke.width;
    let translationsIndex = 0;
    if (this.yRatio.length > 1) {
      this.yaxisIndex = w.globals.seriesYAxisReverseMap[realIndex];
      translationsIndex = realIndex;
    }
    this.isReversed = w.config.yaxis[this.yaxisIndex] && w.config.yaxis[this.yaxisIndex].reversed;
    this.zeroY = w.layout.gridHeight - this.baseLineY[translationsIndex] - (this.isReversed ? w.layout.gridHeight : 0) + (this.isReversed ? this.baseLineY[translationsIndex] * 2 : 0);
    this.areaBottomY = this.zeroY;
    if (this.zeroY > w.layout.gridHeight || w.config.plotOptions.area.fillTo === "end") {
      this.areaBottomY = w.layout.gridHeight;
    }
    this.categoryAxisCorrection = this.xDivision / 2;
    const seriesItem = (
      /** @type {Record<string,any>} */
      w.config.series[realIndex]
    );
    this.elSeries = graphics.group({
      class: `apexcharts-series`,
      zIndex: typeof seriesItem.zIndex !== "undefined" ? seriesItem.zIndex : realIndex,
      seriesName: Utils$1.escapeString(w.seriesData.seriesNames[realIndex])
    });
    this.elPointsMain = graphics.group({
      class: "apexcharts-series-markers-wrap",
      "data:realIndex": realIndex
    });
    if (w.globals.hasNullValues) {
      const firstPoint = this.markers.plotChartMarkers({
        pointsPos: {
          x: [0],
          y: [w.layout.gridHeight + w.globals.markers.largestSize]
        },
        seriesIndex: i,
        j: 0,
        pSize: 0.1,
        alwaysDrawMarker: true,
        isVirtualPoint: true
      });
      if (firstPoint !== null) {
        this.elPointsMain.add(firstPoint);
      }
    }
    this.elDataLabelsWrap = graphics.group({
      class: "apexcharts-datalabels",
      "data:realIndex": realIndex
    });
    const longestSeries = series[i].length === w.globals.dataPoints;
    this.elSeries.attr({
      "data:longestSeries": longestSeries,
      rel: i + 1,
      "data:realIndex": realIndex
    });
    this.appendPathFrom = true;
  }
  /** @param {{ type?: any, series?: any, i?: any, realIndex?: any, translationsIndex?: any, prevX?: any, prevY?: any, prevY2?: any }} opts */
  _calculatePathsFrom({
    type,
    series,
    i,
    realIndex,
    translationsIndex,
    prevX,
    prevY,
    prevY2
  }) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    let linePath, areaPath, pathFromLine, pathFromArea;
    if (series[i][0] === null) {
      for (let s = 0; s < series[i].length; s++) {
        if (series[i][s] !== null) {
          prevX = this.xDivision * s;
          prevY = this.zeroY - series[i][s] / this.yRatio[translationsIndex];
          linePath = graphics.move(prevX, prevY);
          areaPath = graphics.move(prevX, this.areaBottomY);
          break;
        }
      }
    } else {
      linePath = graphics.move(prevX, prevY);
      if (type === "rangeArea") {
        linePath = graphics.move(prevX, prevY2) + graphics.line(prevX, prevY);
      }
      areaPath = graphics.move(prevX, this.areaBottomY) + graphics.line(prevX, prevY);
    }
    pathFromLine = graphics.move(0, this.areaBottomY) + graphics.line(0, this.areaBottomY);
    pathFromArea = graphics.move(0, this.areaBottomY) + graphics.line(0, this.areaBottomY);
    if (w.globals.previousPaths.length > 0) {
      const pathFrom = this.lineHelpers.checkPreviousPaths({
        pathFromLine,
        pathFromArea,
        realIndex
      });
      pathFromLine = pathFrom.pathFromLine;
      pathFromArea = pathFrom.pathFromArea;
    }
    return {
      prevX,
      prevY,
      linePath,
      areaPath,
      pathFromLine,
      pathFromArea
    };
  }
  /** @param {{type: any, realIndex: any, i: any, paths: any}} opts */
  _handlePaths({ type, realIndex, i, paths }) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const fill = new Fill(this.w);
    this.prevSeriesY.push(paths.yArrj);
    w.globals.seriesXvalues[realIndex] = paths.xArrj;
    w.globals.seriesYvalues[realIndex] = paths.yArrj;
    const forecast = w.config.forecastDataPoints;
    if (forecast.count > 0 && type !== "rangeArea") {
      const forecastCutoff = w.globals.seriesXvalues[realIndex][w.globals.seriesXvalues[realIndex].length - forecast.count - 1];
      const elForecastMask = graphics.drawRect(
        forecastCutoff,
        0,
        w.layout.gridWidth,
        w.layout.gridHeight,
        0
      );
      w.dom.elForecastMask.appendChild(elForecastMask.node);
      const elNonForecastMask = graphics.drawRect(
        0,
        0,
        forecastCutoff,
        w.layout.gridHeight,
        0
      );
      w.dom.elNonForecastMask.appendChild(elNonForecastMask.node);
    }
    if (!this.pointsChart) {
      w.globals.delayedElements.push({
        el: this.elPointsMain.node,
        index: realIndex
      });
    }
    const defaultRenderedPathOptions = {
      i,
      realIndex,
      animationDelay: i,
      initialSpeed: w.config.chart.animations.speed,
      dataChangeSpeed: w.config.chart.animations.dynamicAnimation.speed,
      className: `apexcharts-${type}`
    };
    if (type === "area") {
      const pathFill = fill.fillPath({
        seriesNumber: realIndex
      });
      for (let p = 0; p < paths.areaPaths.length; p++) {
        const renderedPath = graphics.renderPaths(__spreadProps(__spreadValues({}, defaultRenderedPathOptions), {
          pathFrom: paths.pathFromArea,
          pathTo: paths.areaPaths[p],
          stroke: "none",
          strokeWidth: 0,
          strokeLineCap: null,
          fill: pathFill
        }));
        this.elSeries.add(renderedPath);
      }
    }
    if (w.config.stroke.show && !this.pointsChart) {
      let lineFill = null;
      if (type === "line") {
        lineFill = fill.fillPath({
          seriesNumber: realIndex,
          i
        });
      } else {
        if (w.config.stroke.fill.type === "solid") {
          lineFill = w.globals.stroke.colors[realIndex];
        } else {
          const prevFill = w.config.fill;
          w.config.fill = w.config.stroke.fill;
          lineFill = fill.fillPath({
            seriesNumber: realIndex,
            i
          });
          w.config.fill = prevFill;
        }
      }
      for (let p = 0; p < paths.linePaths.length; p++) {
        let pathFill = lineFill;
        if (type === "rangeArea") {
          pathFill = fill.fillPath({
            seriesNumber: realIndex
          });
        }
        const linePathCommonOpts = __spreadProps(__spreadValues({}, defaultRenderedPathOptions), {
          pathFrom: paths.pathFromLine,
          pathTo: paths.linePaths[p],
          stroke: lineFill,
          strokeWidth: this.strokeWidth,
          strokeLineCap: w.config.stroke.lineCap,
          fill: type === "rangeArea" ? pathFill : "none"
        });
        const renderedPath = graphics.renderPaths(linePathCommonOpts);
        this.elSeries.add(renderedPath);
        renderedPath.attr("fill-rule", `evenodd`);
        if (forecast.count > 0 && type !== "rangeArea") {
          const renderedForecastPath = graphics.renderPaths(linePathCommonOpts);
          renderedForecastPath.node.setAttribute(
            "stroke-dasharray",
            forecast.dashArray
          );
          if (forecast.strokeWidth) {
            renderedForecastPath.node.setAttribute(
              "stroke-width",
              forecast.strokeWidth
            );
          }
          this.elSeries.add(renderedForecastPath);
          renderedForecastPath.attr(
            "clip-path",
            `url(#forecastMask${w.globals.cuid})`
          );
          renderedPath.attr(
            "clip-path",
            `url(#nonForecastMask${w.globals.cuid})`
          );
        }
      }
    }
  }
  _iterateOverDataPoints({
    type,
    series,
    iterations,
    realIndex,
    translationsIndex,
    i,
    x,
    y,
    pX,
    pY,
    pathsFrom,
    linePaths,
    areaPaths,
    seriesIndex,
    lineYPosition,
    xArrj,
    yArrj,
    y2Arrj,
    isRangeStart,
    seriesRangeEnd
  }) {
    var _a, _b;
    const w = this.w;
    const graphics = new Graphics(this.w);
    const yRatio = this.yRatio;
    let { prevY, linePath, areaPath, pathFromLine, pathFromArea } = pathsFrom;
    const minY = Utils$1.isNumber(w.globals.minYArr[realIndex]) ? w.globals.minYArr[realIndex] : w.globals.minY;
    if (!iterations) {
      iterations = w.globals.dataPoints > 1 ? w.globals.dataPoints - 1 : w.globals.dataPoints;
    }
    const getY = (_y, lineYPos) => {
      return lineYPos - _y / yRatio[translationsIndex] + (this.isReversed ? _y / yRatio[translationsIndex] : 0) * 2;
    };
    let y2 = y;
    const stackSeries = w.config.chart.stacked && !w.globals.comboCharts || w.config.chart.stacked && w.globals.comboCharts && (!this.w.config.chart.stackOnlyBar || /** @type {Record<string,any>} */
    ((_a = this.w.config.series[realIndex]) == null ? void 0 : _a.type) === "bar" || /** @type {Record<string,any>} */
    ((_b = this.w.config.series[realIndex]) == null ? void 0 : _b.type) === "column");
    let curve = w.config.stroke.curve;
    if (Array.isArray(curve)) {
      if (Array.isArray(seriesIndex)) {
        curve = curve[seriesIndex[i]];
      } else {
        curve = curve[i];
      }
    }
    let pathState = 0;
    let segmentStartX;
    for (let j = 0; j < iterations; j++) {
      if (series[i].length === 0) break;
      const isNull = typeof series[i][j + 1] === "undefined" || series[i][j + 1] === null;
      if (w.axisFlags.isXNumeric) {
        let sX = w.seriesData.seriesX[realIndex][j + 1];
        if (typeof w.seriesData.seriesX[realIndex][j + 1] === "undefined") {
          sX = w.seriesData.seriesX[realIndex][iterations - 1];
        }
        x = (sX - w.globals.minX) / this.xRatio;
      } else {
        x = x + this.xDivision;
      }
      if (stackSeries) {
        if (i > 0 && w.globals.collapsedSeries.length < w.config.series.length - 1) {
          const prevIndex = (pi) => {
            for (let pii = pi; pii > 0; pii--) {
              if (w.globals.collapsedSeriesIndices.indexOf(
                (seriesIndex == null ? void 0 : seriesIndex[pii]) || pii
              ) > -1) {
                pii--;
              } else {
                return pii;
              }
            }
            return 0;
          };
          lineYPosition = this.prevSeriesY[prevIndex(i - 1)][j + 1];
        } else {
          lineYPosition = this.zeroY;
        }
      } else {
        lineYPosition = this.zeroY;
      }
      if (isNull) {
        y = getY(minY, lineYPosition);
      } else {
        y = getY(series[i][j + 1], lineYPosition);
        if (type === "rangeArea") {
          y2 = getY(seriesRangeEnd[i][j + 1], lineYPosition);
        }
      }
      xArrj.push(series[i][j + 1] === null ? null : x);
      if (isNull && (w.config.stroke.curve === "smooth" || w.config.stroke.curve === "monotoneCubic")) {
        yArrj.push(null);
        y2Arrj.push(null);
      } else {
        yArrj.push(y);
        y2Arrj.push(y2);
      }
      const pointsPos = this.lineHelpers.calculatePoints({
        series,
        x,
        y,
        realIndex,
        i,
        j,
        prevY
      });
      const calculatedPaths = this._createPaths({
        type,
        series,
        i,
        j,
        x,
        y,
        y2,
        xArrj,
        yArrj,
        y2Arrj,
        pX,
        pY,
        pathState,
        segmentStartX,
        linePath,
        areaPath,
        linePaths,
        areaPaths,
        curve,
        isRangeStart
      });
      areaPaths = calculatedPaths.areaPaths;
      linePaths = calculatedPaths.linePaths;
      pX = calculatedPaths.pX;
      pY = calculatedPaths.pY;
      pathState = calculatedPaths.pathState;
      segmentStartX = calculatedPaths.segmentStartX;
      areaPath = calculatedPaths.areaPath;
      linePath = calculatedPaths.linePath;
      if (this.appendPathFrom && !w.globals.hasNullValues && !(curve === "monotoneCubic" && type === "rangeArea")) {
        pathFromLine += graphics.line(x, this.areaBottomY);
        pathFromArea += graphics.line(x, this.areaBottomY);
      }
      this.handleNullDataPoints(series, pointsPos, i, j, realIndex);
      this._handleMarkersAndLabels({
        type,
        pointsPos,
        i,
        j,
        realIndex,
        isRangeStart
      });
    }
    return {
      yArrj,
      xArrj,
      pathFromArea,
      areaPaths,
      pathFromLine,
      linePaths,
      linePath,
      areaPath
    };
  }
  /** @param {{type: any, pointsPos: any, isRangeStart: any, i: any, j: any, realIndex: any}} opts */
  _handleMarkersAndLabels({ type, pointsPos, isRangeStart, i, j, realIndex }) {
    const w = this.w;
    const dataLabels = new DataLabels(this.w, this.ctx);
    if (!this.pointsChart) {
      if (w.seriesData.series[i].length > 1) {
        this.elPointsMain.node.classList.add("apexcharts-element-hidden");
      }
      const elPointsWrap = this.markers.plotChartMarkers({
        pointsPos,
        seriesIndex: realIndex,
        j: j + 1
      });
      if (elPointsWrap !== null) {
        this.elPointsMain.add(elPointsWrap);
      }
    } else {
      this.scatter.draw(this.elSeries, j, {
        realIndex,
        pointsPos,
        zRatio: this.zRatio,
        elParent: this.elPointsMain
      });
    }
    const drawnLabels = dataLabels.drawDataLabel({
      type,
      isRangeStart,
      pos: pointsPos,
      i: realIndex,
      j: j + 1
    });
    if (drawnLabels !== null) {
      this.elDataLabelsWrap.add(drawnLabels);
    }
  }
  /** @param {{type: any, series: any, i: any, j: any, x: any, y: any, xArrj: any, yArrj: any, y2: any, y2Arrj: any, pX: any, pY: any, pathState: any, segmentStartX: any, linePath: any, areaPath: any, linePaths: any, areaPaths: any, curve: any, isRangeStart: any}} opts */
  _createPaths({
    type,
    series,
    i,
    j,
    x,
    y,
    xArrj,
    yArrj,
    y2,
    y2Arrj,
    pX,
    pY,
    pathState,
    segmentStartX,
    linePath,
    areaPath,
    linePaths,
    areaPaths,
    curve,
    isRangeStart
  }) {
    const graphics = new Graphics(this.w);
    const areaBottomY = this.areaBottomY;
    const rangeArea = type === "rangeArea";
    const isLowerRangeAreaPath = type === "rangeArea" && isRangeStart;
    switch (curve) {
      case "monotoneCubic": {
        const yAj = isRangeStart ? yArrj : y2Arrj;
        const getSmoothInputs = (xArr, yArr) => {
          return xArr.map((_, i2) => {
            return [_, yArr[i2]];
          }).filter((_) => _[1] !== null);
        };
        const getSegmentLengths = (yArr) => {
          const segLens = [];
          let count = 0;
          yArr.forEach((_) => {
            if (_ !== null) {
              count++;
            } else if (count > 0) {
              segLens.push(count);
              count = 0;
            }
          });
          if (count > 0) {
            segLens.push(count);
          }
          return segLens;
        };
        const getSegments = (yArr, points) => {
          const segLens = getSegmentLengths(yArr);
          const segments = [];
          for (let i2 = 0, len = 0; i2 < segLens.length; len += segLens[i2++]) {
            segments[i2] = spline.slice(points, len, len + segLens[i2]);
          }
          return segments;
        };
        switch (pathState) {
          case 0:
            if (yAj[j + 1] === null) {
              break;
            }
            pathState = 1;
          // falls through
          case 1:
            if (!(rangeArea ? xArrj.length === series[i].length : j === series[i].length - 2)) {
              break;
            }
          // falls through
          case 2: {
            const _xAj = isRangeStart ? xArrj : xArrj.slice().reverse();
            const _yAj = isRangeStart ? yAj : yAj.slice().reverse();
            const smoothInputs = getSmoothInputs(_xAj, _yAj);
            const points = smoothInputs.length > 1 ? spline.points(smoothInputs) : smoothInputs;
            let smoothInputsLower = [];
            if (rangeArea) {
              if (isLowerRangeAreaPath) {
                areaPaths = smoothInputs;
              } else {
                smoothInputsLower = areaPaths.reverse();
              }
            }
            let segmentCount = 0;
            let smoothInputsIndex = 0;
            getSegments(_yAj, points).forEach((_) => {
              segmentCount++;
              const svgPoints = svgPath(_);
              const _start = smoothInputsIndex;
              smoothInputsIndex += _.length;
              const _end = smoothInputsIndex - 1;
              if (isLowerRangeAreaPath) {
                linePath = graphics.move(
                  smoothInputs[_start][0],
                  smoothInputs[_start][1]
                ) + svgPoints;
              } else if (rangeArea) {
                linePath = graphics.move(
                  smoothInputsLower[_start][0],
                  smoothInputsLower[_start][1]
                ) + graphics.line(
                  smoothInputs[_start][0],
                  smoothInputs[_start][1]
                ) + svgPoints + graphics.line(
                  smoothInputsLower[_end][0],
                  smoothInputsLower[_end][1]
                );
              } else {
                linePath = graphics.move(
                  smoothInputs[_start][0],
                  smoothInputs[_start][1]
                ) + svgPoints;
                areaPath = linePath + graphics.line(smoothInputs[_end][0], areaBottomY) + graphics.line(smoothInputs[_start][0], areaBottomY) + "z";
                areaPaths.push(areaPath);
              }
              linePaths.push(linePath);
            });
            if (rangeArea && segmentCount > 1 && !isLowerRangeAreaPath) {
              const upperLinePaths = linePaths.slice(segmentCount).reverse();
              linePaths.splice(segmentCount);
              upperLinePaths.forEach(
                (u) => linePaths.push(u)
              );
            }
            pathState = 0;
            break;
          }
        }
        break;
      }
      case "smooth": {
        const length = (x - pX) * 0.35;
        if (series[i][j] === null) {
          pathState = 0;
        } else {
          switch (pathState) {
            case 0:
              segmentStartX = pX;
              if (isLowerRangeAreaPath) {
                linePath = graphics.move(pX, y2Arrj[j]) + graphics.line(pX, pY);
              } else {
                linePath = graphics.move(pX, pY);
              }
              areaPath = graphics.move(pX, pY);
              if (series[i][j + 1] === null || typeof series[i][j + 1] === "undefined") {
                linePaths.push(linePath);
                areaPaths.push(areaPath);
                break;
              }
              pathState = 1;
              if (j < series[i].length - 2) {
                const p = graphics.curve(pX + length, pY, x - length, y, x, y);
                linePath += p;
                areaPath += p;
                break;
              }
            // falls through
            case 1:
              if (series[i][j + 1] === null) {
                if (isLowerRangeAreaPath) {
                  linePath += graphics.line(pX, y2);
                } else {
                  linePath += graphics.move(pX, pY);
                }
                areaPath += graphics.line(pX, areaBottomY) + graphics.line(segmentStartX, areaBottomY) + "z";
                linePaths.push(linePath);
                areaPaths.push(areaPath);
                pathState = -1;
              } else {
                const p = graphics.curve(pX + length, pY, x - length, y, x, y);
                linePath += p;
                areaPath += p;
                if (j >= series[i].length - 2) {
                  if (isLowerRangeAreaPath) {
                    linePath += graphics.curve(x, y, x, y, x, y2) + graphics.move(x, y2);
                  }
                  areaPath += graphics.curve(x, y, x, y, x, areaBottomY) + graphics.line(segmentStartX, areaBottomY) + "z";
                  linePaths.push(linePath);
                  areaPaths.push(areaPath);
                  pathState = -1;
                }
              }
              break;
          }
        }
        pX = x;
        pY = y;
        break;
      }
      default: {
        const pathToPoint = (curve2, x2, y3) => {
          let path = "";
          switch (curve2) {
            case "stepline":
              path = graphics.line(x2, null, "H") + graphics.line(null, y3, "V");
              break;
            case "linestep":
              path = graphics.line(null, y3, "V") + graphics.line(x2, null, "H");
              break;
            case "straight":
              path = graphics.line(x2, y3);
              break;
          }
          return path;
        };
        if (series[i][j] === null) {
          pathState = 0;
        } else {
          switch (pathState) {
            case 0:
              segmentStartX = pX;
              if (isLowerRangeAreaPath) {
                linePath = graphics.move(pX, y2Arrj[j]) + graphics.line(pX, pY);
              } else {
                linePath = graphics.move(pX, pY);
              }
              areaPath = graphics.move(pX, pY);
              if (series[i][j + 1] === null || typeof series[i][j + 1] === "undefined") {
                linePaths.push(linePath);
                areaPaths.push(areaPath);
                break;
              }
              pathState = 1;
              if (j < series[i].length - 2) {
                const p = pathToPoint(curve, x, y);
                linePath += p;
                areaPath += p;
                break;
              }
            // falls through
            case 1:
              if (series[i][j + 1] === null) {
                if (isLowerRangeAreaPath) {
                  linePath += graphics.line(pX, y2);
                } else {
                  linePath += graphics.move(pX, pY);
                }
                areaPath += graphics.line(pX, areaBottomY) + graphics.line(segmentStartX, areaBottomY) + "z";
                linePaths.push(linePath);
                areaPaths.push(areaPath);
                pathState = -1;
              } else {
                const p = pathToPoint(curve, x, y);
                linePath += p;
                areaPath += p;
                if (j >= series[i].length - 2) {
                  if (isLowerRangeAreaPath) {
                    linePath += graphics.line(x, y2);
                  }
                  areaPath += graphics.line(x, areaBottomY) + graphics.line(segmentStartX, areaBottomY) + "z";
                  linePaths.push(linePath);
                  areaPaths.push(areaPath);
                  pathState = -1;
                }
              }
              break;
          }
        }
        pX = x;
        pY = y;
        break;
      }
    }
    return {
      linePaths,
      areaPaths,
      pX,
      pY,
      pathState,
      segmentStartX,
      linePath,
      areaPath
    };
  }
  /**
   * @param {any[]} series
   * @param {any} pointsPos
   * @param {number} i
   * @param {number} j
   * @param {number} realIndex
   */
  handleNullDataPoints(series, pointsPos, i, j, realIndex) {
    const w = this.w;
    if (series[i][j] === null && w.config.markers.showNullDataPoints || series[i].length === 1) {
      let pSize = this.strokeWidth - w.config.markers.strokeWidth / 2;
      if (!(pSize > 0)) {
        pSize = 0;
      }
      const elPointsWrap = this.markers.plotChartMarkers({
        pointsPos,
        seriesIndex: realIndex,
        j: j + 1,
        pSize,
        alwaysDrawMarker: true
      });
      if (elPointsWrap !== null) {
        this.elPointsMain.add(elPointsWrap);
      }
    }
  }
}
class CircularChartsHelpers {
  /**
   * @param {import('../../../types/internal').ChartStateW} w
   */
  constructor(w) {
    this.w = w;
  }
  /**
   * @param {number} x
   * @param {number} y
   * @param {number} i
   * @param {string | number} text
   */
  drawYAxisTexts(x, y, i, text) {
    const w = this.w;
    const yaxisConfig = w.config.yaxis[0];
    const formatter = w.formatters.yLabelFormatters[0];
    const graphics = new Graphics(this.w);
    const yaxisLabel = graphics.drawText({
      x: x + yaxisConfig.labels.offsetX,
      y: y + yaxisConfig.labels.offsetY,
      text: formatter(text, i),
      textAnchor: "middle",
      fontSize: yaxisConfig.labels.style.fontSize,
      fontFamily: yaxisConfig.labels.style.fontFamily,
      foreColor: Array.isArray(yaxisConfig.labels.style.colors) ? yaxisConfig.labels.style.colors[i] : yaxisConfig.labels.style.colors
    });
    return yaxisLabel;
  }
}
class Pie {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.ctx = ctx;
    this.w = w;
    this.chartType = this.w.config.chart.type;
    this.initialAnim = this.w.config.chart.animations.enabled;
    this.dynamicAnim = this.initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled;
    this.animBeginArr = [0];
    this.animDur = 0;
    this.donutDataLabels = this.w.config.plotOptions.pie.donut.labels;
    this.lineColorArr = w.globals.stroke.colors !== void 0 ? w.globals.stroke.colors : w.globals.colors;
    this.defaultSize = Math.min(w.layout.gridWidth, w.layout.gridHeight);
    this.centerY = this.defaultSize / 2;
    this.centerX = w.layout.gridWidth / 2;
    if (w.config.chart.type === "radialBar") {
      this.fullAngle = 360;
    } else {
      this.fullAngle = Math.abs(
        w.config.plotOptions.pie.endAngle - w.config.plotOptions.pie.startAngle
      );
    }
    this.initialAngle = w.config.plotOptions.pie.startAngle % this.fullAngle;
    w.globals.radialSize = this.defaultSize / 2.05 - w.config.stroke.width - (!w.config.chart.sparkline.enabled ? w.config.chart.dropShadow.blur : 0);
    this.donutSize = w.globals.radialSize * parseInt(w.config.plotOptions.pie.donut.size, 10) / 100;
    const scaleSize = w.config.plotOptions.pie.customScale;
    const halfW = w.layout.gridWidth / 2;
    const halfH = w.layout.gridHeight / 2;
    this.translateX = halfW - halfW * scaleSize;
    this.translateY = halfH - halfH * scaleSize;
    this.dataLabelsGroup = new Graphics(this.w).group({
      class: "apexcharts-datalabels-group",
      transform: `translate(${this.translateX}, ${this.translateY}) scale(${scaleSize})`
    });
    this.maxY = 0;
    this.sliceLabels = [];
    this.sliceSizes = [];
    this.prevSectorAngleArr = [];
  }
  /**
   * @param {any[]} series
   */
  draw(series) {
    const self = this;
    const w = this.w;
    const graphics = new Graphics(this.w);
    const elPie = graphics.group({
      class: "apexcharts-pie"
    });
    if (w.globals.noData) return elPie;
    let total = 0;
    for (let k = 0; k < series.length; k++) {
      total += Utils$1.negToZero(series[k]);
    }
    const sectorAngleArr = [];
    const elSeries = graphics.group();
    if (total === 0) {
      total = 1e-5;
    }
    series.forEach((m) => {
      this.maxY = Math.max(this.maxY, m);
    });
    if (w.config.yaxis[0].max) {
      this.maxY = w.config.yaxis[0].max;
    }
    if (w.config.grid.position === "back" && this.chartType === "polarArea") {
      this.drawPolarElements(elPie);
    }
    for (let i = 0; i < series.length; i++) {
      const angle = this.fullAngle * Utils$1.negToZero(series[i]) / total;
      sectorAngleArr.push(angle);
      if (this.chartType === "polarArea") {
        sectorAngleArr[i] = this.fullAngle / series.length;
        this.sliceSizes.push(w.globals.radialSize * series[i] / this.maxY);
      } else {
        this.sliceSizes.push(w.globals.radialSize);
      }
    }
    if (w.globals.dataChanged) {
      let prevTotal = 0;
      for (let k = 0; k < w.globals.previousPaths.length; k++) {
        prevTotal += Utils$1.negToZero(w.globals.previousPaths[k]);
      }
      let previousAngle;
      for (let i = 0; i < w.globals.previousPaths.length; i++) {
        previousAngle = this.fullAngle * Utils$1.negToZero(w.globals.previousPaths[i]) / prevTotal;
        this.prevSectorAngleArr.push(previousAngle);
      }
    }
    if (this.donutSize < 0) {
      this.donutSize = 0;
    }
    if (this.chartType === "donut") {
      const circle = graphics.drawCircle(this.donutSize);
      circle.attr({
        cx: this.centerX,
        cy: this.centerY,
        fill: w.config.plotOptions.pie.donut.background ? w.config.plotOptions.pie.donut.background : "transparent"
      });
      elSeries.add(circle);
    }
    const elG = self.drawArcs(sectorAngleArr, series);
    this.sliceLabels.forEach((s) => {
      elG.add(s);
    });
    elSeries.attr({
      transform: `translate(${this.translateX}, ${this.translateY}) scale(${w.config.plotOptions.pie.customScale})`
    });
    elSeries.add(elG);
    elPie.add(elSeries);
    if (this.donutDataLabels.show) {
      const dataLabels = this.renderInnerDataLabels(
        this.dataLabelsGroup,
        this.donutDataLabels,
        {
          hollowSize: this.donutSize,
          centerX: this.centerX,
          centerY: this.centerY,
          opacity: this.donutDataLabels.show
        }
      );
      elPie.add(dataLabels);
    }
    if (w.config.grid.position === "front" && this.chartType === "polarArea") {
      this.drawPolarElements(elPie);
    }
    return elPie;
  }
  // core function for drawing pie arcs
  /**
   * @param {any[]} sectorAngleArr
   * @param {any[]} series
   */
  drawArcs(sectorAngleArr, series) {
    const w = this.w;
    const filters = new Filters(this.w);
    const graphics = new Graphics(this.w);
    const fill = new Fill(this.w);
    const g = graphics.group({
      class: "apexcharts-slices"
    });
    let startAngle = this.initialAngle;
    let prevStartAngle = this.initialAngle;
    let endAngle = this.initialAngle;
    let prevEndAngle = this.initialAngle;
    this.strokeWidth = w.config.stroke.show ? w.config.stroke.width : 0;
    for (let i = 0; i < sectorAngleArr.length; i++) {
      const elPieArc = graphics.group({
        class: `apexcharts-series apexcharts-pie-series`,
        seriesName: Utils$1.escapeString(w.seriesData.seriesNames[i]),
        rel: i + 1,
        "data:realIndex": i
      });
      g.add(elPieArc);
      startAngle = endAngle;
      prevStartAngle = prevEndAngle;
      endAngle = startAngle + sectorAngleArr[i];
      prevEndAngle = prevStartAngle + this.prevSectorAngleArr[i];
      const angle = endAngle < startAngle ? this.fullAngle + endAngle - startAngle : endAngle - startAngle;
      const pathFill = fill.fillPath({
        seriesNumber: i,
        size: this.sliceSizes[i],
        value: series[i]
      });
      const path = this.getChangedPath(prevStartAngle, prevEndAngle);
      const elPath = graphics.drawPath({
        d: path,
        stroke: Array.isArray(this.lineColorArr) ? this.lineColorArr[i] : this.lineColorArr,
        strokeWidth: 0,
        fill: pathFill,
        fillOpacity: w.config.fill.opacity,
        classes: `apexcharts-pie-area apexcharts-${this.chartType.toLowerCase()}-slice-${i}`
      });
      elPath.attr({
        index: 0,
        j: i
      });
      filters.setSelectionFilter(elPath, 0, i);
      if (w.config.chart.dropShadow.enabled) {
        const shadow = w.config.chart.dropShadow;
        filters.dropShadow(elPath, shadow, i);
      }
      this.addListeners(elPath, this.donutDataLabels);
      let labelPosition = {
        x: 0,
        y: 0
      };
      const midAngle = (startAngle + angle / 2) % this.fullAngle;
      let arcCenter = { x: this.centerX, y: this.centerY };
      if (this.chartType === "pie" || this.chartType === "polarArea") {
        labelPosition = Utils$1.polarToCartesian(
          this.centerX,
          this.centerY,
          w.globals.radialSize / 1.25 + w.config.plotOptions.pie.dataLabels.offset,
          midAngle
        );
        arcCenter = Utils$1.polarToCartesian(
          this.centerX,
          this.centerY,
          w.globals.radialSize / 2,
          midAngle
        );
      } else if (this.chartType === "donut") {
        labelPosition = Utils$1.polarToCartesian(
          this.centerX,
          this.centerY,
          (w.globals.radialSize + this.donutSize) / 2 + w.config.plotOptions.pie.dataLabels.offset,
          midAngle
        );
        arcCenter = Utils$1.polarToCartesian(
          this.centerX,
          this.centerY,
          (w.globals.radialSize + this.donutSize) / 2,
          midAngle
        );
      }
      Graphics.setAttrs(elPath.node, {
        "data:angle": angle,
        "data:startAngle": startAngle,
        "data:strokeWidth": this.strokeWidth,
        "data:value": series[i],
        "data:cx": arcCenter.x,
        "data:cy": arcCenter.y
      });
      elPieArc.add(elPath);
      let dur = 0;
      if (this.initialAnim && !w.globals.resized && !w.globals.dataChanged) {
        dur = angle / this.fullAngle * w.config.chart.animations.speed;
        if (dur === 0) dur = 1;
        this.animDur = dur + this.animDur;
        this.animBeginArr.push(this.animDur);
      } else {
        this.animBeginArr.push(0);
      }
      if (this.dynamicAnim && w.globals.dataChanged) {
        this.animatePaths(elPath, {
          size: this.sliceSizes[i],
          endAngle,
          startAngle,
          prevStartAngle,
          prevEndAngle,
          animateStartingPos: true,
          i,
          animBeginArr: this.animBeginArr,
          shouldSetPrevPaths: true,
          dur: w.config.chart.animations.dynamicAnimation.speed
        });
      } else {
        this.animatePaths(elPath, {
          size: this.sliceSizes[i],
          endAngle,
          startAngle,
          i,
          totalItems: sectorAngleArr.length - 1,
          animBeginArr: this.animBeginArr,
          dur
        });
      }
      if (w.config.plotOptions.pie.expandOnClick && this.chartType !== "polarArea") {
        elPath.node.addEventListener("mouseup", this.pieClicked.bind(this, i));
      }
      if (typeof w.interact.selectedDataPoints[0] !== "undefined" && w.interact.selectedDataPoints[0].indexOf(i) > -1) {
        this.pieClicked(i);
      }
      if (w.config.dataLabels.enabled) {
        const xPos = labelPosition.x;
        const yPos = labelPosition.y;
        let text = 100 * angle / this.fullAngle + "%";
        if (angle !== 0 && w.config.plotOptions.pie.dataLabels.minAngleToShowLabel < sectorAngleArr[i]) {
          const formatter = w.config.dataLabels.formatter;
          if (formatter !== void 0) {
            text = formatter(w.globals.seriesPercent[i][0], {
              seriesIndex: i,
              w
            });
          }
          const foreColor = w.globals.dataLabels.style.colors[i];
          const elPieLabelWrap = graphics.group({
            class: `apexcharts-datalabels`
          });
          const elPieLabel = graphics.drawText({
            x: xPos,
            y: yPos,
            text,
            textAnchor: "middle",
            fontSize: w.config.dataLabels.style.fontSize,
            fontFamily: w.config.dataLabels.style.fontFamily,
            fontWeight: w.config.dataLabels.style.fontWeight,
            foreColor
          });
          elPieLabelWrap.add(elPieLabel);
          if (w.config.dataLabels.dropShadow.enabled) {
            const textShadow = w.config.dataLabels.dropShadow;
            filters.dropShadow(elPieLabel, textShadow);
          }
          elPieLabel.node.classList.add("apexcharts-pie-label");
          if (w.config.chart.animations.animate && w.globals.resized === false) {
            elPieLabel.node.classList.add("apexcharts-pie-label-delay");
            elPieLabel.node.style.animationDelay = w.config.chart.animations.speed / 940 + "s";
          }
          this.sliceLabels.push(elPieLabelWrap);
        }
      }
    }
    return g;
  }
  /**
   * @param {any} elPath
   * @param {Record<string, any>} dataLabels
   */
  addListeners(elPath, dataLabels) {
    const graphics = new Graphics(this.w);
    elPath.node.addEventListener(
      "mouseenter",
      graphics.pathMouseEnter.bind(this, elPath)
    );
    elPath.node.addEventListener(
      "mouseleave",
      graphics.pathMouseLeave.bind(this, elPath)
    );
    elPath.node.addEventListener(
      "mouseleave",
      this.revertDataLabelsInner.bind(this)
    );
    elPath.node.addEventListener(
      "mousedown",
      graphics.pathMouseDown.bind(this, elPath)
    );
    if (!this.donutDataLabels.total.showAlways) {
      elPath.node.addEventListener(
        "mouseenter",
        this.printDataLabelsInner.bind(this, elPath.node, dataLabels)
      );
      elPath.node.addEventListener(
        "mousedown",
        this.printDataLabelsInner.bind(this, elPath.node, dataLabels)
      );
    }
  }
  // This function can be used for other circle charts too
  /**
   * @param {any} el
   * @param {Record<string, any>} opts
   */
  animatePaths(el, opts) {
    const w = this.w;
    const me = this;
    let angle = opts.endAngle < opts.startAngle ? this.fullAngle + opts.endAngle - opts.startAngle : opts.endAngle - opts.startAngle;
    let prevAngle = angle;
    let fromStartAngle = opts.startAngle;
    const toStartAngle = opts.startAngle;
    if (opts.prevStartAngle !== void 0 && opts.prevEndAngle !== void 0) {
      fromStartAngle = opts.prevEndAngle;
      prevAngle = opts.prevEndAngle < opts.prevStartAngle ? this.fullAngle + opts.prevEndAngle - opts.prevStartAngle : opts.prevEndAngle - opts.prevStartAngle;
    }
    if (opts.i === w.config.series.length - 1) {
      if (angle + toStartAngle > this.fullAngle) {
        opts.endAngle = opts.endAngle - (angle + toStartAngle);
      } else if (angle + toStartAngle < this.fullAngle) {
        opts.endAngle = opts.endAngle + (this.fullAngle - (angle + toStartAngle));
      }
    }
    if (angle === this.fullAngle) angle = this.fullAngle - 0.01;
    me.animateArc(el, fromStartAngle, toStartAngle, angle, prevAngle, opts);
  }
  /**
   * @param {any} el
   * @param {number} fromStartAngle
   * @param {number} toStartAngle
   * @param {number} angle
   * @param {number} prevAngle
   * @param {Record<string, any>} opts
   */
  animateArc(el, fromStartAngle, toStartAngle, angle, prevAngle, opts) {
    const me = this;
    const w = this.w;
    const animations = new Animations(this.w);
    const size = opts.size;
    let path;
    if (isNaN(fromStartAngle) || isNaN(prevAngle)) {
      fromStartAngle = toStartAngle;
      prevAngle = angle;
      opts.dur = 0;
    }
    let currAngle = angle;
    let startAngle = toStartAngle;
    const fromAngle = fromStartAngle < toStartAngle ? this.fullAngle + fromStartAngle - toStartAngle : fromStartAngle - toStartAngle;
    if (w.globals.dataChanged && opts.shouldSetPrevPaths) {
      if (opts.prevEndAngle) {
        path = me.getPiePath({
          me,
          startAngle: opts.prevStartAngle,
          angle: opts.prevEndAngle < opts.prevStartAngle ? this.fullAngle + opts.prevEndAngle - opts.prevStartAngle : opts.prevEndAngle - opts.prevStartAngle,
          size
        });
        el.attr({ d: path });
      }
    }
    if (opts.dur !== 0) {
      el.animate(opts.dur, opts.animBeginArr[opts.i]).after(
        /** @this {any} */
        function() {
          if (me.chartType === "pie" || me.chartType === "donut" || me.chartType === "polarArea") {
            this.animate(
              w.config.chart.animations.dynamicAnimation.speed
            ).attr({
              "stroke-width": me.strokeWidth
            });
          }
          if (opts.i === w.config.series.length - 1) {
            animations.animationCompleted(el);
          }
        }
      ).during((pos) => {
        currAngle = fromAngle + (angle - fromAngle) * pos;
        if (opts.animateStartingPos) {
          currAngle = prevAngle + (angle - prevAngle) * pos;
          startAngle = fromStartAngle - prevAngle + (toStartAngle - (fromStartAngle - prevAngle)) * pos;
        }
        path = me.getPiePath({
          me,
          startAngle,
          angle: currAngle,
          size
        });
        el.node.setAttribute("data:pathOrig", path);
        el.attr({
          d: path
        });
      });
    } else {
      path = me.getPiePath({
        me,
        startAngle,
        angle,
        size
      });
      if (!opts.isTrack) {
        w.globals.animationEnded = true;
      }
      el.node.setAttribute("data:pathOrig", path);
      el.attr({
        d: path,
        "stroke-width": me.strokeWidth
      });
    }
  }
  /**
   * @param {number} i
   */
  pieClicked(i) {
    const w = this.w;
    const me = this;
    const size = me.sliceSizes[i] + (w.config.plotOptions.pie.expandOnClick ? 4 : 0);
    const elPath = w.dom.Paper.findOne(
      `.apexcharts-${me.chartType.toLowerCase()}-slice-${i}`
    );
    if (elPath.attr("data:pieClicked") === "true") {
      elPath.attr({
        "data:pieClicked": "false"
      });
      this.revertDataLabelsInner();
      const origPath = elPath.attr("data:pathOrig");
      elPath.attr({
        d: origPath
      });
      return;
    } else {
      const allEls = w.dom.baseEl.getElementsByClassName("apexcharts-pie-area");
      Array.prototype.forEach.call(allEls, (pieSlice) => {
        pieSlice.setAttribute("data:pieClicked", "false");
        const origPath = pieSlice.getAttribute("data:pathOrig");
        if (origPath) {
          pieSlice.setAttribute("d", origPath);
        }
      });
      w.interact.capturedDataPointIndex = i;
      elPath.attr("data:pieClicked", "true");
    }
    const startAngle = parseInt(elPath.attr("data:startAngle"), 10);
    const angle = parseInt(elPath.attr("data:angle"), 10);
    const path = me.getPiePath({
      me,
      startAngle,
      angle,
      size
    });
    if (angle === 360) return;
    elPath.plot(path);
  }
  /**
   * @param {number} prevStartAngle
   * @param {number} prevEndAngle
   */
  getChangedPath(prevStartAngle, prevEndAngle) {
    let path = "";
    if (this.dynamicAnim && this.w.globals.dataChanged) {
      path = this.getPiePath({
        me: this,
        startAngle: prevStartAngle,
        angle: prevEndAngle - prevStartAngle,
        // @ts-ignore — size is set dynamically during draw()
        size: this.size
      });
    }
    return path;
  }
  /** @param {{me: any, startAngle: any, angle: any, size: any}} opts */
  getPiePath({ me, startAngle, angle, size }) {
    let path;
    const graphics = new Graphics(this.w);
    const startDeg = startAngle;
    const startRadians = Math.PI * (startDeg - 90) / 180;
    let endDeg = angle + startAngle;
    if (Math.ceil(endDeg) >= this.fullAngle + this.w.config.plotOptions.pie.startAngle % this.fullAngle) {
      endDeg = this.fullAngle + this.w.config.plotOptions.pie.startAngle % this.fullAngle - 0.01;
    }
    if (Math.ceil(endDeg) > this.fullAngle) endDeg -= this.fullAngle;
    const endRadians = Math.PI * (endDeg - 90) / 180;
    const x1 = me.centerX + size * Math.cos(startRadians);
    const y1 = me.centerY + size * Math.sin(startRadians);
    const x2 = me.centerX + size * Math.cos(endRadians);
    const y2 = me.centerY + size * Math.sin(endRadians);
    const startInner = Utils$1.polarToCartesian(
      me.centerX,
      me.centerY,
      me.donutSize,
      endDeg
    );
    const endInner = Utils$1.polarToCartesian(
      me.centerX,
      me.centerY,
      me.donutSize,
      startDeg
    );
    const largeArc = angle > 180 ? 1 : 0;
    const pathBeginning = ["M", x1, y1, "A", size, size, 0, largeArc, 1, x2, y2];
    if (me.chartType === "donut") {
      path = [
        ...pathBeginning,
        "L",
        startInner.x,
        startInner.y,
        "A",
        me.donutSize,
        me.donutSize,
        0,
        largeArc,
        0,
        endInner.x,
        endInner.y,
        "L",
        x1,
        y1,
        "z"
      ].join(" ");
    } else if (me.chartType === "pie" || me.chartType === "polarArea") {
      path = [...pathBeginning, "L", me.centerX, me.centerY, "L", x1, y1].join(
        " "
      );
    } else {
      path = [...pathBeginning].join(" ");
    }
    return graphics.roundPathCorners(path, this.strokeWidth * 2);
  }
  /**
   * @param {any} parent
   */
  drawPolarElements(parent) {
    const w = this.w;
    const scale = new Scales(this.w);
    const graphics = new Graphics(this.w);
    const helpers = new CircularChartsHelpers(this.w);
    const gCircles = graphics.group();
    const gYAxis = graphics.group();
    const yScale = scale.niceScale(0, Math.ceil(this.maxY), 0);
    const yTexts = yScale.result.reverse();
    const len = yScale.result.length;
    this.maxY = yScale.niceMax;
    let circleSize = w.globals.radialSize;
    const diff = circleSize / (len - 1);
    for (let i = 0; i < len - 1; i++) {
      const circle = graphics.drawCircle(circleSize);
      circle.attr({
        cx: this.centerX,
        cy: this.centerY,
        fill: "none",
        "stroke-width": w.config.plotOptions.polarArea.rings.strokeWidth,
        stroke: w.config.plotOptions.polarArea.rings.strokeColor
      });
      if (w.config.yaxis[0].show) {
        const yLabel = helpers.drawYAxisTexts(
          this.centerX,
          this.centerY - circleSize + parseInt(w.config.yaxis[0].labels.style.fontSize, 10) / 2,
          i,
          yTexts[i]
        );
        gYAxis.add(yLabel);
      }
      gCircles.add(circle);
      circleSize = circleSize - diff;
    }
    this.drawSpokes(parent);
    parent.add(gCircles);
    parent.add(gYAxis);
  }
  /**
   * @param {any} dataLabelsGroup
   * @param {Record<string, any>} dataLabelsConfig
   * @param {Record<string, any>} opts
   */
  renderInnerDataLabels(dataLabelsGroup, dataLabelsConfig, opts) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const showTotal = dataLabelsConfig.total.show;
    dataLabelsGroup.node.innerHTML = "";
    dataLabelsGroup.node.style.opacity = opts.opacity;
    const x = opts.centerX;
    const y = !this.donutDataLabels.total.label ? opts.centerY - opts.centerY / 6 : opts.centerY;
    let labelColor, valueColor;
    if (dataLabelsConfig.name.color === void 0) {
      labelColor = w.globals.colors[0];
    } else {
      labelColor = dataLabelsConfig.name.color;
    }
    let labelFontSize = dataLabelsConfig.name.fontSize;
    let labelFontFamily = dataLabelsConfig.name.fontFamily;
    let labelFontWeight = dataLabelsConfig.name.fontWeight;
    if (dataLabelsConfig.value.color === void 0) {
      valueColor = w.config.chart.foreColor;
    } else {
      valueColor = dataLabelsConfig.value.color;
    }
    const lbFormatter = dataLabelsConfig.value.formatter;
    let val = "";
    let name2 = "";
    if (showTotal) {
      labelColor = dataLabelsConfig.total.color;
      labelFontSize = dataLabelsConfig.total.fontSize;
      labelFontFamily = dataLabelsConfig.total.fontFamily;
      labelFontWeight = dataLabelsConfig.total.fontWeight;
      name2 = !this.donutDataLabels.total.label ? "" : dataLabelsConfig.total.label;
      val = dataLabelsConfig.total.formatter(w);
    } else {
      if (w.seriesData.series.length === 1) {
        val = lbFormatter(w.seriesData.series[0], w);
        name2 = w.seriesData.seriesNames[0];
      }
    }
    if (name2) {
      name2 = dataLabelsConfig.name.formatter(
        name2,
        dataLabelsConfig.total.show,
        w
      );
    }
    if (dataLabelsConfig.name.show) {
      const elLabel = graphics.drawText({
        x,
        y: y + parseFloat(dataLabelsConfig.name.offsetY),
        text: name2,
        textAnchor: "middle",
        foreColor: labelColor,
        fontSize: labelFontSize,
        fontWeight: labelFontWeight,
        fontFamily: labelFontFamily
      });
      elLabel.node.classList.add("apexcharts-datalabel-label");
      dataLabelsGroup.add(elLabel);
    }
    if (dataLabelsConfig.value.show) {
      const valOffset = dataLabelsConfig.name.show ? parseFloat(dataLabelsConfig.value.offsetY) + 16 : dataLabelsConfig.value.offsetY;
      const elValue = graphics.drawText({
        x,
        y: y + valOffset,
        text: val,
        textAnchor: "middle",
        foreColor: valueColor,
        fontWeight: dataLabelsConfig.value.fontWeight,
        fontSize: dataLabelsConfig.value.fontSize,
        fontFamily: dataLabelsConfig.value.fontFamily
      });
      elValue.node.classList.add("apexcharts-datalabel-value");
      dataLabelsGroup.add(elValue);
    }
    return dataLabelsGroup;
  }
  /**
   *
   * @param {string} name - The name of the series
   * @param {string} val - The value of that series
   * @param {any} el - Optional el (indicates which series was hovered/clicked). If this param is not present, means we need to show total
   * @param {Record<string, any>} labelsConfig
   */
  printInnerLabels(labelsConfig, name2, val, el) {
    const w = this.w;
    let labelColor;
    if (el) {
      if (labelsConfig.name.color === void 0) {
        labelColor = w.globals.colors[parseInt(el.parentNode.getAttribute("rel"), 10) - 1];
      } else {
        labelColor = labelsConfig.name.color;
      }
    } else {
      if (w.seriesData.series.length > 1 && labelsConfig.total.show) {
        labelColor = labelsConfig.total.color;
      }
    }
    const elLabel = w.dom.baseEl.querySelector(".apexcharts-datalabel-label");
    const elValue = w.dom.baseEl.querySelector(".apexcharts-datalabel-value");
    const lbFormatter = labelsConfig.value.formatter;
    val = lbFormatter(val, w);
    if (!el && typeof labelsConfig.total.formatter === "function") {
      val = labelsConfig.total.formatter(w);
    }
    const isTotal = name2 === labelsConfig.total.label;
    name2 = !this.donutDataLabels.total.label ? "" : labelsConfig.name.formatter(name2, isTotal, w);
    if (elLabel !== null) {
      elLabel.textContent = name2;
    }
    if (elValue !== null) {
      elValue.textContent = val;
    }
    if (elLabel !== null) {
      const elLabelEl = (
        /** @type {HTMLElement} */
        elLabel
      );
      elLabelEl.style.fill = labelColor;
    }
  }
  /**
   * @param {any} el
   * @param {Record<string, any>} dataLabelsConfig
   */
  printDataLabelsInner(el, dataLabelsConfig) {
    const w = this.w;
    const val = el.getAttribute("data:value");
    const name2 = w.seriesData.seriesNames[parseInt(el.parentNode.getAttribute("rel"), 10) - 1];
    if (w.seriesData.series.length > 1) {
      this.printInnerLabels(dataLabelsConfig, name2, val, el);
    }
    const dataLabelsGroup = w.dom.baseEl.querySelector(
      ".apexcharts-datalabels-group"
    );
    if (dataLabelsGroup !== null) {
      const dataLabelsGroupEl = (
        /** @type {HTMLElement} */
        dataLabelsGroup
      );
      dataLabelsGroupEl.style.opacity = "1";
    }
  }
  /**
   * @param {any} parent
   */
  drawSpokes(parent) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const spokeConfig = w.config.plotOptions.polarArea.spokes;
    if (spokeConfig.strokeWidth === 0) return;
    const spokes = [];
    const angleDivision = 360 / w.seriesData.series.length;
    for (let i = 0; i < w.seriesData.series.length; i++) {
      spokes.push(
        Utils$1.polarToCartesian(
          this.centerX,
          this.centerY,
          w.globals.radialSize,
          w.config.plotOptions.pie.startAngle + angleDivision * i
        )
      );
    }
    spokes.forEach((p, i) => {
      const line = graphics.drawLine(
        p.x,
        p.y,
        this.centerX,
        this.centerY,
        Array.isArray(spokeConfig.connectorColors) ? spokeConfig.connectorColors[i] : spokeConfig.connectorColors
      );
      parent.add(line);
    });
  }
  revertDataLabelsInner() {
    const w = this.w;
    if (this.donutDataLabels.show) {
      const dataLabelsGroup = w.dom.Paper.findOne(
        `.apexcharts-datalabels-group`
      );
      const dataLabels = this.renderInnerDataLabels(
        dataLabelsGroup,
        this.donutDataLabels,
        {
          hollowSize: this.donutSize,
          centerX: this.centerX,
          centerY: this.centerY,
          opacity: this.donutDataLabels.show
        }
      );
      const elPie = w.dom.Paper.findOne(
        ".apexcharts-radialbar, .apexcharts-pie"
      );
      elPie.add(dataLabels);
    }
  }
}
class Radar {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.ctx = ctx;
    this.w = w;
    this.chartType = this.w.config.chart.type;
    this.initialAnim = this.w.config.chart.animations.enabled;
    this.dynamicAnim = this.initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled;
    this.animDur = 0;
    this.graphics = new Graphics(this.w);
    this.lineColorArr = w.globals.stroke.colors !== void 0 ? w.globals.stroke.colors : w.globals.colors;
    this.defaultSize = w.globals.svgHeight < w.globals.svgWidth ? w.layout.gridHeight : w.layout.gridWidth;
    this.isLog = w.config.yaxis[0].logarithmic;
    this.logBase = w.config.yaxis[0].logBase;
    this.coreUtils = new CoreUtils(this.w);
    this.maxValue = this.isLog ? this.coreUtils.getLogVal(this.logBase, w.globals.maxY, 0) : w.globals.maxY;
    this.minValue = this.isLog ? this.coreUtils.getLogVal(this.logBase, this.w.globals.minY, 0) : w.globals.minY;
    this.polygons = w.config.plotOptions.radar.polygons;
    this.strokeWidth = w.config.stroke.show ? w.config.stroke.width : 0;
    this.size = this.defaultSize / 2.1 - this.strokeWidth - w.config.chart.dropShadow.blur;
    if (w.config.xaxis.labels.show) {
      this.size = this.size - w.layout.xAxisLabelsWidth / 1.75;
    }
    if (w.config.plotOptions.radar.size !== void 0) {
      this.size = w.config.plotOptions.radar.size;
    }
    this.dataRadiusOfPercent = /** @type {any} */
    [];
    this.dataRadius = /** @type {any} */
    [];
    this.angleArr = /** @type {any} */
    [];
    this.dataPointsLen = 0;
    this.disAngle = 0;
    this.yaxisLabelsTextsPos = [];
  }
  /**
   * @param {any[]} series
   */
  draw(series) {
    const w = this.w;
    const fill = new Fill(this.w);
    const allSeries = [];
    const dataLabels = new DataLabels(this.w, this.ctx);
    if (series.length) {
      this.dataPointsLen = series[w.globals.maxValsInArrayIndex].length;
    }
    this.disAngle = Math.PI * 2 / this.dataPointsLen;
    const halfW = w.layout.gridWidth / 2;
    const halfH = w.layout.gridHeight / 2;
    const translateX = halfW + w.config.plotOptions.radar.offsetX;
    const translateY = halfH + w.config.plotOptions.radar.offsetY;
    const ret = this.graphics.group({
      class: "apexcharts-radar-series apexcharts-plot-series",
      transform: `translate(${translateX || 0}, ${translateY || 0})`
    });
    let dataPointsPos = [];
    let elPointsMain = null;
    let elDataPointsMain = null;
    this.yaxisLabels = this.graphics.group({
      class: "apexcharts-yaxis"
    });
    series.forEach((s, i) => {
      const longestSeries = s.length === w.globals.dataPoints;
      const elSeries = this.graphics.group().attr({
        class: `apexcharts-series`,
        "data:longestSeries": longestSeries,
        seriesName: Utils$1.escapeString(w.seriesData.seriesNames[i]),
        rel: i + 1,
        "data:realIndex": i
      });
      this.dataRadiusOfPercent[i] = [];
      this.dataRadius[i] = [];
      this.angleArr[i] = [];
      s.forEach((dv, j) => {
        const range = Math.abs(this.maxValue - this.minValue);
        dv = dv - this.minValue;
        if (this.isLog) {
          dv = this.coreUtils.getLogVal(this.logBase, dv, 0);
        }
        this.dataRadiusOfPercent[i][j] = dv / range;
        this.dataRadius[i][j] = this.dataRadiusOfPercent[i][j] * this.size;
        this.angleArr[i][j] = j * this.disAngle;
      });
      dataPointsPos = this.getDataPointsPos(
        this.dataRadius[i],
        this.angleArr[i]
      );
      const paths = this.createPaths(dataPointsPos, {
        x: 0,
        y: 0
      });
      elPointsMain = this.graphics.group({
        class: "apexcharts-series-markers-wrap apexcharts-element-hidden"
      });
      elDataPointsMain = this.graphics.group({
        class: `apexcharts-datalabels`,
        "data:realIndex": i
      });
      w.globals.delayedElements.push({
        el: elPointsMain.node,
        index: i
      });
      const defaultRenderedPathOptions = {
        i,
        realIndex: i,
        animationDelay: i,
        initialSpeed: w.config.chart.animations.speed,
        dataChangeSpeed: w.config.chart.animations.dynamicAnimation.speed,
        className: `apexcharts-radar`,
        shouldClipToGrid: false,
        bindEventsOnPaths: false,
        stroke: w.globals.stroke.colors[i],
        strokeLineCap: w.config.stroke.lineCap
      };
      let pathFrom = null;
      if (w.globals.previousPaths.length > 0) {
        pathFrom = this.getPreviousPath(i);
      }
      for (let p = 0; p < paths.linePathsTo.length; p++) {
        const renderedLinePath = this.graphics.renderPaths(__spreadProps(__spreadValues({}, defaultRenderedPathOptions), {
          pathFrom: pathFrom === null ? paths.linePathsFrom[p] : pathFrom,
          pathTo: paths.linePathsTo[p],
          strokeWidth: Array.isArray(this.strokeWidth) ? this.strokeWidth[i] : this.strokeWidth,
          fill: "none",
          drawShadow: false
        }));
        elSeries.add(renderedLinePath);
        const pathFill = fill.fillPath({
          seriesNumber: i
        });
        const renderedAreaPath = this.graphics.renderPaths(__spreadProps(__spreadValues({}, defaultRenderedPathOptions), {
          pathFrom: pathFrom === null ? paths.areaPathsFrom[p] : pathFrom,
          pathTo: paths.areaPathsTo[p],
          strokeWidth: 0,
          fill: pathFill,
          drawShadow: false
        }));
        if (w.config.chart.dropShadow.enabled) {
          const filters = new Filters(this.w);
          const shadow = w.config.chart.dropShadow;
          filters.dropShadow(
            renderedAreaPath,
            Object.assign({}, shadow, { noUserSpaceOnUse: true }),
            i
          );
        }
        elSeries.add(renderedAreaPath);
      }
      s.forEach((sj, j) => {
        const markers = new Markers(this.w, this.ctx);
        const opts = markers.getMarkerConfig({
          cssClass: "apexcharts-marker",
          seriesIndex: i,
          dataPointIndex: j
        });
        const point = this.graphics.drawMarker(
          dataPointsPos[j].x,
          dataPointsPos[j].y,
          opts
        );
        point.attr("rel", j);
        point.attr("j", j);
        point.attr("index", i);
        point.node.setAttribute("default-marker-size", opts.pSize);
        const elPointsWrap = this.graphics.group({
          class: "apexcharts-series-markers"
        });
        if (elPointsWrap) {
          elPointsWrap.add(point);
        }
        elPointsMain.add(elPointsWrap);
        elSeries.add(elPointsMain);
        const dataLabelsConfig = w.config.dataLabels;
        if (dataLabelsConfig.enabled) {
          const text = dataLabelsConfig.formatter(w.seriesData.series[i][j], {
            seriesIndex: i,
            dataPointIndex: j,
            w
          });
          dataLabels.plotDataLabelsText({
            x: dataPointsPos[j].x,
            y: dataPointsPos[j].y,
            text,
            textAnchor: "middle",
            i,
            j: i,
            parent: elDataPointsMain,
            offsetCorrection: false,
            dataLabelsConfig: __spreadValues({}, dataLabelsConfig)
          });
        }
        elSeries.add(elDataPointsMain);
      });
      allSeries.push(elSeries);
    });
    this.drawPolygons({
      parent: ret
    });
    if (w.config.xaxis.labels.show) {
      const xaxisTexts = this.drawXAxisTexts();
      ret.add(xaxisTexts);
    }
    allSeries.forEach((elS) => {
      ret.add(elS);
    });
    ret.add(this.yaxisLabels);
    return ret;
  }
  /**
   * @param {Record<string, any>} opts
   */
  drawPolygons(opts) {
    const w = this.w;
    const { parent } = opts;
    const helpers = new CircularChartsHelpers(this.w);
    const yaxisTexts = w.globals.yAxisScale[0].result.reverse();
    const layers = yaxisTexts.length;
    const radiusSizes = [];
    const layerDis = this.size / (layers - 1);
    for (let i = 0; i < layers; i++) {
      radiusSizes[i] = layerDis * i;
    }
    radiusSizes.reverse();
    const polygonStrings = [];
    const lines = [];
    radiusSizes.forEach((radiusSize, r) => {
      const polygon = Utils$1.getPolygonPos(radiusSize, this.dataPointsLen);
      let string = "";
      polygon.forEach((p, i) => {
        if (r === 0) {
          const line = this.graphics.drawLine(
            p.x,
            p.y,
            0,
            0,
            Array.isArray(this.polygons.connectorColors) ? this.polygons.connectorColors[i] : this.polygons.connectorColors
          );
          lines.push(line);
        }
        if (i === 0) {
          this.yaxisLabelsTextsPos.push({
            x: p.x,
            y: p.y
          });
        }
        string += p.x + "," + p.y + " ";
      });
      polygonStrings.push(string);
    });
    polygonStrings.forEach((p, i) => {
      const strokeColors = this.polygons.strokeColors;
      const strokeWidth = this.polygons.strokeWidth;
      const polygon = this.graphics.drawPolygon(
        p,
        Array.isArray(strokeColors) ? strokeColors[i] : strokeColors,
        Array.isArray(strokeWidth) ? strokeWidth[i] : strokeWidth,
        w.globals.radarPolygons.fill.colors[i]
      );
      parent.add(polygon);
    });
    lines.forEach((l) => {
      parent.add(l);
    });
    if (w.config.yaxis[0].show) {
      this.yaxisLabelsTextsPos.forEach(
        (p, i) => {
          const yText = helpers.drawYAxisTexts(p.x, p.y, i, yaxisTexts[i]);
          this.yaxisLabels.add(yText);
        }
      );
    }
  }
  drawXAxisTexts() {
    const w = this.w;
    const xaxisLabelsConfig = w.config.xaxis.labels;
    const elXAxisWrap = this.graphics.group({
      class: "apexcharts-xaxis"
    });
    const polygonPos = Utils$1.getPolygonPos(this.size, this.dataPointsLen);
    w.labelData.labels.forEach((label, i) => {
      const formatter = w.config.xaxis.labels.formatter;
      const dataLabels = new DataLabels(this.w, this.ctx);
      if (polygonPos[i]) {
        const textPos = this.getTextPos(polygonPos[i], this.size);
        const text = formatter(label, {
          seriesIndex: -1,
          dataPointIndex: i,
          w
        });
        const dataLabelText = dataLabels.plotDataLabelsText({
          x: textPos.newX,
          y: textPos.newY,
          text,
          textAnchor: textPos.textAnchor,
          i,
          j: i,
          parent: elXAxisWrap,
          className: "apexcharts-xaxis-label",
          color: Array.isArray(xaxisLabelsConfig.style.colors) && xaxisLabelsConfig.style.colors[i] ? xaxisLabelsConfig.style.colors[i] : "#a8a8a8",
          dataLabelsConfig: __spreadValues({
            textAnchor: textPos.textAnchor,
            dropShadow: { enabled: false }
          }, xaxisLabelsConfig),
          offsetCorrection: false
        });
        dataLabelText.on("click", (e) => {
          if (typeof w.config.chart.events.xAxisLabelClick === "function") {
            const opts = Object.assign({}, w, {
              labelIndex: i
            });
            w.config.chart.events.xAxisLabelClick(e, this.ctx, opts);
          }
        });
      }
    });
    return elXAxisWrap;
  }
  /**
   * @param {Array<Record<string, any>>} pos
   * @param {Record<string, any>} origin
   */
  createPaths(pos, origin) {
    const linePathsTo = [];
    let linePathsFrom = [];
    const areaPathsTo = [];
    let areaPathsFrom = [];
    if (pos.length) {
      linePathsFrom = [this.graphics.move(origin.x, origin.y)];
      areaPathsFrom = [this.graphics.move(origin.x, origin.y)];
      let linePathTo = this.graphics.move(pos[0].x, pos[0].y);
      let areaPathTo = this.graphics.move(pos[0].x, pos[0].y);
      pos.forEach((p, i) => {
        linePathTo += this.graphics.line(p.x, p.y);
        areaPathTo += this.graphics.line(p.x, p.y);
        if (i === pos.length - 1) {
          linePathTo += "Z";
          areaPathTo += "Z";
        }
      });
      linePathsTo.push(linePathTo);
      areaPathsTo.push(areaPathTo);
    }
    return {
      linePathsFrom,
      linePathsTo,
      areaPathsFrom,
      areaPathsTo
    };
  }
  /**
   * @param {Record<string, any>} pos
   * @param {number} polygonSize
   */
  getTextPos(pos, polygonSize) {
    const limit = 10;
    let textAnchor = "middle";
    let newX = pos.x;
    let newY = pos.y;
    if (Math.abs(pos.x) >= limit) {
      if (pos.x > 0) {
        textAnchor = "start";
        newX += 10;
      } else if (pos.x < 0) {
        textAnchor = "end";
        newX -= 10;
      }
    } else {
      textAnchor = "middle";
    }
    if (Math.abs(pos.y) >= polygonSize - limit) {
      if (pos.y < 0) {
        newY -= 10;
      } else if (pos.y > 0) {
        newY += 10;
      }
    }
    return {
      textAnchor,
      newX,
      newY
    };
  }
  /**
   * @param {number} realIndex
   */
  getPreviousPath(realIndex) {
    const w = this.w;
    let pathFrom = null;
    for (let pp = 0; pp < w.globals.previousPaths.length; pp++) {
      const gpp = w.globals.previousPaths[pp];
      if (gpp.paths.length > 0 && parseInt(gpp.realIndex, 10) === parseInt(String(realIndex), 10)) {
        if (typeof w.globals.previousPaths[pp].paths[0] !== "undefined") {
          pathFrom = w.globals.previousPaths[pp].paths[0].d;
        }
      }
    }
    return pathFrom;
  }
  /**
   * @param {any[]} dataRadiusArr
   * @param {any[]} angleArr
   */
  getDataPointsPos(dataRadiusArr, angleArr, dataPointsLen = this.dataPointsLen) {
    dataRadiusArr = dataRadiusArr || [];
    angleArr = angleArr || [];
    const dataPointsPosArray = [];
    for (let j = 0; j < dataPointsLen; j++) {
      const curPointPos = {};
      curPointPos.x = dataRadiusArr[j] * Math.sin(angleArr[j]);
      curPointPos.y = -dataRadiusArr[j] * Math.cos(angleArr[j]);
      dataPointsPosArray.push(curPointPos);
    }
    return dataPointsPosArray;
  }
}
class Radial extends Pie {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    super(w, ctx);
    this.ctx = ctx;
    this.w = w;
    this.animBeginArr = [0];
    this.animDur = 0;
    this.startAngle = w.config.plotOptions.radialBar.startAngle;
    this.endAngle = w.config.plotOptions.radialBar.endAngle;
    this.totalAngle = Math.abs(
      w.config.plotOptions.radialBar.endAngle - w.config.plotOptions.radialBar.startAngle
    );
    this.trackStartAngle = w.config.plotOptions.radialBar.track.startAngle;
    this.trackEndAngle = w.config.plotOptions.radialBar.track.endAngle;
    this.barLabels = this.w.config.plotOptions.radialBar.barLabels;
    this.donutDataLabels = this.w.config.plotOptions.radialBar.dataLabels;
    this.radialDataLabels = this.donutDataLabels;
    if (!this.trackStartAngle) this.trackStartAngle = this.startAngle;
    if (!this.trackEndAngle) this.trackEndAngle = this.endAngle;
    if (this.endAngle === 360) this.endAngle = 359.99;
    this.margin = parseInt(w.config.plotOptions.radialBar.track.margin, 10);
    this.onBarLabelClick = this.onBarLabelClick.bind(this);
  }
  /**
   * @param {any[]} series
   */
  draw(series) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const ret = graphics.group({
      class: "apexcharts-radialbar"
    });
    if (w.globals.noData) return ret;
    const elSeries = graphics.group();
    const centerY = this.defaultSize / 2;
    const centerX = w.layout.gridWidth / 2;
    let size = this.defaultSize / 2.05;
    if (!w.config.chart.sparkline.enabled) {
      size = size - w.config.stroke.width - w.config.chart.dropShadow.blur;
    }
    const colorArr = w.globals.fill.colors;
    if (w.config.plotOptions.radialBar.track.show) {
      const elTracks = this.drawTracks({
        size,
        centerX,
        centerY,
        colorArr,
        series
      });
      elSeries.add(elTracks);
    }
    const elG = this.drawArcs({
      size,
      centerX,
      centerY,
      colorArr,
      series
    });
    let totalAngle = 360;
    if (w.config.plotOptions.radialBar.startAngle < 0) {
      totalAngle = this.totalAngle;
    }
    const angleRatio = (360 - totalAngle) / 360;
    w.globals.radialSize = size - size * angleRatio;
    if (this.radialDataLabels.value.show) {
      const offset = Math.max(
        this.radialDataLabels.value.offsetY,
        this.radialDataLabels.name.offsetY
      );
      w.globals.radialSize += offset * angleRatio;
    }
    elSeries.add(elG.g);
    if (w.config.plotOptions.radialBar.hollow.position === "front") {
      elG.g.add(elG.elHollow);
      if (elG.dataLabels) {
        elG.g.add(elG.dataLabels);
      }
    }
    ret.add(elSeries);
    return ret;
  }
  /**
   * @param {Record<string, any>} opts
   */
  drawTracks(opts) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const g = graphics.group({
      class: "apexcharts-tracks"
    });
    const filters = new Filters(this.w);
    const fill = new Fill(this.w);
    const strokeWidth = this.getStrokeWidth(opts);
    opts.size = opts.size - strokeWidth / 2;
    for (let i = 0; i < opts.series.length; i++) {
      const elRadialBarTrack = graphics.group({
        class: "apexcharts-radialbar-track apexcharts-track"
      });
      g.add(elRadialBarTrack);
      elRadialBarTrack.attr({
        rel: i + 1
      });
      opts.size = opts.size - strokeWidth - this.margin;
      const trackConfig = w.config.plotOptions.radialBar.track;
      const pathFill = fill.fillPath({
        seriesNumber: 0,
        size: opts.size,
        fillColors: Array.isArray(trackConfig.background) ? trackConfig.background[i] : trackConfig.background,
        solid: true
      });
      const startAngle = this.trackStartAngle;
      let endAngle = this.trackEndAngle;
      if (Math.abs(endAngle) + Math.abs(startAngle) >= 360)
        endAngle = 360 - Math.abs(this.startAngle) - 0.1;
      const elPath = graphics.drawPath({
        d: "",
        stroke: pathFill,
        strokeWidth: strokeWidth * parseInt(trackConfig.strokeWidth, 10) / 100,
        fill: "none",
        strokeOpacity: trackConfig.opacity,
        classes: "apexcharts-radialbar-area"
      });
      if (trackConfig.dropShadow.enabled) {
        const shadow = trackConfig.dropShadow;
        filters.dropShadow(elPath, shadow);
      }
      elRadialBarTrack.add(elPath);
      elPath.attr("id", "apexcharts-radialbarTrack-" + i);
      this.animatePaths(elPath, {
        centerX: opts.centerX,
        centerY: opts.centerY,
        endAngle,
        startAngle,
        size: opts.size,
        i,
        totalItems: 2,
        animBeginArr: 0,
        dur: 0,
        isTrack: true
      });
    }
    return g;
  }
  /**
   * @param {Record<string, any>} opts
   */
  drawArcs(opts) {
    const w = this.w;
    const graphics = new Graphics(this.w);
    const fill = new Fill(this.w);
    const filters = new Filters(this.w);
    const g = graphics.group();
    const strokeWidth = this.getStrokeWidth(opts);
    opts.size = opts.size - strokeWidth / 2;
    let hollowFillID = w.config.plotOptions.radialBar.hollow.background;
    const hollowSize = opts.size - strokeWidth * opts.series.length - this.margin * opts.series.length - strokeWidth * parseInt(w.config.plotOptions.radialBar.track.strokeWidth, 10) / 100 / 2;
    const hollowRadius = hollowSize - w.config.plotOptions.radialBar.hollow.margin;
    if (w.config.plotOptions.radialBar.hollow.image !== void 0) {
      hollowFillID = this.drawHollowImage(opts, g, hollowSize, hollowFillID);
    }
    const elHollow = this.drawHollow({
      size: hollowRadius,
      centerX: opts.centerX,
      centerY: opts.centerY,
      fill: hollowFillID ? hollowFillID : "transparent"
    });
    if (w.config.plotOptions.radialBar.hollow.dropShadow.enabled) {
      const shadow = w.config.plotOptions.radialBar.hollow.dropShadow;
      filters.dropShadow(elHollow, shadow);
    }
    let shown = 1;
    if (!this.radialDataLabels.total.show && w.seriesData.series.length > 1) {
      shown = 0;
    }
    let dataLabels = null;
    if (this.radialDataLabels.show) {
      const dataLabelsGroup = w.dom.Paper.findOne(
        `.apexcharts-datalabels-group`
      );
      dataLabels = this.renderInnerDataLabels(
        dataLabelsGroup,
        this.radialDataLabels,
        {
          hollowSize,
          centerX: opts.centerX,
          centerY: opts.centerY,
          opacity: shown
        }
      );
    }
    if (w.config.plotOptions.radialBar.hollow.position === "back") {
      g.add(elHollow);
      if (dataLabels) {
        g.add(dataLabels);
      }
    }
    let reverseLoop = false;
    if (w.config.plotOptions.radialBar.inverseOrder) {
      reverseLoop = true;
    }
    for (let i = reverseLoop ? opts.series.length - 1 : 0; reverseLoop ? i >= 0 : i < opts.series.length; reverseLoop ? i-- : i++) {
      const elRadialBarArc = graphics.group({
        class: `apexcharts-series apexcharts-radial-series`,
        seriesName: Utils$1.escapeString(w.seriesData.seriesNames[i])
      });
      g.add(elRadialBarArc);
      elRadialBarArc.attr({
        rel: i + 1,
        "data:realIndex": i
      });
      Series.addCollapsedClassToSeries(this.w, elRadialBarArc, i);
      opts.size = opts.size - strokeWidth - this.margin;
      const pathFill = fill.fillPath({
        seriesNumber: i,
        size: opts.size,
        value: opts.series[i]
      });
      const startAngle = this.startAngle;
      let prevStartAngle;
      const dataValue = Utils$1.negToZero(opts.series[i] > 100 ? 100 : opts.series[i]) / 100;
      let endAngle = Math.round(this.totalAngle * dataValue) + this.startAngle;
      let prevEndAngle;
      if (w.globals.dataChanged) {
        prevStartAngle = this.startAngle;
        prevEndAngle = Math.round(
          this.totalAngle * Utils$1.negToZero(w.globals.previousPaths[i]) / 100
        ) + prevStartAngle;
      }
      const currFullAngle = Math.abs(endAngle) + Math.abs(startAngle);
      if (currFullAngle > 360) {
        endAngle = endAngle - 0.01;
      }
      const prevFullAngle = Math.abs(prevEndAngle) + Math.abs(prevStartAngle);
      if (prevFullAngle > 360) {
        prevEndAngle = prevEndAngle - 0.01;
      }
      const angle = endAngle - startAngle;
      const dashArray = Array.isArray(w.config.stroke.dashArray) ? w.config.stroke.dashArray[i] : w.config.stroke.dashArray;
      const elPath = graphics.drawPath({
        d: "",
        stroke: pathFill,
        strokeWidth,
        fill: "none",
        fillOpacity: w.config.fill.opacity,
        classes: "apexcharts-radialbar-area apexcharts-radialbar-slice-" + i,
        strokeDashArray: dashArray
      });
      const radialMidAngle = startAngle + angle / 2;
      const radialArcCenter = Utils$1.polarToCartesian(
        opts.centerX,
        opts.centerY,
        opts.size,
        radialMidAngle
      );
      Graphics.setAttrs(elPath.node, {
        "data:angle": angle,
        "data:value": opts.series[i],
        "data:cx": radialArcCenter.x,
        "data:cy": radialArcCenter.y
      });
      if (w.config.chart.dropShadow.enabled) {
        const shadow = w.config.chart.dropShadow;
        filters.dropShadow(elPath, shadow, i);
      }
      filters.setSelectionFilter(elPath, 0, i);
      this.addListeners(elPath, this.radialDataLabels);
      elRadialBarArc.add(elPath);
      elPath.attr({
        index: 0,
        j: i
      });
      if (this.barLabels.enabled) {
        const barStartCords = Utils$1.polarToCartesian(
          opts.centerX,
          opts.centerY,
          opts.size,
          startAngle
        );
        const text = this.barLabels.formatter(w.seriesData.seriesNames[i], {
          seriesIndex: i,
          w
        });
        const classes = ["apexcharts-radialbar-label"];
        if (!this.barLabels.onClick) {
          classes.push("apexcharts-no-click");
        }
        let textColor = this.barLabels.useSeriesColors ? w.globals.colors[i] : w.config.chart.foreColor;
        if (!textColor) {
          textColor = w.config.chart.foreColor;
        }
        const x = barStartCords.x + this.barLabels.offsetX;
        const y = barStartCords.y + this.barLabels.offsetY;
        const elText = graphics.drawText({
          x,
          y,
          text,
          textAnchor: "end",
          dominantBaseline: "middle",
          fontFamily: this.barLabels.fontFamily,
          fontWeight: this.barLabels.fontWeight,
          fontSize: this.barLabels.fontSize,
          foreColor: textColor,
          cssClass: classes.join(" ")
        });
        elText.on("click", this.onBarLabelClick);
        elText.attr({
          rel: i + 1
        });
        if (startAngle !== 0) {
          elText.attr({
            "transform-origin": `${x} ${y}`,
            transform: `rotate(${startAngle} 0 0)`
          });
        }
        elRadialBarArc.add(elText);
      }
      let dur = 0;
      if (this.initialAnim && !w.globals.resized && !w.globals.dataChanged) {
        dur = w.config.chart.animations.speed;
      }
      if (w.globals.dataChanged) {
        dur = w.config.chart.animations.dynamicAnimation.speed;
      }
      this.animDur = dur / (opts.series.length * 1.2) + this.animDur;
      this.animBeginArr.push(this.animDur);
      this.animatePaths(elPath, {
        centerX: opts.centerX,
        centerY: opts.centerY,
        endAngle,
        startAngle,
        prevEndAngle,
        prevStartAngle,
        size: opts.size,
        i,
        totalItems: 2,
        animBeginArr: this.animBeginArr,
        dur,
        shouldSetPrevPaths: true
      });
    }
    return {
      g,
      elHollow,
      dataLabels
    };
  }
  /**
   * @param {Record<string, any>} opts
   */
  drawHollow(opts) {
    const graphics = new Graphics(this.w);
    const circle = graphics.drawCircle(opts.size * 2);
    circle.attr({
      class: "apexcharts-radialbar-hollow",
      cx: opts.centerX,
      cy: opts.centerY,
      r: opts.size,
      fill: opts.fill
    });
    return circle;
  }
  /**
   * @param {Record<string, any>} opts
   * @param {any} g
   * @param {number} hollowSize
   * @param {string} hollowFillID
   */
  drawHollowImage(opts, g, hollowSize, hollowFillID) {
    const w = this.w;
    const fill = new Fill(this.w);
    const randID = Utils$1.randomId();
    const hollowFillImg = w.config.plotOptions.radialBar.hollow.image;
    if (w.config.plotOptions.radialBar.hollow.imageClipped) {
      fill.clippedImgArea({
        width: hollowSize,
        height: hollowSize,
        image: hollowFillImg,
        patternID: `pattern${w.globals.cuid}${randID}`
      });
      hollowFillID = `url(#pattern${w.globals.cuid}${randID})`;
    } else {
      const imgWidth = w.config.plotOptions.radialBar.hollow.imageWidth;
      const imgHeight = w.config.plotOptions.radialBar.hollow.imageHeight;
      if (imgWidth === void 0 && imgHeight === void 0) {
        const image = w.dom.Paper.image(
          hollowFillImg,
          /** @this {any} */
          function(loader) {
            this.move(
              opts.centerX - loader.width / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetX,
              opts.centerY - loader.height / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetY
            );
          }
        );
        g.add(image);
      } else {
        const image = w.dom.Paper.image(
          hollowFillImg,
          /** @this {any} */
          function() {
            this.move(
              opts.centerX - imgWidth / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetX,
              opts.centerY - imgHeight / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetY
            );
            this.size(imgWidth, imgHeight);
          }
        );
        g.add(image);
      }
    }
    return hollowFillID;
  }
  /**
   * @param {Record<string, any>} opts
   */
  getStrokeWidth(opts) {
    const w = this.w;
    return opts.size * (100 - parseInt(w.config.plotOptions.radialBar.hollow.size, 10)) / 100 / (opts.series.length + 1) - this.margin;
  }
  /**
   * @param {Event} e
   */
  onBarLabelClick(e) {
    var _a;
    const target = (
      /** @type {Element} */
      e.target
    );
    const seriesIndex = parseInt((_a = target.getAttribute("rel")) != null ? _a : "", 10) - 1;
    const legendClick = this.barLabels.onClick;
    const w = this.w;
    if (legendClick) {
      legendClick(w.seriesData.seriesNames[seriesIndex], { w, seriesIndex });
    }
  }
}
class RangeBar extends Bar {
  /**
   * @param {any[]} series
   * @param {number} seriesIndex
   */
  draw(series, seriesIndex) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i;
    const w = this.w;
    const graphics = new Graphics(this.w);
    this.rangeBarOptions = this.w.config.plotOptions.rangeBar;
    this.series = series;
    this.seriesRangeStart = w.rangeData.seriesRangeStart;
    this.seriesRangeEnd = w.rangeData.seriesRangeEnd;
    this.barHelpers.initVariables(series);
    const ret = graphics.group({
      class: "apexcharts-rangebar-series apexcharts-plot-series"
    });
    for (let i = 0; i < series.length; i++) {
      let x, y;
      const realIndex = w.globals.comboCharts ? (
        /** @type {any} */
        seriesIndex[i]
      ) : i;
      const { columnGroupIndex } = this.barHelpers.getGroupIndex(realIndex);
      const elSeries = graphics.group({
        class: `apexcharts-series`,
        seriesName: Utils$1.escapeString(w.seriesData.seriesNames[realIndex]),
        rel: i + 1,
        "data:realIndex": realIndex
      });
      Series.addCollapsedClassToSeries(this.w, elSeries, realIndex);
      if (series[i].length > 0) {
        this.visibleI = this.visibleI + 1;
      }
      let translationsIndex = 0;
      if (this.yRatio.length > 1) {
        this.yaxisIndex = /** @type {any} */
        w.globals.seriesYAxisReverseMap[realIndex][0];
        translationsIndex = realIndex;
      }
      const initPositions = this.barHelpers.initialPositions(realIndex);
      const {
        y: initY,
        zeroW,
        // zeroW is the baseline where 0 meets x axis
        x: initX,
        zeroH
        // zeroH is the baseline where 0 meets y axis
      } = initPositions;
      let barWidth = (_a = initPositions.barWidth) != null ? _a : 0;
      let barHeight = (_b = initPositions.barHeight) != null ? _b : 0;
      const yDivision = (_c = initPositions.yDivision) != null ? _c : 0;
      const xDivision = (_d = initPositions.xDivision) != null ? _d : 0;
      y = initY;
      x = initX;
      const elDataLabelsWrap = graphics.group({
        class: "apexcharts-datalabels",
        "data:realIndex": realIndex
      });
      const elGoalsMarkers = graphics.group({
        class: "apexcharts-rangebar-goals-markers"
      });
      for (let j = 0; j < w.globals.dataPoints; j++) {
        const strokeWidth = this.barHelpers.getStrokeWidth(i, j, realIndex);
        const y1 = this.seriesRangeStart[i][j];
        const y2 = this.seriesRangeEnd[i][j];
        let paths = (
          /** @type {any} */
          null
        );
        let barXPosition = null;
        let barYPosition = null;
        const params = { x, y, strokeWidth, elSeries };
        let seriesLen = this.seriesLen;
        if (w.config.plotOptions.bar.rangeBarGroupRows) {
          seriesLen = 1;
        }
        if (typeof /** @type {Record<string,any>} */
        ((_e = w.config.series[i].data) == null ? void 0 : _e[j]) === "undefined") {
          break;
        }
        if (this.isHorizontal) {
          barYPosition = y + barHeight * /** @type {any} */
          this.visibleI;
          const srty = (yDivision - barHeight * seriesLen) / 2;
          if (
            /** @type {Record<string,any>} */
            (_g = (_f = w.config.series[i].data) == null ? void 0 : _f[j]) == null ? void 0 : _g.x
          ) {
            const positions = this.detectOverlappingBars({
              i,
              j,
              barYPosition,
              srty,
              barHeight,
              yDivision,
              initPositions
            });
            barHeight = positions.barHeight;
            barYPosition = positions.barYPosition;
          }
          paths = this.drawRangeBarPaths(__spreadValues({
            indexes: { i, j, realIndex },
            barHeight,
            barYPosition,
            zeroW,
            yDivision,
            y1,
            y2
          }, params));
          barWidth = paths.barWidth;
        } else {
          if (w.axisFlags.isXNumeric) {
            x = (w.seriesData.seriesX[i][j] - w.globals.minX) / this.xRatio - barWidth / 2;
          }
          barXPosition = x + barWidth * /** @type {any} */
          this.visibleI;
          const srtx = (xDivision - barWidth * seriesLen) / 2;
          if (
            /** @type {Record<string,any>} */
            (_i = (_h = w.config.series[i].data) == null ? void 0 : _h[j]) == null ? void 0 : _i.x
          ) {
            const positions = this.detectOverlappingBars({
              i,
              j,
              barXPosition,
              srtx,
              barWidth,
              xDivision,
              initPositions
            });
            barWidth = positions.barWidth;
            barXPosition = positions.barXPosition;
          }
          paths = this.drawRangeColumnPaths(__spreadValues({
            indexes: { i, j, realIndex, translationsIndex },
            barWidth,
            barXPosition,
            zeroH,
            xDivision
          }, params));
          barHeight = paths.barHeight;
        }
        const barGoalLine = this.barHelpers.drawGoalLine({
          barXPosition: paths.barXPosition,
          barYPosition,
          goalX: paths.goalX,
          goalY: paths.goalY,
          barHeight,
          barWidth
        });
        if (barGoalLine) {
          elGoalsMarkers.add(barGoalLine);
        }
        y = paths.y;
        x = paths.x;
        const pathFill = this.barHelpers.getPathFillColor(
          series,
          i,
          j,
          realIndex
        );
        this.renderSeries({
          realIndex,
          pathFill: pathFill.color,
          lineFill: pathFill.useRangeColor ? pathFill.color : w.globals.stroke.colors[realIndex],
          j,
          i,
          x,
          y,
          y1,
          y2,
          pathFrom: paths.pathFrom,
          pathTo: paths.pathTo,
          strokeWidth,
          elSeries,
          series,
          barHeight,
          barWidth,
          barXPosition,
          barYPosition,
          columnGroupIndex,
          elDataLabelsWrap,
          elGoalsMarkers,
          visibleSeries: this.visibleI,
          type: "rangebar"
        });
      }
      ret.add(elSeries);
    }
    return ret;
  }
  /** @param {{ i?: any, j?: any, barYPosition?: any, barXPosition?: any, srty?: any, srtx?: any, barHeight?: any, barWidth?: any, yDivision?: any, xDivision?: any, initPositions?: any }} opts */
  detectOverlappingBars({
    i,
    j,
    barYPosition,
    barXPosition,
    srty,
    srtx,
    barHeight,
    barWidth,
    yDivision,
    xDivision,
    initPositions
  }) {
    var _a, _b, _c, _d;
    const w = this.w;
    let overlaps = [];
    const rangeName = (
      /** @type {Record<string,any>} */
      (_b = (_a = w.config.series[i].data) == null ? void 0 : _a[j]) == null ? void 0 : _b.rangeName
    );
    const x = (
      /** @type {Record<string,any>} */
      (_d = (_c = w.config.series[i].data) == null ? void 0 : _c[j]) == null ? void 0 : _d.x
    );
    const labelX = Array.isArray(x) ? x.join(" ") : x;
    const rowIndex = w.labelData.labels.map((_) => Array.isArray(_) ? _.join(" ") : _).indexOf(labelX);
    const overlappedIndex = w.rangeData.seriesRange[i].findIndex(
      (tx) => {
        var _a2;
        return tx.x === labelX && ((_a2 = tx.overlaps) == null ? void 0 : _a2.size) > 0;
      }
    );
    if (this.isHorizontal) {
      if (w.config.plotOptions.bar.rangeBarGroupRows) {
        barYPosition = srty + yDivision * rowIndex;
      } else {
        barYPosition = srty + barHeight * this.visibleI + yDivision * rowIndex;
      }
      if (overlappedIndex > -1 && !w.config.plotOptions.bar.rangeBarOverlap) {
        overlaps = Array.from(
          /** @type {any} */
          w.rangeData.seriesRange[i][overlappedIndex].overlaps
        );
        if (overlaps.indexOf(rangeName) > -1) {
          barHeight = initPositions.barHeight / overlaps.length;
          barYPosition = barHeight * this.visibleI + yDivision * (100 - parseInt(this.barOptions.barHeight, 10)) / 100 / 2 + barHeight * (this.visibleI + overlaps.indexOf(rangeName)) + yDivision * rowIndex;
        }
      }
    } else {
      if (rowIndex > -1 && !w.labelData.timescaleLabels.length) {
        if (w.config.plotOptions.bar.rangeBarGroupRows) {
          barXPosition = srtx + xDivision * rowIndex;
        } else {
          barXPosition = srtx + barWidth * this.visibleI + xDivision * rowIndex;
        }
      }
      if (overlappedIndex > -1 && !w.config.plotOptions.bar.rangeBarOverlap) {
        overlaps = Array.from(
          /** @type {any} */
          w.rangeData.seriesRange[i][overlappedIndex].overlaps
        );
        if (overlaps.indexOf(rangeName) > -1) {
          barWidth = initPositions.barWidth / overlaps.length;
          barXPosition = barWidth * this.visibleI + xDivision * (100 - parseInt(this.barOptions.barWidth, 10)) / 100 / 2 + barWidth * (this.visibleI + overlaps.indexOf(rangeName)) + xDivision * rowIndex;
        }
      }
    }
    return {
      barYPosition,
      barXPosition,
      barHeight,
      barWidth
    };
  }
  /** @param {{indexes: any, x: any, xDivision: any, barWidth: any, barXPosition: any, zeroH: any}} opts */
  drawRangeColumnPaths({
    indexes,
    x,
    xDivision,
    barWidth,
    barXPosition,
    zeroH
  }) {
    var _a, _b;
    const w = this.w;
    const { i, j, realIndex, translationsIndex } = indexes;
    const yRatio = this.yRatio[translationsIndex];
    const range = this.getRangeValue(realIndex, j);
    let y1 = Math.min(range.start, range.end);
    let y2 = Math.max(range.start, range.end);
    if (typeof /** @type {any} */
    ((_a = this.series[i]) == null ? void 0 : _a[j]) === "undefined" || /** @type {any} */
    ((_b = this.series[i]) == null ? void 0 : _b[j]) === null) {
      y1 = zeroH;
    } else {
      y1 = zeroH - y1 / yRatio;
      y2 = zeroH - y2 / yRatio;
    }
    const barHeight = Math.abs(y2 - y1);
    const paths = this.barHelpers.getColumnPaths({
      barXPosition,
      barWidth,
      y1,
      y2,
      strokeWidth: this.strokeWidth,
      series: this.seriesRangeEnd,
      realIndex,
      i: realIndex,
      j,
      w
    });
    if (!w.axisFlags.isXNumeric) {
      x = x + xDivision;
    } else {
      const xForNumericXAxis = this.getBarXForNumericXAxis({
        x,
        j,
        realIndex,
        barWidth
      });
      x = xForNumericXAxis.x;
      barXPosition = xForNumericXAxis.barXPosition;
    }
    return {
      pathTo: paths.pathTo,
      pathFrom: paths.pathFrom,
      barHeight,
      x,
      y: range.start < 0 && range.end < 0 ? y1 : y2,
      goalY: this.barHelpers.getGoalValues(
        "y",
        /** @type {any} */
        null,
        zeroH,
        i,
        j,
        translationsIndex
      ),
      barXPosition
    };
  }
  /**
   * @param {number} val
   */
  preventBarOverflow(val) {
    const w = this.w;
    if (val < 0) {
      val = 0;
    }
    if (val > w.layout.gridWidth) {
      val = w.layout.gridWidth;
    }
    return val;
  }
  /** @param {{indexes: any, y: any, y1: any, y2: any, yDivision: any, barHeight: any, barYPosition: any, zeroW: any}} opts */
  drawRangeBarPaths({
    indexes,
    y,
    y1,
    y2,
    yDivision,
    barHeight,
    barYPosition,
    zeroW
  }) {
    const w = this.w;
    const { realIndex, j } = indexes;
    const x1 = this.preventBarOverflow(zeroW + y1 / this.invertedYRatio);
    const x2 = this.preventBarOverflow(zeroW + y2 / this.invertedYRatio);
    const range = this.getRangeValue(realIndex, j);
    const barWidth = Math.abs(x2 - x1);
    const paths = this.barHelpers.getBarpaths({
      barYPosition,
      barHeight,
      x1,
      x2,
      strokeWidth: this.strokeWidth,
      series: this.seriesRangeEnd,
      i: realIndex,
      realIndex,
      j,
      w
    });
    if (!w.axisFlags.isXNumeric) {
      y = y + yDivision;
    }
    return {
      pathTo: paths.pathTo,
      pathFrom: paths.pathFrom,
      barWidth,
      x: range.start < 0 && range.end < 0 ? x1 : x2,
      goalX: this.barHelpers.getGoalValues(
        "x",
        zeroW,
        /** @type {any} */
        null,
        realIndex,
        j,
        0
      ),
      y
    };
  }
  /**
   * @param {number} i
   * @param {number} j
   */
  getRangeValue(i, j) {
    const w = this.w;
    return {
      start: w.rangeData.seriesRangeStart[i][j],
      end: w.rangeData.seriesRangeEnd[i][j]
    };
  }
}
function normalize(data, area) {
  let sum = 0;
  for (let i = 0; i < data.length; i++) {
    sum += data[i];
  }
  const multiplier = area / sum;
  const result = new Array(data.length);
  for (let i = 0; i < data.length; i++) {
    result[i] = data[i] * multiplier;
  }
  return result;
}
function calculateRatio(rowMin, rowMax, rowSum, length) {
  const lengthSq = length * length;
  const sumSq = rowSum * rowSum;
  return Math.max(
    lengthSq * rowMax / sumSq,
    sumSq / (lengthSq * rowMin)
  );
}
function improvesRatio(rowLen, rowMin, rowMax, rowSum, nextNode, length) {
  if (rowLen === 0) return true;
  const currentRatio = calculateRatio(rowMin, rowMax, rowSum, length);
  const newRatio = calculateRatio(
    Math.min(rowMin, nextNode),
    Math.max(rowMax, nextNode),
    rowSum + nextNode,
    length
  );
  return currentRatio >= newRatio;
}
function emitCoordinates(coords, row, rowLen, rowSum, xoffset, yoffset, width, height) {
  if (width >= height) {
    const areaWidth = rowSum / height;
    let subY = yoffset;
    for (let i = 0; i < rowLen; i++) {
      const h = row[i] / areaWidth;
      coords.push([xoffset, subY, xoffset + areaWidth, subY + h]);
      subY += h;
    }
  } else {
    const areaHeight = rowSum / width;
    let subX = xoffset;
    for (let i = 0; i < rowLen; i++) {
      const w = row[i] / areaHeight;
      coords.push([subX, yoffset, subX + w, yoffset + areaHeight]);
      subX += w;
    }
  }
}
function squarify(data, xoffset, yoffset, width, height) {
  const coords = [];
  const n = data.length;
  if (n === 0) return coords;
  const row = new Array(n);
  let rowLen = 0;
  let rowSum = 0;
  let rowMin = Infinity;
  let rowMax = -Infinity;
  let i = 0;
  while (i < n) {
    const length = Math.min(width, height);
    const val = data[i];
    if (improvesRatio(rowLen, rowMin, rowMax, rowSum, val, length)) {
      row[rowLen] = val;
      rowLen++;
      rowSum += val;
      if (val < rowMin) rowMin = val;
      if (val > rowMax) rowMax = val;
      i++;
    } else {
      emitCoordinates(coords, row, rowLen, rowSum, xoffset, yoffset, width, height);
      if (width >= height) {
        const areaWidth = rowSum / height;
        xoffset += areaWidth;
        width -= areaWidth;
      } else {
        const areaHeight = rowSum / width;
        yoffset += areaHeight;
        height -= areaHeight;
      }
      rowLen = 0;
      rowSum = 0;
      rowMin = Infinity;
      rowMax = -Infinity;
    }
  }
  if (rowLen > 0) {
    emitCoordinates(coords, row, rowLen, rowSum, xoffset, yoffset, width, height);
  }
  return coords;
}
function generate(data, width, height) {
  const n = data.length;
  const sums = new Array(n);
  for (let i = 0; i < n; i++) {
    let s = 0;
    const series = data[i];
    for (let j = 0; j < series.length; j++) {
      s += series[j];
    }
    sums[i] = s;
  }
  const seriesRects = squarify(
    normalize(sums, width * height),
    0,
    0,
    width,
    height
  );
  const results = new Array(n);
  for (let i = 0; i < n; i++) {
    const rect = seriesRects[i];
    const rx = rect[0];
    const ry = rect[1];
    const rw = rect[2] - rx;
    const rh = rect[3] - ry;
    results[i] = squarify(
      normalize(data[i], rw * rh),
      rx,
      ry,
      rw,
      rh
    );
  }
  return results;
}
const TreemapSquared = { generate };
class TreemapChart {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.ctx = ctx;
    this.w = w;
    this.strokeWidth = this.w.config.stroke.width;
    this.helpers = new TreemapHelpers(w, ctx);
    this.dynamicAnim = this.w.config.chart.animations.dynamicAnimation;
    this.labels = [];
  }
  /**
   * @param {any[]} series
   */
  draw(series) {
    const w = this.w;
    const graphics = new Graphics(this.w, this.ctx);
    const fill = new Fill(this.w);
    const ret = graphics.group({
      class: "apexcharts-treemap"
    });
    if (w.globals.noData) return ret;
    const ser = [];
    series.forEach((s) => {
      const d = s.map((v) => {
        return Math.abs(v);
      });
      ser.push(d);
    });
    this.negRange = this.helpers.checkColorRange();
    w.config.series.forEach((s, i) => {
      s.data.forEach((l) => {
        if (!Array.isArray(this.labels[i])) this.labels[i] = [];
        this.labels[i].push(l.x);
      });
    });
    const nodes = TreemapSquared.generate(
      ser,
      w.layout.gridWidth,
      w.layout.gridHeight
    );
    nodes.forEach((node, i) => {
      var _a;
      const elSeries = graphics.group({
        class: `apexcharts-series apexcharts-treemap-series`,
        seriesName: Utils$1.escapeString(w.seriesData.seriesNames[i]),
        rel: i + 1,
        "data:realIndex": i
      });
      graphics.setupEventDelegation(elSeries, ".apexcharts-treemap-rect");
      if (w.config.chart.dropShadow.enabled) {
        const shadow = w.config.chart.dropShadow;
        const filters = new Filters(this.w);
        filters.dropShadow(ret, shadow, i);
      }
      const elDataLabelWrap = graphics.group({
        class: "apexcharts-data-labels"
      });
      const bounds = {
        xMin: Infinity,
        yMin: Infinity,
        xMax: -Infinity,
        yMax: -Infinity
      };
      node.forEach((r, j) => {
        const x1 = r[0];
        const y1 = r[1];
        const x2 = r[2];
        const y2 = r[3];
        bounds.xMin = Math.min(bounds.xMin, x1);
        bounds.yMin = Math.min(bounds.yMin, y1);
        bounds.xMax = Math.max(bounds.xMax, x2);
        bounds.yMax = Math.max(bounds.yMax, y2);
        const colorProps = this.helpers.getShadeColor(
          w.config.chart.type,
          i,
          j,
          this.negRange
        );
        const color = colorProps.color;
        const pathFill = fill.fillPath({
          color,
          seriesNumber: i,
          dataPointIndex: j
        });
        const elRect = graphics.drawRect(
          x1,
          y1,
          x2 - x1,
          y2 - y1,
          w.config.plotOptions.treemap.borderRadius,
          "#fff",
          1,
          this.strokeWidth,
          w.config.plotOptions.treemap.useFillColorAsStroke ? color : w.globals.stroke.colors[i]
        );
        elRect.attr({
          cx: x1,
          cy: y1,
          index: i,
          i,
          j,
          width: x2 - x1,
          height: y2 - y1,
          fill: pathFill
        });
        elRect.node.classList.add("apexcharts-treemap-rect");
        let fromRect = {
          x: x1 + (x2 - x1) / 2,
          y: y1 + (y2 - y1) / 2,
          width: 0,
          height: 0
        };
        const toRect = {
          x: x1,
          y: y1,
          width: x2 - x1,
          height: y2 - y1
        };
        if (w.config.chart.animations.enabled && !w.globals.dataChanged) {
          let speed = 1;
          if (!w.globals.resized) {
            speed = w.config.chart.animations.speed;
          }
          this.animateTreemap(elRect, fromRect, toRect, speed);
        }
        if (w.globals.dataChanged) {
          let speed = 1;
          if (this.dynamicAnim.enabled && w.globals.shouldAnimate) {
            speed = this.dynamicAnim.speed;
            if (w.globals.previousPaths[i] && /** @type {Record<string,any>} */
            w.globals.previousPaths[i][j] && /** @type {Record<string,any>} */
            w.globals.previousPaths[i][j].rect) {
              fromRect = /** @type {Record<string,any>} */
              w.globals.previousPaths[i][j].rect;
            }
            this.animateTreemap(elRect, fromRect, toRect, speed);
          }
        }
        let fontSize = this.getFontSize(r);
        let formattedText = w.config.dataLabels.formatter(this.labels[i][j], {
          value: w.seriesData.series[i][j],
          seriesIndex: i,
          dataPointIndex: j,
          w
        });
        if (w.config.plotOptions.treemap.dataLabels.format === "truncate") {
          fontSize = parseInt(String(w.config.dataLabels.style.fontSize), 10);
          formattedText = this.truncateLabels(
            String(formattedText),
            fontSize,
            x1,
            y1,
            x2,
            y2
          );
        }
        let dataLabels = null;
        if (w.seriesData.series[i][j]) {
          dataLabels = this.helpers.calculateDataLabels({
            text: formattedText,
            x: (x1 + x2) / 2,
            y: (y1 + y2) / 2 + this.strokeWidth / 2 + fontSize / 3,
            i,
            j,
            colorProps,
            fontSize,
            series
          });
        }
        if (w.config.dataLabels.enabled && dataLabels) {
          this.rotateToFitLabel(
            dataLabels,
            fontSize,
            formattedText,
            x1,
            y1,
            x2,
            y2
          );
        }
        elSeries.add(elRect);
        if (dataLabels !== null) {
          elSeries.add(dataLabels);
        }
      });
      const seriesTitle = w.config.plotOptions.treemap.seriesTitle;
      if (w.config.series.length > 1 && seriesTitle && seriesTitle.show) {
        const sName = (
          /** @type {Record<string,any>} */
          w.config.series[i].name || ""
        );
        if (sName && bounds.xMin < Infinity && bounds.yMin < Infinity) {
          const {
            offsetX,
            offsetY,
            borderColor,
            borderWidth,
            borderRadius,
            style
          } = seriesTitle;
          const textColor = style.color || w.config.chart.foreColor;
          const padding = {
            left: style.padding.left,
            right: style.padding.right,
            top: style.padding.top,
            bottom: style.padding.bottom
          };
          const textSize = graphics.getTextRects(
            sName,
            style.fontSize,
            style.fontFamily
          );
          const labelRectWidth = textSize.width + padding.left + padding.right;
          const labelRectHeight = textSize.height + padding.top + padding.bottom;
          const labelX = bounds.xMin + (offsetX || 0);
          const labelY = bounds.yMin + (offsetY || 0);
          const elLabelRect = graphics.drawRect(
            labelX,
            labelY,
            labelRectWidth,
            labelRectHeight,
            borderRadius,
            style.background,
            1,
            borderWidth,
            borderColor
          );
          const elLabelText = graphics.drawText({
            x: labelX + padding.left,
            y: labelY + padding.top + ((_a = textSize == null ? void 0 : textSize.height) != null ? _a : 0) * 0.75,
            text: sName,
            fontSize: style.fontSize,
            fontFamily: style.fontFamily,
            fontWeight: style.fontWeight,
            foreColor: textColor,
            cssClass: style.cssClass || ""
          });
          elSeries.add(elLabelRect);
          elSeries.add(elLabelText);
        }
      }
      elSeries.add(elDataLabelWrap);
      ret.add(elSeries);
    });
    return ret;
  }
  // This calculates a font-size based upon
  // average label length and the size of the box
  /**
   * @param {number[]} coordinates
   */
  getFontSize(coordinates) {
    const w = this.w;
    function totalLabelLength(arr) {
      let i, total = 0;
      if (Array.isArray(arr[0])) {
        for (i = 0; i < arr.length; i++) {
          total += totalLabelLength(arr[i]);
        }
      } else {
        for (i = 0; i < arr.length; i++) {
          total += arr[i].length;
        }
      }
      return total;
    }
    function countLabels(arr) {
      let i, total = 0;
      if (Array.isArray(arr[0])) {
        for (i = 0; i < arr.length; i++) {
          total += countLabels(arr[i]);
        }
      } else {
        for (i = 0; i < arr.length; i++) {
          total += 1;
        }
      }
      return total;
    }
    const averagelabelsize = totalLabelLength(this.labels) / countLabels(this.labels);
    function fontSize(width, height) {
      const area = width * height;
      const arearoot = Math.pow(area, 0.5);
      return Math.min(
        arearoot / averagelabelsize,
        parseInt(w.config.dataLabels.style.fontSize, 10)
      );
    }
    return fontSize(
      coordinates[2] - coordinates[0],
      coordinates[3] - coordinates[1]
    );
  }
  /**
   * @param {any} elText
   * @param {string | number} fontSize
   * @param {string} text
   * @param {number} x1
   * @param {number} y1
   * @param {number} x2
   * @param {number} y2
   */
  rotateToFitLabel(elText, fontSize, text, x1, y1, x2, y2) {
    const graphics = new Graphics(this.w);
    const textRect = graphics.getTextRects(text, String(fontSize));
    if (textRect.width + this.w.config.stroke.width + 5 > x2 - x1 && textRect.width <= y2 - y1) {
      const labelRotatingCenter = graphics.rotateAroundCenter(elText.node);
      elText.node.setAttribute(
        "transform",
        `rotate(-90 ${labelRotatingCenter.x} ${labelRotatingCenter.y}) translate(${textRect.height / 3})`
      );
    }
  }
  // This is an alternative label formatting method that uses a
  // consistent font size, and trims the edge of long labels
  /**
   * @param {string} text
   * @param {number} fontSize
   * @param {number} x1
   * @param {number} y1
   * @param {number} x2
   * @param {number} y2
   */
  truncateLabels(text, fontSize, x1, y1, x2, y2) {
    const graphics = new Graphics(this.w);
    const textRect = graphics.getTextRects(text, String(fontSize));
    const labelMaxWidth = textRect.width + this.w.config.stroke.width + 5 > x2 - x1 && y2 - y1 > x2 - x1 ? y2 - y1 : x2 - x1;
    const truncatedText = graphics.getTextBasedOnMaxWidth({
      text,
      maxWidth: labelMaxWidth,
      fontSize
    });
    if (text.length !== truncatedText.length && labelMaxWidth / fontSize < 5) {
      return "";
    } else {
      return truncatedText;
    }
  }
  /**
   * @param {any} el
   * @param {Record<string, any>} fromRect
   * @param {Record<string, any>} toRect
   * @param {number} speed
   */
  animateTreemap(el, fromRect, toRect, speed) {
    const animations = new Animations(this.w);
    animations.animateRect(el, fromRect, toRect, speed, () => {
      animations.animationCompleted(el);
    });
  }
}
ApexCharts.use({
  line: Line,
  area: Line,
  scatter: Line,
  bubble: Line,
  rangeArea: Line,
  bar: Bar,
  column: Bar,
  barStacked: BarStacked,
  rangeBar: RangeBar,
  candlestick: BoxCandleStick,
  boxPlot: BoxCandleStick,
  pie: Pie,
  donut: Pie,
  polarArea: Pie,
  radialBar: Radial,
  radar: Radar,
  heatmap: HeatMap,
  treemap: TreemapChart
});
class SSRRenderer {
  /**
   * Render chart to SVG string for server-side rendering
   *
   * @param {Record<string, any>} options - Chart configuration (same as ApexCharts constructor)
   * @param {{ width?: number, height?: number, scale?: number }} [ssrOptions] - SSR-specific options
   * @returns {Promise<string>} SVG string
   *
   * @example
   * const svgString = await SSRRenderer.renderToString({
   *   series: [{ data: [30, 40, 35] }],
   *   chart: { type: 'bar' }
   * }, {
   *   width: 500,
   *   height: 300
   * });
   */
  static renderToString(_0) {
    return __async(this, arguments, function* (options2, ssrOptions = {}) {
      if (Environment.isSSR()) {
        BrowserAPIs.init();
      }
      const { width = 400, height = 300, scale = 1 } = ssrOptions;
      const virtualEl = this._createVirtualElement(width, height);
      const ssrConfig = __spreadProps(__spreadValues({}, options2), {
        chart: __spreadProps(__spreadValues({}, options2.chart), {
          width,
          height,
          // Disable interactive features for SSR
          toolbar: { show: false },
          animations: { enabled: false }
        })
      });
      const chart = new ApexCharts(
        /** @type {HTMLElement} */
        virtualEl,
        ssrConfig
      );
      try {
        yield chart.render();
        const svgString = this._extractSVGString(chart, scale);
        chart.destroy();
        return svgString;
      } catch (error) {
        chart.destroy();
        throw new Error(
          `SSR rendering failed: ${/** @type {any} */
          error.message}`
        );
      }
    });
  }
  /**
   * Generate hydration-ready HTML with embedded configuration
   *
   * @param {Record<string, any>} options - Chart configuration
   * @param {{ width?: number, height?: number, scale?: number, className?: string }} [ssrOptions] - SSR-specific options
   * @returns {Promise<string>} HTML string with SVG and hydration data
   *
   * @example
   * const html = await SSRRenderer.renderToHTML({
   *   series: [{ data: [30, 40, 35] }],
   *   chart: { type: 'bar' }
   * }, {
   *   width: 500,
   *   height: 300
   * });
   */
  static renderToHTML(_0) {
    return __async(this, arguments, function* (options2, ssrOptions = {}) {
      const { className = "" } = ssrOptions;
      const svgString = yield this.renderToString(options2, ssrOptions);
      const dataConfig = this._encodeConfig(options2);
      const wrapperClass = `apexcharts-ssr-wrapper${className ? " " + className : ""}`;
      return `<div class="${wrapperClass}" data-apexcharts-hydrate data-apexcharts-config="${dataConfig}">
${svgString}
</div>`;
    });
  }
  /**
   * Create a virtual DOM element for SSR rendering
   * @private
   * @param {number} width
   * @param {number} height
   */
  static _createVirtualElement(width, height) {
    if (Environment.isBrowser()) {
      const el = document.createElement("div");
      el.style.width = `${width}px`;
      el.style.height = `${height}px`;
      return el;
    }
    return {
      _ssrWidth: width,
      _ssrHeight: height,
      _ssrMode: true,
      nodeType: 1,
      nodeName: "DIV",
      children: (
        /** @type {any[]} */
        []
      ),
      style: {},
      classList: {
        add: () => {
        },
        remove: () => {
        },
        contains: () => false
      },
      /**
       * @param {any} child
       */
      appendChild(child) {
        this.children.push(child);
      },
      /**
       * @param {any} child
       */
      removeChild(child) {
        const index = this.children.indexOf(child);
        if (index > -1) this.children.splice(index, 1);
      },
      querySelector() {
        return null;
      },
      querySelectorAll() {
        return [];
      },
      getElementsByClassName() {
        return [];
      },
      getAttribute() {
        return null;
      },
      setAttribute() {
      },
      removeAttribute() {
      },
      hasAttribute() {
        return false;
      },
      getBoundingClientRect() {
        return {
          width: this._ssrWidth,
          height: this._ssrHeight,
          top: 0,
          left: 0,
          right: this._ssrWidth,
          bottom: this._ssrHeight,
          x: 0,
          y: 0
        };
      },
      get parentNode() {
        return null;
      },
      get isConnected() {
        return true;
      },
      getRootNode() {
        return this;
      }
    };
  }
  /**
   * Extract SVG string from rendered chart
   * @private
   * @param {any} chart
   */
  static _extractSVGString(chart, scale = 1) {
    const w = chart.w;
    if (!w || !w.dom || !w.dom.Paper) {
      throw new Error("Chart not properly initialized");
    }
    const svgNode = w.dom.Paper.node;
    if (Environment.isBrowser() && svgNode instanceof SVGElement) {
      const serializer = new XMLSerializer();
      let svgString = serializer.serializeToString(svgNode);
      if (scale !== 1) {
        svgString = this._applyScale(svgString, scale);
      }
      return svgString;
    }
    if (svgNode && typeof svgNode.toString === "function") {
      let svgString = svgNode.toString();
      if (scale !== 1) {
        svgString = this._applyScale(svgString, scale);
      }
      return svgString;
    }
    throw new Error("Unable to extract SVG string from chart");
  }
  /**
   * Apply scale transformation to SVG string
   * @private
   * @param {string} svgString
   * @param {number} scale
   */
  static _applyScale(svgString, scale) {
    const widthMatch = svgString.match(/width="([^"]+)"/);
    const heightMatch = svgString.match(/height="([^"]+)"/);
    if (widthMatch && heightMatch) {
      const width = parseFloat(widthMatch[1]);
      const height = parseFloat(heightMatch[1]);
      const scaledWidth = width * scale;
      const scaledHeight = height * scale;
      svgString = svgString.replace(/width="[^"]+"/, `width="${scaledWidth}"`).replace(/height="[^"]+"/, `height="${scaledHeight}"`);
    }
    return svgString;
  }
  /**
   * Encode configuration for client-side hydration
   * @private
   * @param {Record<string, any>} config
   */
  static _encodeConfig(config) {
    try {
      const json = JSON.stringify(config);
      if (typeof Buffer !== "undefined") {
        return Buffer.from(json).toString("base64");
      } else if (typeof btoa !== "undefined") {
        return btoa(json);
      }
      return encodeURIComponent(json);
    } catch (error) {
      throw new Error(
        `Failed to encode config: ${/** @type {any} */
        error.message}`
      );
    }
  }
  /**
   * Decode configuration from hydration data
   * @private
   * @param {string} encodedConfig
   */
  static _decodeConfig(encodedConfig) {
    try {
      let json;
      if (typeof Buffer !== "undefined") {
        json = Buffer.from(encodedConfig, "base64").toString("utf-8");
      } else if (typeof atob !== "undefined") {
        json = atob(encodedConfig);
      } else {
        json = decodeURIComponent(encodedConfig);
      }
      return JSON.parse(json);
    } catch (error) {
      throw new Error(
        `Failed to decode config: ${/** @type {any} */
        error.message}`
      );
    }
  }
}
class Hydration {
  /**
   * Hydrate a single server-rendered chart
   *
   * @param {HTMLElement} el - Container element with data-apexcharts-hydrate attribute
   * @param {object} clientOptions - Optional config overrides for client-side (e.g., enable animations)
   * @returns {ApexCharts} Hydrated chart instance
   *
   * @example
   * // Hydrate with default settings
   * const chart = Hydration.hydrate(document.getElementById('my-chart'));
   *
   * @example
   * // Hydrate with custom options
   * const chart = Hydration.hydrate(element, {
   *   chart: {
   *     animations: { enabled: true, speed: 800 }
   *   }
   * });
   */
  static hydrate(el, clientOptions = {}) {
    if (!Environment.isBrowser()) {
      throw new Error("Hydration can only be performed in browser environment");
    }
    if (!el) {
      throw new Error("Element is required for hydration");
    }
    if (!el.hasAttribute("data-apexcharts-hydrate")) {
      throw new Error("Element does not have data-apexcharts-hydrate attribute");
    }
    const configAttr = el.getAttribute("data-apexcharts-config");
    if (!configAttr) {
      throw new Error("Element is missing data-apexcharts-config attribute");
    }
    const ssrConfig = this._decodeConfig(configAttr);
    const config = this._mergeConfigs(ssrConfig, clientOptions);
    const ssrContent = el.innerHTML;
    const chart = new ApexCharts(el, config);
    const rect = el.getBoundingClientRect();
    el.style.width = `${rect.width}px`;
    el.style.height = `${rect.height}px`;
    el.innerHTML = "";
    el.removeAttribute("data-apexcharts-hydrate");
    el.removeAttribute("data-apexcharts-config");
    chart.render().then(() => {
      el.setAttribute("data-apexcharts-hydrated", "true");
      el.style.width = "";
      el.style.height = "";
      const event = new CustomEvent("apexcharts:hydrated", {
        detail: { chart, ssrContent }
      });
      el.dispatchEvent(event);
    }).catch((error) => {
      console.error("ApexCharts hydration failed:", error);
      el.innerHTML = ssrContent;
      el.setAttribute("data-apexcharts-hydrate", "");
      el.setAttribute("data-apexcharts-config", configAttr);
      throw error;
    });
    return chart;
  }
  /**
   * Auto-hydrate all server-rendered charts on the page
   *
   * @param {string} selector - CSS selector for containers (default: '[data-apexcharts-hydrate]')
   * @param {object} clientOptions - Optional config overrides applied to all charts
   * @returns {ApexCharts[]} Array of hydrated chart instances
   *
   * @example
   * // Hydrate all charts on page load
   * document.addEventListener('DOMContentLoaded', () => {
   *   ApexCharts.hydrateAll();
   * });
   *
   * @example
   * // Hydrate with animations enabled
   * ApexCharts.hydrateAll('[data-apexcharts-hydrate]', {
   *   chart: { animations: { enabled: true } }
   * });
   */
  static hydrateAll(selector = "[data-apexcharts-hydrate]", clientOptions = {}) {
    if (!Environment.isBrowser()) {
      throw new Error("Hydration can only be performed in browser environment");
    }
    const elements = document.querySelectorAll(selector);
    if (elements.length === 0) {
      console.warn(`No elements found matching selector: ${selector}`);
      return [];
    }
    const charts = [];
    elements.forEach((el) => {
      try {
        const chart = this.hydrate(
          /** @type {HTMLElement} */
          el,
          clientOptions
        );
        charts.push(chart);
      } catch (error) {
        console.error("Failed to hydrate element:", el, error);
      }
    });
    return charts;
  }
  /**
   * Check if an element has been hydrated
   *
   * @param {HTMLElement} el - Element to check
   * @returns {boolean} True if element has been hydrated
   */
  static isHydrated(el) {
    if (!el) return false;
    return el.hasAttribute("data-apexcharts-hydrated");
  }
  /**
   * Decode configuration from base64-encoded data attribute
   * @private
   * @param {string} encodedConfig
   * @returns {any}
   */
  static _decodeConfig(encodedConfig) {
    try {
      let json;
      if (typeof atob !== "undefined") {
        json = atob(encodedConfig);
      } else if (typeof Buffer !== "undefined") {
        json = Buffer.from(encodedConfig, "base64").toString("utf-8");
      } else {
        json = decodeURIComponent(encodedConfig);
      }
      return JSON.parse(json);
    } catch (error) {
      throw new Error(
        `Failed to decode chart config: ${/** @type {any} */
        error.message}`
      );
    }
  }
  /**
   * Merge SSR configuration with client-side overrides
   * @private
   * @param {Record<string, any>} ssrConfig
   * @param {Record<string, any>} clientOptions
   * @returns {any}
   */
  static _mergeConfigs(ssrConfig, clientOptions) {
    var _a, _b, _c;
    const merged = __spreadValues(__spreadValues({}, ssrConfig), clientOptions);
    if (ssrConfig.chart || clientOptions.chart) {
      merged.chart = __spreadValues(__spreadValues({}, ssrConfig.chart), clientOptions.chart);
      if (merged.chart.animations === void 0 || merged.chart.animations.enabled === false) {
        merged.chart.animations = __spreadProps(__spreadValues({}, merged.chart.animations || {}), {
          enabled: true
        });
      }
      if (((_a = clientOptions.chart) == null ? void 0 : _a.toolbar) === void 0 && ((_c = (_b = ssrConfig.chart) == null ? void 0 : _b.toolbar) == null ? void 0 : _c.show) === false) {
        merged.chart.toolbar = __spreadProps(__spreadValues({}, merged.chart.toolbar || {}), {
          show: true
        });
      }
    }
    return merged;
  }
}
ApexCharts.renderToString = SSRRenderer.renderToString.bind(SSRRenderer);
ApexCharts.renderToHTML = SSRRenderer.renderToHTML.bind(SSRRenderer);
ApexCharts.hydrate = Hydration.hydrate.bind(Hydration);
ApexCharts.hydrateAll = Hydration.hydrateAll.bind(Hydration);
ApexCharts.isHydrated = Hydration.isHydrated.bind(Hydration);
export {
  Hydration,
  SSRRenderer,
  ApexCharts as default
};