import { nothing, svg } from "lit";
import { BorderRadiusPosition, Priority, InstrumentState } from "../../navigation-instruments/types.js";
import { AdviceState, AdviceType } from "../../navigation-instruments/watch/advice.js";
import { TickmarkStyle, tickmarkColor } from "../../navigation-instruments/watch/tickmark.js";
import { valueToY, valueToX, adjustRectWidthForStroke, adjustRectHeightForStroke } from "../../svghelpers/stroke-aware.js";
import { SetpointVisualState, SetpointColorMode, generateSetpointId, SETPOINT_ANIMATION_CSS_VAR, SETPOINT_ANIMATION_DURATION_DEFAULT, drawSetpointMarker, computeAtSetpoint, getSetpointOutwardOffset } from "../../svghelpers/setpoint.js";
var ExternalScaleOrientation = /* @__PURE__ */ ((ExternalScaleOrientation2) => {
  ExternalScaleOrientation2["vertical"] = "vertical";
  ExternalScaleOrientation2["horizontal"] = "horizontal";
  return ExternalScaleOrientation2;
})(ExternalScaleOrientation || {});
var ExternalScaleSide = /* @__PURE__ */ ((ExternalScaleSide2) => {
  ExternalScaleSide2["left"] = "left";
  ExternalScaleSide2["right"] = "right";
  ExternalScaleSide2["top"] = "top";
  ExternalScaleSide2["bottom"] = "bottom";
  return ExternalScaleSide2;
})(ExternalScaleSide || {});
var ScaleType = /* @__PURE__ */ ((ScaleType2) => {
  ScaleType2["regular"] = "regular";
  ScaleType2["condensed"] = "condensed";
  return ScaleType2;
})(ScaleType || {});
var FillMode = /* @__PURE__ */ ((FillMode2) => {
  FillMode2["fill"] = "fill";
  FillMode2["tint"] = "tint";
  return FillMode2;
})(FillMode || {});
var AdvicePosition = /* @__PURE__ */ ((AdvicePosition2) => {
  AdvicePosition2["center"] = "center";
  AdvicePosition2["inner"] = "inner";
  AdvicePosition2["outer"] = "outer";
  return AdvicePosition2;
})(AdvicePosition || {});
var BarContainerStyle = /* @__PURE__ */ ((BarContainerStyle2) => {
  BarContainerStyle2["primary"] = "primary";
  BarContainerStyle2["secondary"] = "secondary";
  return BarContainerStyle2;
})(BarContainerStyle || {});
const EXTERNAL_SCALE_BORDER_RADIUS_CSS_VAR = "--instrument-components-watchface-frame-regular-border-radius";
function parseCssLengthToPx(value, context) {
  if (!value) return void 0;
  const v = value.trim();
  const n = Number.parseFloat(v);
  if (!Number.isFinite(n)) return void 0;
  if (v.endsWith("px")) return n;
  const canComputeStyles = typeof getComputedStyle === "function";
  if (v.endsWith("rem")) {
    if (!canComputeStyles) return void 0;
    const docEl = context?.documentElement ?? (typeof document !== "undefined" ? document.documentElement : void 0);
    if (!docEl) return void 0;
    const rootFontSize = Number.parseFloat(getComputedStyle(docEl).fontSize);
    return Number.isFinite(rootFontSize) ? n * rootFontSize : void 0;
  }
  if (v.endsWith("em")) {
    if (!canComputeStyles) return void 0;
    const el = context?.element;
    if (!el) return void 0;
    const fontSize = Number.parseFloat(getComputedStyle(el).fontSize);
    return Number.isFinite(fontSize) ? n * fontSize : void 0;
  }
  return n;
}
function readExternalScaleBorderRadiusPx(host, scaleType, cssVarName = EXTERNAL_SCALE_BORDER_RADIUS_CSS_VAR) {
  const fallback = scaleType === "condensed" ? 4 : 8;
  if (typeof getComputedStyle !== "function") return fallback;
  const raw = getComputedStyle(host).getPropertyValue(cssVarName).trim();
  const parsed = parseCssLengthToPx(raw, {
    element: host,
    documentElement: (
      // Prefer the element's owning document to support iframes/shadow contexts.
      host.ownerDocument?.documentElement ?? (typeof document !== "undefined" ? document.documentElement : void 0)
    )
  });
  return parsed ?? fallback;
}
function startExternalScaleBorderRadiusObserver(host, onChange) {
  if (typeof MutationObserver === "undefined") return void 0;
  const observer = new MutationObserver(() => onChange());
  const targets = [host];
  let current = host.parentElement;
  while (current) {
    targets.push(current);
    current = current.parentElement;
  }
  const docEl = host.ownerDocument?.documentElement;
  if (docEl) targets.push(docEl);
  for (const t of targets) {
    observer.observe(t, {
      attributes: true,
      attributeFilter: ["class", "style"]
    });
  }
  return observer;
}
function defaultExternalScaleBorderRadiusPx(scaleType) {
  return scaleType === "condensed" ? 4 : 8;
}
function computeExternalScaleEffectiveBorderRadiusPx(config) {
  const fallback = defaultExternalScaleBorderRadiusPx(config.scaleType);
  const r = config.borderRadius;
  return typeof r === "number" && Number.isFinite(r) && r >= 0 ? r : fallback;
}
function computeExternalScaleEffectiveBarThickness(config) {
  const bt = Number.isFinite(config.barThickness) ? config.barThickness : 0;
  if (!config.hasBar) return bt;
  const r = computeExternalScaleEffectiveBorderRadiusPx(config);
  return Math.max(bt, r * 2);
}
function computeExternalScaleEffectiveTickThickness(config) {
  const tt = Number.isFinite(config.tickThickness) ? config.tickThickness : 0;
  if (config.scaleType === "condensed") {
    const condensedMaxThickness = 14;
    return Math.min(tt, condensedMaxThickness);
  }
  return tt;
}
function toExternalScaleLayoutConfig(config) {
  return {
    orientation: config.orientation,
    side: config.side,
    hasBar: config.hasBar,
    hasScale: config.hasScale,
    labels: config.labels,
    barThickness: computeExternalScaleEffectiveBarThickness(config),
    tickThickness: computeExternalScaleEffectiveTickThickness(config),
    labelThickness: config.labelThickness,
    length: config.length,
    scaleType: config.scaleType
  };
}
function computeExternalScaleViewBox(config, layout) {
  if (config.orientation === "vertical") {
    return {
      x: layout.viewBoxPerpStart,
      y: -config.length / 2,
      width: layout.viewBoxThickness,
      height: config.length
    };
  }
  return {
    x: 0,
    y: layout.viewBoxPerpStart,
    width: config.length,
    height: layout.viewBoxThickness
  };
}
function computeMeetScale(viewBoxWidth, viewBoxHeight, containerWidth, containerHeight) {
  const widthScale = viewBoxWidth > 0 ? containerWidth / viewBoxWidth : 1;
  const heightScale = viewBoxHeight > 0 ? containerHeight / viewBoxHeight : 1;
  return Math.min(widthScale, heightScale);
}
function computeFixedAspectRatioScale(config) {
  const { containerMainAxisSize, scaleReferenceSize } = config;
  if (containerMainAxisSize <= 0 || scaleReferenceSize <= 0) {
    return 1;
  }
  return containerMainAxisSize / scaleReferenceSize;
}
function computeScaledThickness(baseThickness, scale) {
  return baseThickness * scale;
}
function computeExternalScaleLayout(config) {
  const barSpace = config.hasBar ? config.barThickness : 0;
  const effectiveTickThickness = computeExternalScaleEffectiveTickThickness(config);
  const scaleSpace = config.hasScale ? effectiveTickThickness : 0;
  const labelSpace = config.labels ? config.labelThickness : 0;
  const thickness = barSpace + scaleSpace + labelSpace;
  const isOutwardPositive2 = config.orientation === "vertical" && config.side === "right" || config.orientation === "horizontal" && config.side === "bottom";
  const viewBoxPerpStart = isOutwardPositive2 ? 0 : -thickness;
  return {
    thickness,
    viewBoxPerpStart,
    viewBoxLength: config.length,
    viewBoxThickness: thickness
  };
}
function isVertical(config) {
  return config.orientation === "vertical";
}
function isOutwardPositive(config) {
  return config.orientation === "vertical" && config.side === "right" || config.orientation === "horizontal" && config.side === "bottom";
}
function rangeIncludesZero(minValue, maxValue) {
  return minValue <= 0 && maxValue >= 0;
}
function calculateAtSetpoint(config) {
  const isTouching = config.touching ?? false;
  return computeAtSetpoint({
    value: config.value,
    setpoint: config.setpoint,
    touching: isTouching,
    auto: config.autoAtSetpoint,
    deadband: config.autoAtSetpointDeadband,
    atSetpointManual: config.atSetpoint
  });
}
function deriveSetpointVisualState(config) {
  const isTouching = config.touching ?? false;
  if (isTouching && config.newSetpoint === void 0) {
    return SetpointVisualState.focus;
  }
  const isAt = calculateAtSetpoint(config);
  if (isAt) {
    const setpointAtZero = config.setpoint !== void 0 && Math.abs(config.setpoint) < config.setpointAtZeroDeadband;
    if (setpointAtZero) {
      return SetpointVisualState.equalZero;
    }
    return SetpointVisualState.equal;
  }
  return SetpointVisualState.notEqual;
}
function deriveSetpointColorMode(config) {
  return config.priority === Priority.enhanced ? SetpointColorMode.enhanced : SetpointColorMode.regular;
}
function deriveSetpointDisabled(config) {
  if (config.setpointDisabled !== void 0) {
    return config.setpointDisabled;
  }
  if (config.setpointOverride) {
    return false;
  }
  if (config.state === InstrumentState.loading || config.state === InstrumentState.off) {
    return true;
  }
  return false;
}
function colors(config) {
  const isEnhanced = config.priority === Priority.enhanced;
  let barFillColor = config.fillMode === "tint" ? isEnhanced ? "var(--instrument-enhanced-tertiary-color)" : "var(--instrument-regular-tertiary-color)" : isEnhanced ? "var(--instrument-enhanced-secondary-color)" : "var(--instrument-regular-secondary-color)";
  let markerFillColor = isEnhanced ? "var(--instrument-enhanced-secondary-color)" : "var(--instrument-regular-secondary-color)";
  let markerStrokeColor = isEnhanced ? "var(--instrument-enhanced-tertiary-color)" : "var(--instrument-regular-tertiary-color)";
  let setpointColor = isEnhanced ? "var(--instrument-enhanced-primary-color)" : "var(--instrument-regular-primary-color)";
  if (config.state === InstrumentState.loading || config.state === InstrumentState.off) {
    barFillColor = "transparent";
    markerFillColor = "var(--instrument-frame-tertiary-color)";
    markerStrokeColor = "var(--instrument-frame-tertiary-color)";
    setpointColor = "var(--instrument-frame-tertiary-color)";
  }
  return { barFillColor, markerFillColor, markerStrokeColor, setpointColor };
}
function convertAdvices(advices, setpoint) {
  return advices.map((a) => {
    const triggered = setpoint !== void 0 && setpoint >= a.min && setpoint <= a.max;
    const state = triggered ? AdviceState.triggered : a.hinted ? AdviceState.hinted : AdviceState.regular;
    return { min: a.min, max: a.max, type: a.type, state };
  });
}
function mainAxisOffset(config) {
  if (isVertical(config)) {
    return (config.paddingStart - config.paddingEnd) / 2;
  }
  return config.paddingStart;
}
function drawingLength(config) {
  return Math.max(0, config.length - config.paddingStart - config.paddingEnd);
}
function valueToMainAxis(config, value) {
  const dLen = drawingLength(config);
  if (isVertical(config)) {
    return valueToY(value, config.minValue, config.maxValue, dLen) + mainAxisOffset(config);
  }
  return valueToX(value, config.minValue, config.maxValue, dLen) + mainAxisOffset(config);
}
function getTickThicknesses(scaleType) {
  const isCondensed = scaleType === "condensed";
  return {
    primary: isCondensed ? 10 : 20,
    secondary: isCondensed ? 4 : 8,
    tertiary: isCondensed ? 2 : 4,
    main: isCondensed ? 10 : 20
  };
}
function tickBasePerp(config) {
  return config.hasBar ? isOutwardPositive(config) ? config.barThickness : -config.barThickness : 0;
}
function tickGap() {
  return 4;
}
function labelGap() {
  return 8;
}
function buildTickLine(config, mainPos, perpStart, perpLen) {
  const stroke = "var(--instrument-frame-tertiary-color)";
  const strokeWidth = 1;
  if (isVertical(config)) {
    const x1 = perpStart;
    const x2 = perpStart + perpLen;
    const y = mainPos;
    return svg`<line x1=${x1} x2=${x2} y1=${y} y2=${y} stroke=${stroke} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>`;
  }
  const y1 = perpStart;
  const y2 = perpStart + perpLen;
  const x = mainPos;
  return svg`<line x1=${x} x2=${x} y1=${y1} y2=${y2} stroke=${stroke} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>`;
}
function generateTickmarksAtInterval(config, interval, perpStart, perpLen, skipValues) {
  const svgs = [];
  const values = [];
  if (interval <= 0 || !Number.isFinite(interval)) return { svgs, values };
  const includesZero = rangeIncludesZero(config.minValue, config.maxValue);
  const pushTick = (v) => {
    if (skipValues.includes(v)) return;
    values.push(v);
    svgs.push(
      buildTickLine(config, valueToMainAxis(config, v), perpStart, perpLen)
    );
  };
  if (includesZero) {
    for (let v = interval; v <= config.maxValue; v += interval) pushTick(v);
    for (let v = -interval; v >= config.minValue; v -= interval) pushTick(v);
  } else {
    const startValue = Math.ceil(config.minValue / interval) * interval;
    for (let v = startValue; v <= config.maxValue; v += interval) pushTick(v);
  }
  return { svgs, values };
}
function generateTickmarks(config) {
  if (!config.hasScale) return [];
  const svgs = [];
  const skipValues = [];
  const base = tickBasePerp(config);
  const gap = tickGap();
  const tickmarksStart = isOutwardPositive(config) ? base + gap : base - gap;
  const { primary, secondary, tertiary, main } = getTickThicknesses(
    config.scaleType
  );
  if (rangeIncludesZero(config.minValue, config.maxValue)) {
    const isAtBoundary = 0 === config.minValue || 0 === config.maxValue;
    const shouldSkip = config.scaleBackground && isAtBoundary;
    if (!shouldSkip) {
      const perpLen = primary;
      const perpStart = tickmarksStart;
      svgs.push(
        buildTickLine(
          config,
          valueToMainAxis(config, 0),
          perpStart,
          isOutwardPositive(config) ? perpLen : -perpLen
        )
      );
    }
    skipValues.push(0);
  }
  if (config.mainTickmarks) {
    const start = config.frameStyle === "flat" ? base : tickmarksStart;
    const mainLen = config.frameStyle === "flat" ? main + 4 : main;
    const dirLen = isOutwardPositive(config) ? mainLen : -mainLen;
    const mainTickValues = config.mainTickmarks.length > 0 ? config.mainTickmarks : [config.minValue, 0, config.maxValue];
    for (const value of mainTickValues) {
      if (value < config.minValue || value > config.maxValue) continue;
      if (config.scaleBackground && (value === config.minValue || value === config.maxValue)) {
        skipValues.push(value);
        continue;
      }
      svgs.push(
        buildTickLine(config, valueToMainAxis(config, value), start, dirLen)
      );
      skipValues.push(value);
    }
  }
  if (config.primaryTickmarkInterval !== void 0 && config.primaryTickmarkInterval > 0) {
    const { svgs: s, values } = generateTickmarksAtInterval(
      config,
      config.primaryTickmarkInterval,
      tickmarksStart,
      isOutwardPositive(config) ? primary : -primary,
      skipValues
    );
    svgs.push(...s);
    skipValues.push(...values);
  }
  if (config.secondaryTickmarkInterval !== void 0 && config.secondaryTickmarkInterval > 0) {
    const { svgs: s } = generateTickmarksAtInterval(
      config,
      config.secondaryTickmarkInterval,
      tickmarksStart,
      isOutwardPositive(config) ? secondary : -secondary,
      skipValues
    );
    svgs.push(...s);
  }
  if (config.tertiaryTickmarkInterval !== void 0 && config.tertiaryTickmarkInterval > 0) {
    const { svgs: s } = generateTickmarksAtInterval(
      config,
      config.tertiaryTickmarkInterval,
      tickmarksStart,
      isOutwardPositive(config) ? tertiary : -tertiary,
      skipValues
    );
    svgs.push(...s);
  }
  return svgs;
}
function generateLabels(config) {
  if (!config.labels || config.primaryTickmarkInterval === void 0) return [];
  const interval = config.primaryTickmarkInterval;
  if (interval <= 0 || !Number.isFinite(interval)) return [];
  const fontFamily = "var(--font-family-main)";
  const fontColor = "var(--instrument-tick-mark-label-secondary-color)";
  const fontSize = "calc(var(--global-typography-ui-label-font-size) / var(--scale, 1))";
  const base = tickBasePerp(config);
  const effectiveTickThickness = computeExternalScaleEffectiveTickThickness(config);
  const labelPos = isOutwardPositive(config) ? base + (config.hasScale ? effectiveTickThickness : 0) + labelGap() : base - (config.hasScale ? effectiveTickThickness : 0) - labelGap();
  const includesZero = rangeIncludesZero(config.minValue, config.maxValue);
  const labels = [];
  const push = (v) => {
    const main = valueToMainAxis(config, v);
    if (isVertical(config)) {
      const x2 = labelPos;
      const y2 = main;
      const anchor = isOutwardPositive(config) ? "start" : "end";
      labels.push(
        svg`<text x=${x2} y=${y2} text-anchor=${anchor} dominant-baseline="middle" font-family=${fontFamily} style="font-size: ${fontSize}" fill=${fontColor}>${v}</text>`
      );
      return;
    }
    const y = labelPos;
    const x = main;
    const baseline = isOutwardPositive(config) ? "hanging" : "auto";
    labels.push(
      svg`<text x=${x} y=${y} text-anchor="middle" dominant-baseline=${baseline} font-family=${fontFamily} style="font-size: ${fontSize}" fill=${fontColor}>${v}</text>`
    );
  };
  if (includesZero) {
    for (let v = 0; v <= config.maxValue; v += interval) push(v);
    for (let v = -interval; v >= config.minValue; v -= interval) push(v);
  } else {
    const startValue = Math.ceil(config.minValue / interval) * interval;
    for (let v = startValue; v <= config.maxValue; v += interval) push(v);
  }
  return labels;
}
function generateBarContainer(config) {
  if (!config.hasBar) return nothing;
  const borderRadiusFallback = config.scaleType === "condensed" ? 4 : 8;
  const borderRadiusValue = config.borderRadius ?? borderRadiusFallback;
  const strokeWidth = 1;
  let fillColor;
  if (config.barContainerStyle !== void 0) {
    fillColor = config.barContainerStyle === "secondary" ? "var(--instrument-frame-secondary-color)" : "var(--instrument-frame-primary-color)";
  } else {
    fillColor = config.scaleBackground ? "var(--instrument-frame-secondary-color)" : "var(--instrument-frame-primary-color)";
  }
  const strokeColor = "var(--instrument-frame-tertiary-color)";
  const dLen = drawingLength(config);
  const axisShift = mainAxisOffset(config);
  let shouldRoundTopLeft = true;
  let shouldRoundTopRight = true;
  let shouldRoundBottomLeft = true;
  let shouldRoundBottomRight = true;
  if (config.borderRadiusPosition) {
    if (config.borderRadiusPosition === BorderRadiusPosition.middleChild || config.borderRadiusPosition === BorderRadiusPosition.middleRoundedChild) {
      shouldRoundTopLeft = false;
      shouldRoundTopRight = false;
      shouldRoundBottomLeft = false;
      shouldRoundBottomRight = false;
    } else if (isVertical(config)) {
      const isRight = config.side === "right";
      const isInner = config.borderRadiusPosition === BorderRadiusPosition.innerFirstChild;
      if (isRight) {
        shouldRoundTopLeft = isInner;
        shouldRoundBottomLeft = isInner;
        shouldRoundTopRight = !isInner;
        shouldRoundBottomRight = !isInner;
      } else {
        shouldRoundTopLeft = !isInner;
        shouldRoundBottomLeft = !isInner;
        shouldRoundTopRight = isInner;
        shouldRoundBottomRight = isInner;
      }
    } else {
      const isBottom2 = config.side === "bottom";
      const isInner = config.borderRadiusPosition === BorderRadiusPosition.innerFirstChild;
      if (isBottom2) {
        shouldRoundTopLeft = isInner;
        shouldRoundTopRight = isInner;
        shouldRoundBottomLeft = !isInner;
        shouldRoundBottomRight = !isInner;
      } else {
        shouldRoundTopLeft = !isInner;
        shouldRoundTopRight = !isInner;
        shouldRoundBottomLeft = isInner;
        shouldRoundBottomRight = isInner;
      }
    }
  }
  const r = borderRadiusValue;
  const allCornersRounded = shouldRoundTopLeft && shouldRoundTopRight && shouldRoundBottomLeft && shouldRoundBottomRight;
  const noCornersRounded = !shouldRoundTopLeft && !shouldRoundTopRight && !shouldRoundBottomLeft && !shouldRoundBottomRight;
  if (isVertical(config)) {
    let rectX2 = isOutwardPositive(config) ? 0 : -config.barThickness;
    let rectY2 = -dLen / 2 + axisShift;
    let rectWidth2 = config.barThickness;
    let rectHeight2 = dLen;
    const isRight = config.side === "right";
    let viewBoxMinX;
    let viewBoxMaxX;
    if (config.scaleBackground) {
      if (isRight) {
        viewBoxMinX = 0;
        viewBoxMaxX = config.barThickness + 1;
      } else {
        viewBoxMinX = -config.barThickness - 1;
        viewBoxMaxX = 0;
      }
    } else {
      viewBoxMinX = isRight ? 0 : -config.barThickness;
      viewBoxMaxX = isRight ? config.barThickness : 0;
    }
    const adjustedX2 = adjustRectWidthForStroke(
      rectX2,
      rectWidth2,
      viewBoxMinX,
      viewBoxMaxX,
      strokeWidth
    );
    rectX2 = adjustedX2.x;
    rectWidth2 = adjustedX2.width;
    const adjustedY2 = adjustRectHeightForStroke(
      rectY2,
      rectHeight2,
      -dLen / 2 + axisShift,
      dLen / 2 + axisShift,
      strokeWidth
    );
    rectY2 = adjustedY2.y;
    rectHeight2 = adjustedY2.height;
    if (allCornersRounded || noCornersRounded) {
      const rx = allCornersRounded ? r : 0;
      const ry = allCornersRounded ? r : 0;
      if (config.scaleBackground) {
        const isRight2 = config.side === "right";
        let strokePath;
        if (isRight2) {
          strokePath = `M ${rectX2} ${rectY2 + (noCornersRounded ? 0 : r)} L ${rectX2} ${rectY2 + rectHeight2 - (noCornersRounded ? 0 : r)}`;
          if (!noCornersRounded)
            strokePath += ` Q ${rectX2} ${rectY2 + rectHeight2} ${rectX2 + r} ${rectY2 + rectHeight2}`;
          strokePath += ` L ${rectX2 + rectWidth2 - (noCornersRounded ? 0 : r)} ${rectY2 + rectHeight2}`;
          if (!noCornersRounded)
            strokePath += ` Q ${rectX2 + rectWidth2} ${rectY2 + rectHeight2} ${rectX2 + rectWidth2} ${rectY2 + rectHeight2 - r}`;
          strokePath += ` M ${rectX2 + rectWidth2} ${rectY2 + (noCornersRounded ? 0 : r)}`;
          if (!noCornersRounded)
            strokePath += ` Q ${rectX2 + rectWidth2} ${rectY2} ${rectX2 + rectWidth2 - r} ${rectY2}`;
          strokePath += ` L ${rectX2 + (noCornersRounded ? 0 : r)} ${rectY2}`;
          if (!noCornersRounded)
            strokePath += ` Q ${rectX2} ${rectY2} ${rectX2} ${rectY2 + r}`;
        } else {
          strokePath = `M ${rectX2 + (noCornersRounded ? 0 : r)} ${rectY2}`;
          strokePath += ` L ${rectX2 + rectWidth2 - (noCornersRounded ? 0 : r)} ${rectY2}`;
          if (!noCornersRounded)
            strokePath += ` Q ${rectX2 + rectWidth2} ${rectY2} ${rectX2 + rectWidth2} ${rectY2 + r}`;
          strokePath += ` L ${rectX2 + rectWidth2} ${rectY2 + rectHeight2 - (noCornersRounded ? 0 : r)}`;
          if (!noCornersRounded)
            strokePath += ` Q ${rectX2 + rectWidth2} ${rectY2 + rectHeight2} ${rectX2 + rectWidth2 - r} ${rectY2 + rectHeight2}`;
          strokePath += ` L ${rectX2 + (noCornersRounded ? 0 : r)} ${rectY2 + rectHeight2}`;
          if (!noCornersRounded)
            strokePath += ` Q ${rectX2} ${rectY2 + rectHeight2} ${rectX2} ${rectY2 + rectHeight2 - r}`;
          strokePath += ` M ${rectX2} ${rectY2 + (noCornersRounded ? 0 : r)}`;
          if (!noCornersRounded)
            strokePath += ` Q ${rectX2} ${rectY2} ${rectX2 + r} ${rectY2}`;
        }
        return svg`
          <rect x=${rectX2} y=${rectY2} width=${rectWidth2} height=${rectHeight2} rx=${rx} ry=${ry} fill=${fillColor} stroke="none"/>
          <path d="${strokePath}" fill="none" stroke=${strokeColor} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>
        `;
      }
      return svg`<rect x=${rectX2} y=${rectY2} width=${rectWidth2} height=${rectHeight2} rx=${rx} ry=${ry} fill=${fillColor} stroke=${strokeColor} vector-effect="non-scaling-stroke"/>`;
    }
    const x2 = rectX2;
    const y2 = rectY2;
    const w2 = rectWidth2;
    const h2 = rectHeight2;
    let path2 = `M ${x2 + (shouldRoundTopLeft ? r : 0)} ${y2}`;
    path2 += ` L ${x2 + w2 - (shouldRoundTopRight ? r : 0)} ${y2}`;
    if (shouldRoundTopRight) {
      path2 += ` Q ${x2 + w2} ${y2} ${x2 + w2} ${y2 + r}`;
    }
    path2 += ` L ${x2 + w2} ${y2 + h2 - (shouldRoundBottomRight ? r : 0)}`;
    if (shouldRoundBottomRight) {
      path2 += ` Q ${x2 + w2} ${y2 + h2} ${x2 + w2 - r} ${y2 + h2}`;
    }
    path2 += ` L ${x2 + (shouldRoundBottomLeft ? r : 0)} ${y2 + h2}`;
    if (shouldRoundBottomLeft) {
      path2 += ` Q ${x2} ${y2 + h2} ${x2} ${y2 + h2 - r}`;
    }
    path2 += ` L ${x2} ${y2 + (shouldRoundTopLeft ? r : 0)}`;
    if (shouldRoundTopLeft) {
      path2 += ` Q ${x2} ${y2} ${x2 + r} ${y2}`;
    }
    path2 += ` Z`;
    if (config.scaleBackground) {
      const isRight2 = config.side === "right";
      let strokePath;
      if (isRight2) {
        strokePath = `M ${x2} ${y2 + (shouldRoundTopLeft ? r : 0)}`;
        if (shouldRoundTopLeft) strokePath += ` Q ${x2} ${y2} ${x2 + r} ${y2}`;
        strokePath += ` L ${x2 + w2 - (shouldRoundTopRight ? r : 0)} ${y2}`;
        if (shouldRoundTopRight)
          strokePath += ` Q ${x2 + w2} ${y2} ${x2 + w2} ${y2 + r}`;
        strokePath += ` M ${x2 + w2} ${y2 + h2 - (shouldRoundBottomRight ? r : 0)}`;
        if (shouldRoundBottomRight)
          strokePath += ` Q ${x2 + w2} ${y2 + h2} ${x2 + w2 - r} ${y2 + h2}`;
        strokePath += ` L ${x2 + (shouldRoundBottomLeft ? r : 0)} ${y2 + h2}`;
        if (shouldRoundBottomLeft)
          strokePath += ` Q ${x2} ${y2 + h2} ${x2} ${y2 + h2 - r}`;
        strokePath += ` L ${x2} ${y2 + (shouldRoundTopLeft ? r : 0)}`;
      } else {
        strokePath = `M ${x2 + (shouldRoundTopLeft ? r : 0)} ${y2}`;
        strokePath += ` L ${x2 + w2 - (shouldRoundTopRight ? r : 0)} ${y2}`;
        if (shouldRoundTopRight)
          strokePath += ` Q ${x2 + w2} ${y2} ${x2 + w2} ${y2 + r}`;
        strokePath += ` L ${x2 + w2} ${y2 + h2 - (shouldRoundBottomRight ? r : 0)}`;
        if (shouldRoundBottomRight)
          strokePath += ` Q ${x2 + w2} ${y2 + h2} ${x2 + w2 - r} ${y2 + h2}`;
        strokePath += ` L ${x2 + (shouldRoundBottomLeft ? r : 0)} ${y2 + h2}`;
        if (shouldRoundBottomLeft)
          strokePath += ` Q ${x2} ${y2 + h2} ${x2} ${y2 + h2 - r}`;
        strokePath += ` M ${x2} ${y2 + (shouldRoundTopLeft ? r : 0)}`;
        if (shouldRoundTopLeft) strokePath += ` Q ${x2} ${y2} ${x2 + r} ${y2}`;
      }
      return svg`
        <path d=${path2} fill=${fillColor} stroke="none"/>
        <path d="${strokePath}" fill="none" stroke=${strokeColor} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>
      `;
    }
    return svg`<path d=${path2} fill=${fillColor} stroke=${strokeColor} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>`;
  }
  let rectX = mainAxisOffset(config);
  let rectY = isOutwardPositive(config) ? 0 : -config.barThickness;
  let rectWidth = dLen;
  let rectHeight = config.barThickness;
  const isBottom = config.side === "bottom";
  let viewBoxMinY;
  let viewBoxMaxY;
  if (config.scaleBackground) {
    if (isBottom) {
      viewBoxMinY = 0;
      viewBoxMaxY = config.barThickness + 1;
    } else {
      viewBoxMinY = -config.barThickness - 1;
      viewBoxMaxY = 0;
    }
  } else {
    viewBoxMinY = isBottom ? 0 : -config.barThickness;
    viewBoxMaxY = isBottom ? config.barThickness : 0;
  }
  const adjustedX = adjustRectWidthForStroke(
    rectX,
    rectWidth,
    rectX,
    rectX + rectWidth,
    strokeWidth
  );
  rectX = adjustedX.x;
  rectWidth = adjustedX.width;
  const adjustedY = adjustRectHeightForStroke(
    rectY,
    rectHeight,
    viewBoxMinY,
    viewBoxMaxY,
    strokeWidth
  );
  rectY = adjustedY.y;
  rectHeight = adjustedY.height;
  if (allCornersRounded || noCornersRounded) {
    const rx = allCornersRounded ? r : 0;
    const ry = allCornersRounded ? r : 0;
    if (config.scaleBackground) {
      const isBottom2 = config.side === "bottom";
      let strokePath;
      if (isBottom2) {
        strokePath = `M ${rectX + (noCornersRounded ? 0 : r)} ${rectY}`;
        strokePath += ` L ${rectX + rectWidth - (noCornersRounded ? 0 : r)} ${rectY}`;
        if (!noCornersRounded)
          strokePath += ` Q ${rectX + rectWidth} ${rectY} ${rectX + rectWidth} ${rectY + r}`;
        strokePath += ` L ${rectX + rectWidth} ${rectY + rectHeight - (noCornersRounded ? 0 : r)}`;
        if (!noCornersRounded)
          strokePath += ` Q ${rectX + rectWidth} ${rectY + rectHeight} ${rectX + rectWidth - r} ${rectY + rectHeight}`;
        strokePath += ` M ${rectX + (noCornersRounded ? 0 : r)} ${rectY + rectHeight}`;
        if (!noCornersRounded)
          strokePath += ` Q ${rectX} ${rectY + rectHeight} ${rectX} ${rectY + rectHeight - r}`;
        strokePath += ` L ${rectX} ${rectY + (noCornersRounded ? 0 : r)}`;
        if (!noCornersRounded)
          strokePath += ` Q ${rectX} ${rectY} ${rectX + r} ${rectY}`;
      } else {
        strokePath = `M ${rectX} ${rectY + (noCornersRounded ? 0 : r)}`;
        strokePath += ` L ${rectX} ${rectY + rectHeight - (noCornersRounded ? 0 : r)}`;
        if (!noCornersRounded)
          strokePath += ` Q ${rectX} ${rectY + rectHeight} ${rectX + r} ${rectY + rectHeight}`;
        strokePath += ` L ${rectX + rectWidth - (noCornersRounded ? 0 : r)} ${rectY + rectHeight}`;
        if (!noCornersRounded)
          strokePath += ` Q ${rectX + rectWidth} ${rectY + rectHeight} ${rectX + rectWidth} ${rectY + rectHeight - r}`;
        strokePath += ` L ${rectX + rectWidth} ${rectY + (noCornersRounded ? 0 : r)}`;
        if (!noCornersRounded)
          strokePath += ` Q ${rectX + rectWidth} ${rectY} ${rectX + rectWidth - r} ${rectY}`;
        strokePath += ` M ${rectX + (noCornersRounded ? 0 : r)} ${rectY}`;
        if (!noCornersRounded)
          strokePath += ` Q ${rectX} ${rectY} ${rectX} ${rectY + r}`;
      }
      return svg`
        <rect x=${rectX} y=${rectY} width=${rectWidth} height=${rectHeight} rx=${rx} ry=${ry} fill=${fillColor} stroke="none"/>
        <path d="${strokePath}" fill="none" stroke=${strokeColor} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>
      `;
    }
    return svg`<rect x=${rectX} y=${rectY} width=${rectWidth} height=${rectHeight} rx=${rx} ry=${ry} fill=${fillColor} stroke=${strokeColor} vector-effect="non-scaling-stroke"/>`;
  }
  const x = rectX;
  const y = rectY;
  const w = rectWidth;
  const h = rectHeight;
  let path = `M ${x + (shouldRoundTopLeft ? r : 0)} ${y}`;
  path += ` L ${x + w - (shouldRoundTopRight ? r : 0)} ${y}`;
  if (shouldRoundTopRight) {
    path += ` Q ${x + w} ${y} ${x + w} ${y + r}`;
  }
  path += ` L ${x + w} ${y + h - (shouldRoundBottomRight ? r : 0)}`;
  if (shouldRoundBottomRight) {
    path += ` Q ${x + w} ${y + h} ${x + w - r} ${y + h}`;
  }
  path += ` L ${x + (shouldRoundBottomLeft ? r : 0)} ${y + h}`;
  if (shouldRoundBottomLeft) {
    path += ` Q ${x} ${y + h} ${x} ${y + h - r}`;
  }
  path += ` L ${x} ${y + (shouldRoundTopLeft ? r : 0)}`;
  if (shouldRoundTopLeft) {
    path += ` Q ${x} ${y} ${x + r} ${y}`;
  }
  path += ` Z`;
  if (config.scaleBackground) {
    const isBottom2 = config.side === "bottom";
    let strokePath;
    if (isBottom2) {
      strokePath = `M ${x + (shouldRoundTopLeft ? r : 0)} ${y}`;
      strokePath += ` L ${x + w - (shouldRoundTopRight ? r : 0)} ${y}`;
      if (shouldRoundTopRight)
        strokePath += ` Q ${x + w} ${y} ${x + w} ${y + r}`;
      strokePath += ` L ${x + w} ${y + h - (shouldRoundBottomRight ? r : 0)}`;
      if (shouldRoundBottomRight)
        strokePath += ` Q ${x + w} ${y + h} ${x + w - r} ${y + h}`;
      strokePath += ` M ${x + (shouldRoundBottomLeft ? r : 0)} ${y + h}`;
      if (shouldRoundBottomLeft)
        strokePath += ` Q ${x} ${y + h} ${x} ${y + h - r}`;
      strokePath += ` L ${x} ${y + (shouldRoundTopLeft ? r : 0)}`;
      if (shouldRoundTopLeft) strokePath += ` Q ${x} ${y} ${x + r} ${y}`;
    } else {
      strokePath = `M ${x} ${y + (shouldRoundTopLeft ? r : 0)}`;
      if (shouldRoundTopLeft) strokePath += ` Q ${x} ${y} ${x + r} ${y}`;
      strokePath += ` M ${x + w - (shouldRoundTopRight ? r : 0)} ${y}`;
      if (shouldRoundTopRight)
        strokePath += ` Q ${x + w} ${y} ${x + w} ${y + r}`;
      strokePath += ` L ${x + w} ${y + h - (shouldRoundBottomRight ? r : 0)}`;
      if (shouldRoundBottomRight)
        strokePath += ` Q ${x + w} ${y + h} ${x + w - r} ${y + h}`;
      strokePath += ` L ${x + (shouldRoundBottomLeft ? r : 0)} ${y + h}`;
      if (shouldRoundBottomLeft)
        strokePath += ` Q ${x} ${y + h} ${x} ${y + h - r}`;
      strokePath += ` L ${x} ${y + (shouldRoundTopLeft ? r : 0)}`;
    }
    return svg`
      <path d=${path} fill=${fillColor} stroke="none"/>
      <path d="${strokePath}" fill="none" stroke=${strokeColor} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>
    `;
  }
  return svg`<path d=${path} fill=${fillColor} stroke=${strokeColor} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>`;
}
function generateBarFill(config) {
  if (!config.hasBar || config.value === void 0) return nothing;
  const clipId = `obc-bar-fill-clip-${Math.random().toString(36).slice(2)}`;
  const borderRadiusFallback = config.scaleType === "condensed" ? 4 : 8;
  const borderRadiusValue = config.borderRadius ?? borderRadiusFallback;
  const r = borderRadiusValue;
  const c = colors(config);
  const fillMin = config.fillMin ?? 0;
  const fillMax = config.fillMax ?? config.value;
  const v0 = Math.max(Math.min(fillMin, config.maxValue), config.minValue);
  const v1 = Math.max(Math.min(fillMax, config.maxValue), config.minValue);
  const a0 = valueToMainAxis(config, v0);
  const a1 = valueToMainAxis(config, v1);
  const markerSize = 8;
  const markerR = 4;
  const dLen = drawingLength(config);
  const axisShift = mainAxisOffset(config);
  let barRoundTopLeft = true;
  let barRoundTopRight = true;
  let barRoundBottomLeft = true;
  let barRoundBottomRight = true;
  if (config.borderRadiusPosition) {
    if (config.borderRadiusPosition === BorderRadiusPosition.middleChild || config.borderRadiusPosition === BorderRadiusPosition.middleRoundedChild) {
      barRoundTopLeft = false;
      barRoundTopRight = false;
      barRoundBottomLeft = false;
      barRoundBottomRight = false;
    } else if (isVertical(config)) {
      const isRight = config.side === "right";
      const isInner = config.borderRadiusPosition === BorderRadiusPosition.innerFirstChild;
      if (isRight) {
        barRoundTopLeft = isInner;
        barRoundBottomLeft = isInner;
        barRoundTopRight = !isInner;
        barRoundBottomRight = !isInner;
      } else {
        barRoundTopLeft = !isInner;
        barRoundBottomLeft = !isInner;
        barRoundTopRight = isInner;
        barRoundBottomRight = isInner;
      }
    } else {
      const isBottom = config.side === "bottom";
      const isInner = config.borderRadiusPosition === BorderRadiusPosition.innerFirstChild;
      if (isBottom) {
        barRoundTopLeft = isInner;
        barRoundTopRight = isInner;
        barRoundBottomLeft = !isInner;
        barRoundBottomRight = !isInner;
      } else {
        barRoundTopLeft = !isInner;
        barRoundTopRight = !isInner;
        barRoundBottomLeft = isInner;
        barRoundBottomRight = isInner;
      }
    }
  }
  const barAllCornersRounded = barRoundTopLeft && barRoundTopRight && barRoundBottomLeft && barRoundBottomRight;
  const barNoCornersRounded = !barRoundTopLeft && !barRoundTopRight && !barRoundBottomLeft && !barRoundBottomRight;
  if (isVertical(config)) {
    const boxX = isOutwardPositive(config) ? 0 : -config.barThickness;
    const boxWidth = config.barThickness;
    const y = Math.min(a0, a1);
    const h = Math.abs(a1 - a0);
    const rectX2 = isOutwardPositive(config) ? 0 : -config.barThickness;
    const rectY2 = -dLen / 2 + axisShift;
    const rectWidth2 = config.barThickness;
    const rectHeight2 = dLen;
    const barClipShape2 = barNoCornersRounded ? svg`<rect x=${rectX2} y=${rectY2} width=${rectWidth2} height=${rectHeight2} rx=${0} ry=${0}/>` : barAllCornersRounded ? svg`<rect x=${rectX2} y=${rectY2} width=${rectWidth2} height=${rectHeight2} rx=${r} ry=${r}/>` : svg`<path d=${(() => {
      const x2 = rectX2;
      const y2 = rectY2;
      const w2 = rectWidth2;
      const h2 = rectHeight2;
      let path = `M ${x2 + (barRoundTopLeft ? r : 0)} ${y2}`;
      path += ` L ${x2 + w2 - (barRoundTopRight ? r : 0)} ${y2}`;
      if (barRoundTopRight) {
        path += ` Q ${x2 + w2} ${y2} ${x2 + w2} ${y2 + r}`;
      }
      path += ` L ${x2 + w2} ${y2 + h2 - (barRoundBottomRight ? r : 0)}`;
      if (barRoundBottomRight) {
        path += ` Q ${x2 + w2} ${y2 + h2} ${x2 + w2 - r} ${y2 + h2}`;
      }
      path += ` L ${x2 + (barRoundBottomLeft ? r : 0)} ${y2 + h2}`;
      if (barRoundBottomLeft) {
        path += ` Q ${x2} ${y2 + h2} ${x2} ${y2 + h2 - r}`;
      }
      path += ` L ${x2} ${y2 + (barRoundTopLeft ? r : 0)}`;
      if (barRoundTopLeft) {
        path += ` Q ${x2} ${y2} ${x2 + r} ${y2}`;
      }
      path += ` Z`;
      return path;
    })()}/>`;
    const fillRect2 = svg`<rect x=${boxX} y=${y} width=${boxWidth} height=${h} fill=${c.barFillColor} stroke="none"/>`;
    if (config.fillMode === "tint") {
      const markerY = valueToMainAxis(config, config.value) - markerSize / 2;
      const marker = svg`<rect x=${boxX} y=${markerY} width=${boxWidth} height=${markerSize} rx=${markerR} fill=${c.markerFillColor} stroke=${c.markerStrokeColor} vector-effect="non-scaling-stroke"/>`;
      return svg`<defs>
        <clipPath id=${clipId} clipPathUnits="userSpaceOnUse">${barClipShape2}</clipPath>
      </defs>
      <g clip-path=${`url(#${clipId})`}>
        ${fillRect2}
        ${marker}
      </g>`;
    }
    return svg`<defs>
      <clipPath id=${clipId} clipPathUnits="userSpaceOnUse">${barClipShape2}</clipPath>
    </defs>
    <g clip-path=${`url(#${clipId})`}>
      ${fillRect2}
    </g>`;
  }
  const boxY = isOutwardPositive(config) ? 0 : -config.barThickness;
  const boxHeight = config.barThickness;
  const x = Math.min(a0, a1);
  const w = Math.abs(a1 - a0);
  const rectX = mainAxisOffset(config);
  const rectY = isOutwardPositive(config) ? 0 : -config.barThickness;
  const rectWidth = dLen;
  const rectHeight = config.barThickness;
  const barClipShape = barNoCornersRounded ? svg`<rect x=${rectX} y=${rectY} width=${rectWidth} height=${rectHeight} rx=${0} ry=${0}/>` : barAllCornersRounded ? svg`<rect x=${rectX} y=${rectY} width=${rectWidth} height=${rectHeight} rx=${r} ry=${r}/>` : svg`<path d=${(() => {
    const x2 = rectX;
    const y = rectY;
    const w2 = rectWidth;
    const h = rectHeight;
    let path = `M ${x2 + (barRoundTopLeft ? r : 0)} ${y}`;
    path += ` L ${x2 + w2 - (barRoundTopRight ? r : 0)} ${y}`;
    if (barRoundTopRight) {
      path += ` Q ${x2 + w2} ${y} ${x2 + w2} ${y + r}`;
    }
    path += ` L ${x2 + w2} ${y + h - (barRoundBottomRight ? r : 0)}`;
    if (barRoundBottomRight) {
      path += ` Q ${x2 + w2} ${y + h} ${x2 + w2 - r} ${y + h}`;
    }
    path += ` L ${x2 + (barRoundBottomLeft ? r : 0)} ${y + h}`;
    if (barRoundBottomLeft) {
      path += ` Q ${x2} ${y + h} ${x2} ${y + h - r}`;
    }
    path += ` L ${x2} ${y + (barRoundTopLeft ? r : 0)}`;
    if (barRoundTopLeft) {
      path += ` Q ${x2} ${y} ${x2 + r} ${y}`;
    }
    path += ` Z`;
    return path;
  })()}/>`;
  const fillRect = svg`<rect x=${x} y=${boxY} width=${w} height=${boxHeight} fill=${c.barFillColor} stroke="none"/>`;
  if (config.fillMode === "tint") {
    const markerX = valueToMainAxis(config, config.value) - markerSize / 2;
    const marker = svg`<rect x=${markerX} y=${boxY} width=${markerSize} height=${boxHeight} rx=${markerR} fill=${c.markerFillColor} stroke=${c.markerStrokeColor} vector-effect="non-scaling-stroke"/>`;
    return svg`<defs>
      <clipPath id=${clipId} clipPathUnits="userSpaceOnUse">${barClipShape}</clipPath>
    </defs>
    <g clip-path=${`url(#${clipId})`}>
      ${fillRect}
      ${marker}
    </g>`;
  }
  return svg`<defs>
    <clipPath id=${clipId} clipPathUnits="userSpaceOnUse">${barClipShape}</clipPath>
  </defs>
  <g clip-path=${`url(#${clipId})`}>
    ${fillRect}
  </g>`;
}
function generateScaleBackground(config) {
  if (!config.scaleBackground) return nothing;
  const borderRadiusFallback = config.scaleType === "condensed" ? 4 : 8;
  const borderRadiusValue = config.borderRadius ?? borderRadiusFallback;
  const strokeWidth = 1;
  const fillColor = "var(--instrument-frame-primary-color)";
  const strokeColor = "var(--instrument-frame-tertiary-color)";
  const { main } = getTickThicknesses(config.scaleType);
  const backgroundThickness = main + tickGap();
  const dLen = drawingLength(config);
  const axisShift = mainAxisOffset(config);
  const shouldRoundTopLeft = config.orientation === "vertical" && config.side === "left" || config.orientation === "horizontal" && config.side === "top";
  const shouldRoundTopRight = config.orientation === "vertical" && config.side === "right" || config.orientation === "horizontal" && config.side === "top";
  const shouldRoundBottomLeft = config.orientation === "vertical" && config.side === "left" || config.orientation === "horizontal" && config.side === "bottom";
  const shouldRoundBottomRight = config.orientation === "vertical" && config.side === "right" || config.orientation === "horizontal" && config.side === "bottom";
  const r = borderRadiusValue;
  if (isVertical(config)) {
    const startPerp2 = config.hasBar ? isOutwardPositive(config) ? config.barThickness : -config.barThickness : 0;
    let rectX2 = isOutwardPositive(config) ? startPerp2 : startPerp2 - backgroundThickness;
    let rectY2 = -dLen / 2 + axisShift;
    let rectWidth2 = backgroundThickness;
    let rectHeight2 = dLen;
    const isRight = config.side === "right";
    let viewBoxMinX;
    let viewBoxMaxX;
    if (config.hasBar) {
      if (isRight) {
        viewBoxMinX = rectX2 - 1;
        viewBoxMaxX = rectX2 + rectWidth2;
      } else {
        viewBoxMinX = rectX2;
        viewBoxMaxX = rectX2 + rectWidth2 + 1;
      }
    } else {
      viewBoxMinX = rectX2;
      viewBoxMaxX = rectX2 + rectWidth2;
    }
    const adjustedX2 = adjustRectWidthForStroke(
      rectX2,
      rectWidth2,
      viewBoxMinX,
      viewBoxMaxX,
      strokeWidth
    );
    rectX2 = adjustedX2.x;
    rectWidth2 = adjustedX2.width;
    const adjustedY2 = adjustRectHeightForStroke(
      rectY2,
      rectHeight2,
      -dLen / 2 + axisShift,
      dLen / 2 + axisShift,
      strokeWidth
    );
    rectY2 = adjustedY2.y;
    rectHeight2 = adjustedY2.height;
    const x2 = rectX2;
    const y2 = rectY2;
    const w2 = rectWidth2;
    const h2 = rectHeight2;
    let path2 = `M ${x2 + (shouldRoundTopLeft ? r : 0)} ${y2}`;
    path2 += ` L ${x2 + w2 - (shouldRoundTopRight ? r : 0)} ${y2}`;
    if (shouldRoundTopRight) {
      path2 += ` Q ${x2 + w2} ${y2} ${x2 + w2} ${y2 + r}`;
    }
    path2 += ` L ${x2 + w2} ${y2 + h2 - (shouldRoundBottomRight ? r : 0)}`;
    if (shouldRoundBottomRight) {
      path2 += ` Q ${x2 + w2} ${y2 + h2} ${x2 + w2 - r} ${y2 + h2}`;
    }
    path2 += ` L ${x2 + (shouldRoundBottomLeft ? r : 0)} ${y2 + h2}`;
    if (shouldRoundBottomLeft) {
      path2 += ` Q ${x2} ${y2 + h2} ${x2} ${y2 + h2 - r}`;
    }
    path2 += ` L ${x2} ${y2 + (shouldRoundTopLeft ? r : 0)}`;
    if (shouldRoundTopLeft) {
      path2 += ` Q ${x2} ${y2} ${x2 + r} ${y2}`;
    }
    path2 += ` Z`;
    const innerX = isRight ? x2 : x2 + w2;
    const halfStroke2 = strokeWidth / 2;
    return svg`<path d=${path2} fill=${fillColor} stroke=${strokeColor} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>
      <line x1=${innerX} x2=${innerX} y1=${y2 + halfStroke2} y2=${y2 + h2 - halfStroke2} stroke=${fillColor} stroke-width=${strokeWidth + 0.5} vector-effect="non-scaling-stroke"/>`;
  }
  const startPerp = config.hasBar ? isOutwardPositive(config) ? config.barThickness : -config.barThickness : 0;
  let rectX = mainAxisOffset(config);
  let rectY = isOutwardPositive(config) ? startPerp : startPerp - backgroundThickness;
  let rectWidth = dLen;
  let rectHeight = backgroundThickness;
  const isBottom = config.side === "bottom";
  let viewBoxMinY;
  let viewBoxMaxY;
  if (config.hasBar) {
    if (isBottom) {
      viewBoxMinY = rectY - 1;
      viewBoxMaxY = rectY + rectHeight;
    } else {
      viewBoxMinY = rectY;
      viewBoxMaxY = rectY + rectHeight + 1;
    }
  } else {
    viewBoxMinY = rectY;
    viewBoxMaxY = rectY + rectHeight;
  }
  const adjustedX = adjustRectWidthForStroke(
    rectX,
    rectWidth,
    rectX,
    rectX + rectWidth,
    strokeWidth
  );
  rectX = adjustedX.x;
  rectWidth = adjustedX.width;
  const adjustedY = adjustRectHeightForStroke(
    rectY,
    rectHeight,
    viewBoxMinY,
    viewBoxMaxY,
    strokeWidth
  );
  rectY = adjustedY.y;
  rectHeight = adjustedY.height;
  const x = rectX;
  const y = rectY;
  const w = rectWidth;
  const h = rectHeight;
  let path = `M ${x + (shouldRoundTopLeft ? r : 0)} ${y}`;
  path += ` L ${x + w - (shouldRoundTopRight ? r : 0)} ${y}`;
  if (shouldRoundTopRight) {
    path += ` Q ${x + w} ${y} ${x + w} ${y + r}`;
  }
  path += ` L ${x + w} ${y + h - (shouldRoundBottomRight ? r : 0)}`;
  if (shouldRoundBottomRight) {
    path += ` Q ${x + w} ${y + h} ${x + w - r} ${y + h}`;
  }
  path += ` L ${x + (shouldRoundBottomLeft ? r : 0)} ${y + h}`;
  if (shouldRoundBottomLeft) {
    path += ` Q ${x} ${y + h} ${x} ${y + h - r}`;
  }
  path += ` L ${x} ${y + (shouldRoundTopLeft ? r : 0)}`;
  if (shouldRoundTopLeft) {
    path += ` Q ${x} ${y} ${x + r} ${y}`;
  }
  path += ` Z`;
  const innerY = isBottom ? y : y + h;
  const halfStroke = strokeWidth / 2;
  return svg`<path d=${path} fill=${fillColor} stroke=${strokeColor} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>
    <line x1=${x + halfStroke} x2=${x + w - halfStroke} y1=${innerY} y2=${innerY} stroke=${fillColor} stroke-width=${strokeWidth + 0.5} vector-effect="non-scaling-stroke"/>`;
}
function getSetpointRotation(config) {
  if (isVertical(config)) {
    return config.side === "right" ? 90 : -90;
  }
  return config.side === "bottom" ? 180 : 0;
}
function renderSingleSetpoint(config, setpointValue, visualState, colorMode, disabled, idSuffix, opacity = 1, animate = false) {
  const baseId = generateSetpointId(`external-scale-setpoint-${idSuffix}`);
  const stateOffset = getSetpointOutwardOffset(visualState);
  const setpointAtZero = Math.abs(setpointValue) < config.setpointAtZeroDeadband;
  const mainAxisPos = setpointAtZero ? valueToMainAxis(config, 0) : valueToMainAxis(config, setpointValue);
  const base = tickBasePerp(config);
  const outwardOffset = tickGap();
  const totalOutwardOffset = outwardOffset + stateOffset;
  const perpAxisPos = isOutwardPositive(config) ? base + totalOutwardOffset : base - totalOutwardOffset;
  const rotation = getSetpointRotation(config);
  const x = isVertical(config) ? perpAxisPos : mainAxisPos;
  const y = isVertical(config) ? mainAxisPos : perpAxisPos;
  if (animate) {
    const duration = `var(${SETPOINT_ANIMATION_CSS_VAR}, ${SETPOINT_ANIMATION_DURATION_DEFAULT})`;
    return svg`
      <g style="transform: translate(${x}px, ${y}px) rotate(${rotation}deg); opacity: ${opacity}; transition: transform ${duration} ease-out, opacity ${duration} ease-out;">
        ${drawSetpointMarker({ visualState, colorMode, disabled, id: baseId })}
      </g>
    `;
  }
  return svg`
    <g transform="translate(${x}, ${y}) rotate(${rotation})" opacity="${opacity}">
      ${drawSetpointMarker({ visualState, colorMode, disabled, id: baseId })}
    </g>
  `;
}
function setpointMarker(config) {
  const hasOriginalSetpoint = config.setpoint !== void 0;
  const hasNewSetpoint = config.newSetpoint !== void 0;
  const hasDepartingNewSetpoint = config.departingNewSetpoint !== void 0;
  const animate = config.animateSetpoint === true;
  if (!hasOriginalSetpoint && !hasNewSetpoint && !hasDepartingNewSetpoint)
    return nothing;
  const markers = [];
  if (hasOriginalSetpoint) {
    const visualState = deriveSetpointVisualState(config);
    const colorMode = deriveSetpointColorMode(config);
    const disabled = deriveSetpointDisabled(config);
    const opacity = hasNewSetpoint ? 0.75 : 1;
    markers.push(
      renderSingleSetpoint(
        config,
        config.setpoint,
        visualState,
        colorMode,
        disabled,
        "original",
        opacity,
        animate
      )
    );
  }
  if (hasNewSetpoint || hasDepartingNewSetpoint) {
    const isActive = hasNewSetpoint;
    const value = isActive ? config.newSetpoint : config.departingNewSetpoint;
    const targetOpacity = isActive ? 1 : 0;
    const visualState = SetpointVisualState.focus;
    const colorMode = deriveSetpointColorMode(config);
    const disabled = false;
    markers.push(
      renderSingleSetpoint(
        config,
        value,
        visualState,
        colorMode,
        disabled,
        "new",
        targetOpacity,
        animate
      )
    );
  }
  return svg`${markers}`;
}
function generateCurrentValueDot(config) {
  if (!config.highlightCurrentValue || config.value === void 0 || !config.hasScale) {
    return nothing;
  }
  const dotDiameter = 12;
  const strokeWidth = 2;
  const visualRadius = dotDiameter / 2 + strokeWidth / 2;
  const dotRadius = dotDiameter / 2;
  const pos = valueToMainAxis(config, config.value);
  const base = tickBasePerp(config);
  const perpCenter = isOutwardPositive(config) ? base + visualRadius : base - visualRadius;
  const c = colors(config);
  const fillColor = c.markerFillColor;
  const strokeColor = "var(--instrument-frame-primary-color)";
  if (isVertical(config)) {
    return svg`
      <circle
        cx=${perpCenter}
        cy=${pos}
        r=${dotRadius}
        fill=${fillColor}
        stroke=${strokeColor}
        stroke-width=${strokeWidth}
        vector-effect="non-scaling-stroke"
      />
    `;
  }
  return svg`
    <circle
      cx=${pos}
      cy=${perpCenter}
      r=${dotRadius}
      fill=${fillColor}
      stroke=${strokeColor}
      stroke-width=${strokeWidth}
      vector-effect="non-scaling-stroke"
    />
  `;
}
function singleSidedTickmark(config, value, style, tickBase) {
  if (value >= config.maxValue || value <= config.minValue) return null;
  const color = tickmarkColor(style);
  const pos = valueToMainAxis(config, value);
  const gap = tickGap();
  const start = isOutwardPositive(config) ? tickBase + gap : tickBase - gap;
  const len = computeExternalScaleEffectiveTickThickness(config);
  const end = isOutwardPositive(config) ? start + len : start - len;
  if (isVertical(config)) {
    return svg`<line x1=${start} x2=${end} y1=${pos} y2=${pos} stroke=${color} stroke-width="1" vector-effect="non-scaling-stroke"/>`;
  }
  return svg`<line x1=${pos} x2=${pos} y1=${start} y2=${end} stroke=${color} stroke-width="1" vector-effect="non-scaling-stroke"/>`;
}
function advicePill(config, advice, x1, fill, stroke) {
  const width = 8;
  const offset = 4;
  const r = width / 2;
  const inset = 4;
  if (isVertical(config)) {
    const yMin = valueToMainAxis(config, advice.min);
    const yMax = valueToMainAxis(config, advice.max);
    const yL = Math.min(yMin, yMax);
    const yH = Math.max(yMin, yMax);
    const x2 = x1 + offset;
    const y2 = yL + inset;
    const h = Math.max(0, yH - yL - inset * 2);
    return svg`<rect x=${x2} y=${y2} width=${width} height=${h} rx=${r} ry=${r} fill=${fill} stroke=${stroke} stroke-width="1" vector-effect="non-scaling-stroke"/>`;
  }
  const xMin = valueToMainAxis(config, advice.min);
  const xMax = valueToMainAxis(config, advice.max);
  const xL = Math.min(xMin, xMax);
  const xH = Math.max(xMin, xMax);
  const x = xL + inset;
  const y = x1 + offset;
  const w = Math.max(0, xH - xL - inset * 2);
  return svg`<rect x=${x} y=${y} width=${w} height=${width} rx=${r} ry=${r} fill=${fill} stroke=${stroke} stroke-width="1" vector-effect="non-scaling-stroke"/>`;
}
function renderAdvice(config, advice) {
  const tickBase = tickBasePerp(config);
  const hasBarArea = config.hasBar;
  const effectiveAdvicePosition = hasBarArea ? config.advicePosition : "inner";
  let x1;
  if (effectiveAdvicePosition === "center") {
    const adviceWidth = 8;
    const centerOffset = config.barThickness / 2 - adviceWidth / 2;
    if (isVertical(config)) {
      x1 = isOutwardPositive(config) ? centerOffset - 4 : -config.barThickness + centerOffset - 4;
    } else {
      x1 = isOutwardPositive(config) ? centerOffset - 4 : -config.barThickness + centerOffset - 4;
    }
  } else if (effectiveAdvicePosition === "inner") {
    x1 = isOutwardPositive(config) ? tickBase : tickBase - 16;
  } else {
    x1 = isOutwardPositive(config) ? config.barThickness + 10 : -config.barThickness - computeExternalScaleEffectiveTickThickness(config) + 14;
  }
  const ticks = [];
  const dashStroke = "var(--instrument-frame-tertiary-color)";
  const minBound = advice.min > config.minValue;
  const maxBound = advice.max < config.maxValue;
  const barStart = isOutwardPositive(config) ? 0 : -config.barThickness;
  const barEnd = isOutwardPositive(config) ? config.barThickness : 0;
  const dash = (v) => {
    const p = valueToMainAxis(config, v);
    if (isVertical(config)) {
      ticks.push(
        svg`<line x1=${barStart} x2=${barEnd} y1=${p} y2=${p} stroke=${dashStroke} stroke-width="1" vector-effect="non-scaling-stroke" stroke-dasharray="4 4"/>`
      );
    } else {
      ticks.push(
        svg`<line x1=${p} x2=${p} y1=${barStart} y2=${barEnd} stroke=${dashStroke} stroke-width="1" vector-effect="non-scaling-stroke" stroke-dasharray="4 4"/>`
      );
    }
  };
  if (minBound) dash(advice.min);
  if (maxBound) dash(advice.max);
  if (advice.type === AdviceType.caution) {
    let mainColor;
    let fillColor2 = "var(--instrument-frame-primary-color)";
    if (advice.state === AdviceState.hinted) {
      mainColor = "var(--instrument-frame-tertiary-color)";
    } else if (advice.state === AdviceState.regular) {
      mainColor = "var(--instrument-tick-mark-tertiary-color)";
    } else {
      mainColor = "var(--on-caution-active-color)";
      fillColor2 = "var(--alert-caution-color)";
    }
    const pattern = [];
    const ypattern = 50;
    const aMin = valueToMainAxis(config, advice.min);
    const aMax = valueToMainAxis(config, advice.max);
    const mainMin = Math.min(aMin, aMax);
    const mainMax = Math.max(aMin, aMax);
    const span = mainMax - mainMin;
    if (isVertical(config)) {
      const xOffset = x1 + 8 - 25;
      const yStart = mainMin - 25;
      for (let i = -64; i < span + 64; i += 16) {
        const transform = `translate(${xOffset} ${yStart + i})`;
        const path = `M 50 0 L 0 ${ypattern}`;
        pattern.push(
          svg`<g transform=${transform}><path d=${path} stroke=${mainColor} stroke-width="6"/></g>`
        );
      }
    } else {
      const yOffset = x1 + 8 - 25;
      const xStart = mainMin - 25;
      for (let i = -64; i < span + 64; i += 16) {
        const transform = `translate(${xStart + i} ${yOffset})`;
        const path = `M 0 50 L ${ypattern} 0`;
        pattern.push(
          svg`<g transform=${transform}><path d=${path} stroke=${mainColor} stroke-width="6"/></g>`
        );
      }
    }
    const maskId = `externalScaleAdviceMask-${advice.min}-${advice.max}-${Math.random().toString(36).slice(2)}`;
    let tickmarkStyle2 = TickmarkStyle.regular;
    if (advice.state === AdviceState.regular)
      tickmarkStyle2 = TickmarkStyle.regular;
    else if (advice.state === AdviceState.triggered)
      tickmarkStyle2 = TickmarkStyle.enhanced;
    return svg`
      <defs>
        <mask id=${maskId} maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse" x="-4096" y="-4096" width="8192" height="8192">
          ${advicePill(config, advice, x1, "white", "none")}
        </mask>
      </defs>
      <g mask="url(#${maskId})">
        ${fillColor2 ? svg`<rect x="-2048" y="-2048" width="4096" height="4096" fill=${fillColor2}/>` : nothing}
        ${pattern}
      </g>
      ${advicePill(config, advice, x1, "none", mainColor)}
      ${singleSidedTickmark(config, advice.min, tickmarkStyle2, tickBase) ?? nothing}
      ${singleSidedTickmark(config, advice.max, tickmarkStyle2, tickBase) ?? nothing}
      ${ticks}
    `;
  }
  let strokeColor;
  let tickmarkStyle;
  let fillColor;
  if (advice.state === AdviceState.hinted) {
    strokeColor = "var(--instrument-frame-tertiary-color)";
    fillColor = "var(--instrument-frame-primary-color)";
    tickmarkStyle = TickmarkStyle.regular;
  } else if (advice.state === AdviceState.regular) {
    strokeColor = "var(--instrument-regular-secondary-color)";
    fillColor = "var(--instrument-frame-primary-color)";
    tickmarkStyle = TickmarkStyle.regular;
  } else {
    strokeColor = "var(--instrument-enhanced-secondary-color)";
    fillColor = strokeColor;
    tickmarkStyle = TickmarkStyle.regular;
  }
  return svg`
    ${advicePill(config, advice, x1, fillColor, strokeColor)}
    ${singleSidedTickmark(config, advice.min, tickmarkStyle, tickBase) ?? nothing}
    ${singleSidedTickmark(config, advice.max, tickmarkStyle, tickBase) ?? nothing}
    ${ticks}
  `;
}
function generateAdviceOverlays(config) {
  if (!config.advices || !config.advices.length) return [];
  const raw = convertAdvices(config.advices, config.setpoint);
  return raw.map((a) => renderAdvice(config, a));
}
function computeScaleDimensionsForReport(config) {
  const layout = computeExternalScaleLayout(config);
  const viewBox = computeExternalScaleViewBox(
    { orientation: config.orientation, length: config.length },
    layout
  );
  const thickness = config.orientation === "vertical" ? viewBox.width : viewBox.height;
  return {
    side: config.side,
    thickness
  };
}
function renderExternalScale(config) {
  const effectiveBarThickness = computeExternalScaleEffectiveBarThickness(config);
  const effectiveConfig = effectiveBarThickness === config.barThickness ? config : { ...config, barThickness: effectiveBarThickness };
  const parts = {
    barContainer: generateBarContainer(effectiveConfig),
    barFill: generateBarFill(effectiveConfig),
    scaleBackground: generateScaleBackground(effectiveConfig),
    tickmarks: generateTickmarks(effectiveConfig),
    labels: generateLabels(effectiveConfig),
    adviceOverlays: generateAdviceOverlays(effectiveConfig),
    currentValueDot: generateCurrentValueDot(effectiveConfig),
    setpoint: setpointMarker(effectiveConfig)
  };
  return parts;
}
export {
  AdvicePosition,
  BarContainerStyle,
  EXTERNAL_SCALE_BORDER_RADIUS_CSS_VAR,
  ExternalScaleOrientation,
  ExternalScaleSide,
  FillMode,
  ScaleType,
  computeExternalScaleEffectiveBarThickness,
  computeExternalScaleEffectiveBorderRadiusPx,
  computeExternalScaleEffectiveTickThickness,
  computeExternalScaleLayout,
  computeExternalScaleViewBox,
  computeFixedAspectRatioScale,
  computeMeetScale,
  computeScaleDimensionsForReport,
  computeScaledThickness,
  defaultExternalScaleBorderRadiusPx,
  parseCssLengthToPx,
  readExternalScaleBorderRadiusPx,
  renderExternalScale,
  startExternalScaleBorderRadiusObserver,
  toExternalScaleLayoutConfig
};
//# sourceMappingURL=external-scale.js.map
