///|
// Validate the input shared by all stackplot baseline algorithms.
fn validate_stackplot_input(
  xs : Array[Double],
  ys : Array[Array[Double]],
  labels : Array[String],
  baseline : String,
) -> Unit raise @core.DataError {
  if xs.is_empty() {
    raise @core.DataError::InvalidReference(
      message="stackplot requires at least one x value",
    )
  }
  if ys.is_empty() {
    raise @core.DataError::InvalidReference(
      message="stackplot requires at least one y series",
    )
  }
  if labels.length() != 0 && labels.length() != ys.length() {
    raise @core.DataError::LengthMismatch(
      expected=ys.length(),
      actual=labels.length(),
    )
  }
  if baseline != "zero" &&
    baseline != "sym" &&
    baseline != "wiggle" &&
    baseline != "weighted_wiggle" {
    raise @core.DataError::InvalidReference(
      message="stackplot baseline must be zero, sym, wiggle, or weighted_wiggle",
    )
  }
  for value in xs {
    if value.is_nan() || value.is_inf() {
      raise @core.DataError::InvalidReference(
        message="stackplot x values must be finite",
      )
    }
  }
  for row in ys {
    if row.length() != xs.length() {
      raise @core.DataError::LengthMismatch(
        expected=xs.length(),
        actual=row.length(),
      )
    }
    for value in row {
      if value.is_nan() || value.is_inf() {
        raise @core.DataError::InvalidReference(
          message="stackplot y values must be finite",
        )
      }
    }
  }
}

///|
fn stackplot_zeroes(length : Int32) -> Array[Double] {
  let result = Array(capacity=length)
  for _ in 0.. Array[Array[Double]] {
  let length = ys[0].length()
  let cumulative = stackplot_zeroes(length)
  let result : Array[Array[Double]] = []
  for row in ys {
    let upper = Array(capacity=length)
    for index in 0.. Array[Double] {
  let rows = ys.length()
  let length = ys[0].length()
  let result = stackplot_zeroes(length)
  if baseline == "zero" {
    return result
  }
  if baseline == "sym" {
    for index in 0.. 0.0 { 1.0 / total } else { 0.0 }
    let mut movement = 0.0
    for row_index in 0.. String {
  if labels.is_empty() {
    ""
  } else {
    labels[index]
  }
}

///|
fn Axes::add_stackplot_layer(
  self : Axes,
  xs : Array[Double],
  lower : Array[Double],
  upper : Array[Double],
  color : String,
  label : String,
) -> Artist {
  let lower_points = Array(capacity=xs.length())
  let upper_points = Array(capacity=xs.length())
  for index in 0.. Array[Artist] raise @core.DataError {
  self.axes().stackplot(xs, ys, labels~, colors~, baseline~)
}

///|
/// Draw a stacked area plot through the axes handle.
pub fn Axes::stackplot(
  self : Axes,
  xs : Array[Double],
  ys : Array[Array[Double]],
  labels~ : Array[String] = [],
  colors~ : Array[String] = [],
  baseline~ : String = "zero",
) -> Array[Artist] raise @core.DataError {
  validate_stackplot_input(xs, ys, labels, baseline)
  let stacked = stackplot_cumulative(ys)
  let first_line = stackplot_first_line(ys, stacked, baseline)
  let start = self.state.val.artists.length()
  let mut lower = first_line.copy()
  let result : Array[Artist] = []
  for row_index in 0..