function throttleAnimationFrame(func) {
  var wait = false;
  return function () {
    if (!wait) {
      wait = true;
      requestAnimationFrame(function () {
        func();
        wait = false;
      });
    }
  };
}
var antiOverflowAlgo = function antiOverflowAlgo(_ref) {
  var fontSizePx = _ref.fontSizePx,
    minFontSizePx = _ref.minFontSizePx,
    fontSizePrecisionPx = _ref.fontSizePrecisionPx,
    updateFontSizePx = _ref.updateFontSizePx,
    breakPred = _ref.breakPredicate;
  var maxIterCount = Math.ceil(1 / fontSizePrecisionPx); // 1 px should always be enough.
  var iterCount = 0;
  while (fontSizePx > minFontSizePx && iterCount < maxIterCount) {
    if (breakPred()) break;
    fontSizePx = updateFontSizePx(fontSizePx - fontSizePrecisionPx);
    iterCount++;
  }
};
var getContentWidth = function getContentWidth(element) {
  var computedStyle = getComputedStyle(element);
  return element.clientWidth - parseFloat(computedStyle.paddingLeft) - parseFloat(computedStyle.paddingRight);
};
var getContentHeight = function getContentHeight(element) {
  var computedStyle = getComputedStyle(element);
  return element.clientHeight - parseFloat(computedStyle.paddingTop) - parseFloat(computedStyle.paddingBottom);
};
var multilineAlgo = function multilineAlgo(opts) {
  opts.innerEl.style.whiteSpace = 'nowrap';
  onelineAlgo(opts);
  if (opts.innerEl.scrollWidth > getContentWidth(opts.containerEl)) {
    opts.innerEl.style.whiteSpace = 'normal';
  }
};
var onelineAlgo = function onelineAlgo(_ref2) {
  var innerEl = _ref2.innerEl,
    containerEl = _ref2.containerEl,
    fontSizePx = _ref2.fontSizePx,
    minFontSizePx = _ref2.minFontSizePx,
    maxFontSizePx = _ref2.maxFontSizePx,
    fontSizePrecisionPx = _ref2.fontSizePrecisionPx,
    updateFontSizePx = _ref2.updateFontSizePx;
  var maxIterCount = 10;
  var iterCount = 0;
  var prevOverflowFactor = 1;
  while (iterCount < maxIterCount) {
    var w0 = innerEl.scrollWidth;
    var w1 = getContentWidth(containerEl);
    var canGrow = fontSizePx < maxFontSizePx && w0 < w1;
    var canShrink = fontSizePx > minFontSizePx && w0 > w1;
    var overflowFactor = w0 / w1;

    // The browser cannot render a difference based on the previous font size update
    if (prevOverflowFactor === overflowFactor) {
      break;
    }
    if (!(canGrow || canShrink)) {
      break;
    }
    var updatePx = fontSizePx / overflowFactor - fontSizePx;
    var prevFontSizePx = fontSizePx;
    fontSizePx = updateFontSizePx(fontSizePx + updatePx);
    if (Math.abs(fontSizePx - prevFontSizePx) <= fontSizePrecisionPx) {
      break;
    }
    prevOverflowFactor = overflowFactor;
    iterCount++;
  }
  antiOverflowAlgo({
    fontSizePx: fontSizePx,
    minFontSizePx: minFontSizePx,
    updateFontSizePx: updateFontSizePx,
    fontSizePrecisionPx: fontSizePrecisionPx,
    breakPredicate: function breakPredicate() {
      return innerEl.scrollWidth <= getContentWidth(containerEl);
    }
  });
};
var boxAlgo = function boxAlgo(_ref3) {
  var innerEl = _ref3.innerEl,
    containerEl = _ref3.containerEl,
    fontSizePx = _ref3.fontSizePx,
    minFontSizePx = _ref3.minFontSizePx,
    maxFontSizePx = _ref3.maxFontSizePx,
    fontSizePrecisionPx = _ref3.fontSizePrecisionPx,
    updateFontSizePx = _ref3.updateFontSizePx;
  var maxIterCount = 100;
  fontSizePx = updateFontSizePx((maxFontSizePx - minFontSizePx) * 0.5);
  var updatePx = (maxFontSizePx - minFontSizePx) * 0.25;
  var iterCount = 0;
  while (updatePx > fontSizePrecisionPx && iterCount < maxIterCount) {
    var w0 = innerEl.scrollWidth;
    var w1 = getContentWidth(containerEl);
    var h0 = innerEl.scrollHeight;
    var h1 = getContentHeight(containerEl);
    if (w0 === w1 && h0 === h1) break;

    /**
     * Use `<=` rather than `<` since equality is possible even though there is
     * room for resizing in the other dimension.
     */
    if (fontSizePx < maxFontSizePx && w0 <= w1 && h0 <= h1) {
      fontSizePx = updateFontSizePx(fontSizePx + updatePx);
    } else if (fontSizePx > minFontSizePx && (w0 > w1 || h0 > h1)) {
      fontSizePx = updateFontSizePx(fontSizePx - updatePx);
    }
    updatePx *= 0.5; // Binary search. Don't change this number.
    iterCount++;
  }
  antiOverflowAlgo({
    fontSizePx: fontSizePx,
    minFontSizePx: minFontSizePx,
    updateFontSizePx: updateFontSizePx,
    fontSizePrecisionPx: fontSizePrecisionPx,
    breakPredicate: function breakPredicate() {
      return innerEl.scrollWidth <= getContentWidth(containerEl) && innerEl.scrollHeight <= getContentHeight(containerEl);
    }
  });
};
export function updateTextSize(_ref4) {
  var innerEl = _ref4.innerEl,
    containerEl = _ref4.containerEl,
    _ref4$mode = _ref4.mode,
    mode = _ref4$mode === void 0 ? 'multiline' : _ref4$mode,
    _ref4$minFontSizePx = _ref4.minFontSizePx,
    minFontSizePx = _ref4$minFontSizePx === void 0 ? 8 : _ref4$minFontSizePx,
    _ref4$maxFontSizePx = _ref4.maxFontSizePx,
    maxFontSizePx = _ref4$maxFontSizePx === void 0 ? 160 : _ref4$maxFontSizePx,
    _ref4$fontSizePrecisi = _ref4.fontSizePrecisionPx,
    fontSizePrecisionPx = _ref4$fontSizePrecisi === void 0 ? 0.1 : _ref4$fontSizePrecisi,
    _ref4$scrollToEnd = _ref4.scrollToEnd,
    scrollToEnd = _ref4$scrollToEnd === void 0 ? false : _ref4$scrollToEnd;
  var t0 = performance.now();
  if (!isFinite(minFontSizePx)) {
    throw new Error("Invalid minFontSizePx (".concat(minFontSizePx, ")"));
  }
  if (!isFinite(minFontSizePx)) {
    throw new Error("Invalid maxFontSizePx (".concat(maxFontSizePx, ")"));
  }
  if (!isFinite(fontSizePrecisionPx) || fontSizePrecisionPx === 0) {
    throw new Error("Invalid fontSizePrecisionPx (".concat(fontSizePrecisionPx, ")"));
  }
  if (containerEl.children.length > 1) {
    console.warn("AutoTextSize has ".concat(containerEl.children.length - 1, " siblings. This may interfere with the algorithm."));
  }
  var containerStyles = {
    display: 'flex',
    alignItems: 'start'
  };
  var innerStyles = {
    display: 'block'
  };
  if (mode === 'oneline') {
    innerStyles.whiteSpace = 'nowrap';
  } else if (mode === 'multiline') {
    innerStyles.wordBreak = 'break-word';
  } else if (mode === 'box') {
    innerStyles.whiteSpace = 'pre-wrap';
    innerStyles.wordBreak = 'break-word';
  } else if (mode === 'boxoneline') {
    innerStyles.whiteSpace = 'nowrap';
  }
  Object.assign(containerEl.style, containerStyles);
  Object.assign(innerEl.style, innerStyles);
  var fontSizeStr = window.getComputedStyle(innerEl, null).getPropertyValue('font-size');
  var fontSizePx = parseFloat(fontSizeStr);
  var iterations = 0;
  var updateFontSizePx = function updateFontSizePx(px) {
    px = Math.min(Math.max(px, minFontSizePx), maxFontSizePx);
    // console.debug(
    //   `setFontSizePx ${px > fontSizePx ? "up" : "down"} (abs: ${
    //     px / fontSizePx
    //   }, rel: ${(px - fontSizePx) / fontSizePx}) ${px}`
    // );
    fontSizePx = px;
    innerEl.style.fontSize = "".concat(fontSizePx, "px");
    iterations++;
    return fontSizePx;
  };
  if (fontSizePx > maxFontSizePx || fontSizePx < minFontSizePx) {
    updateFontSizePx(fontSizePx);
  }
  var algoOpts = {
    innerEl: innerEl,
    containerEl: containerEl,
    fontSizePx: fontSizePx,
    minFontSizePx: minFontSizePx,
    maxFontSizePx: maxFontSizePx,
    fontSizePrecisionPx: fontSizePrecisionPx,
    updateFontSizePx: updateFontSizePx
  };
  if (mode === 'oneline') {
    onelineAlgo(algoOpts);
  } else if (mode === 'multiline') {
    multilineAlgo(algoOpts);
  } else if (mode === 'box') {
    boxAlgo(algoOpts);
  } else if (mode === 'boxoneline') {
    boxAlgo(algoOpts);
  }

  // 如果启用了 scrollToEnd，滚动到内容末端
  if (scrollToEnd) {
    // 使用 requestAnimationFrame 确保在 DOM 更新后执行滚动
    requestAnimationFrame(function () {
      if (mode === 'oneline' || mode === 'boxoneline') {
        // 对于单行模式，滚动到最右端
        var maxScrollLeft = Math.max(0, innerEl.scrollWidth - innerEl.clientWidth);
        innerEl.scrollLeft = maxScrollLeft;
      } else {
        // 对于多行模式，滚动到最底端
        var maxScrollTop = Math.max(0, innerEl.scrollHeight - innerEl.clientHeight);
        innerEl.scrollTop = maxScrollTop;
      }
    });
  }
}
export function autoTextSize(_ref5) {
  var innerEl = _ref5.innerEl,
    containerEl = _ref5.containerEl,
    mode = _ref5.mode,
    minFontSizePx = _ref5.minFontSizePx,
    maxFontSizePx = _ref5.maxFontSizePx,
    fontSizePrecisionPx = _ref5.fontSizePrecisionPx,
    scrollToEnd = _ref5.scrollToEnd;
  var containerDimensions = undefined;
  var throttledUpdateTextSize = throttleAnimationFrame(function () {
    updateTextSize({
      innerEl: innerEl,
      containerEl: containerEl,
      mode: mode,
      maxFontSizePx: maxFontSizePx,
      minFontSizePx: minFontSizePx,
      fontSizePrecisionPx: fontSizePrecisionPx,
      scrollToEnd: scrollToEnd
    });
    containerDimensions = [getContentWidth(containerEl), getContentHeight(containerEl)];
  });
  var resizeObserver = new ResizeObserver(function () {
    var prevContainerDimensions = containerDimensions;
    containerDimensions = [getContentWidth(containerEl), getContentHeight(containerEl)];
    if ((prevContainerDimensions === null || prevContainerDimensions === void 0 ? void 0 : prevContainerDimensions[0]) !== containerDimensions[0] || (prevContainerDimensions === null || prevContainerDimensions === void 0 ? void 0 : prevContainerDimensions[1]) !== containerDimensions[1]) {
      throttledUpdateTextSize();
    }
  });
  resizeObserver.observe(containerEl);
  throttledUpdateTextSize.disconnect = function () {
    return resizeObserver.disconnect();
  };
  return throttledUpdateTextSize;
}