///|
fn run_foundation_example() -> Unit raise {
  run_closed_stroke_tree_example()
  run_decimal_closed_stroke_example()
  run_closed_stroke_example()
  run_lineclip_example()
  run_rectclip_example()
  run_decimal_rectclip_lines_example()
  run_rectclip_polygons_example()
  run_rectclip_tree_example()
  run_decimal_rectclip_polygons_example()
  run_stroke_batch_example()
  run_stroke_batch_tree_example()
  run_decimal_stroke_batch_example()
  run_decimal_minkowski_example()
  run_tree_locate_example()
  run_decimal_tree_locate_example()
  let path : @moonclip.Path64 = [
    @moonclip.Point64::new(-10L, 0L),
    @moonclip.Point64::new(10L, 0L),
    @moonclip.Point64::new(0L, 10L),
  ]
  let paths : @moonclip.Paths64 = [path, []]
  let copied = @moonclip.copy_paths(paths)
  assert_true(paths == copied)
  path[0] = @moonclip.Point64::new(-99L, 5L)
  assert_eq(copied[0][0].x, -10L)
  assert_eq(copied[0][0].y, 0L)
  assert_true(paths != copied)

  let contour : @moonclip.Path64 = [
    @moonclip.Point64::new(-4L, -3L),
    @moonclip.Point64::new(4L, -3L),
    @moonclip.Point64::new(4L, 3L),
    @moonclip.Point64::new(-4L, 3L),
  ]
  assert_eq(
    @moonclip.orientation(contour[0], contour[1], contour[2]),
    Ok(@moonclip.CounterClockwise),
  )
  match @moonclip.bounds(contour) {
    Ok(Some(box)) => {
      assert_eq(box.min_x, -4L)
      assert_eq(box.min_y, -3L)
      assert_eq(box.max_x, 4L)
      assert_eq(box.max_y, 3L)
    }
    _ => fail("Expected bounds for the rectangle")
  }
  assert_eq(@moonclip.area2(contour), Ok(96N))
  assert_eq(
    @moonclip.point_in_polygon(@moonclip.Point64::new(0L, 0L), contour),
    Ok(@moonclip.Inside),
  )
  assert_eq(
    @moonclip.point_in_polygon(@moonclip.Point64::new(4L, 0L), contour),
    Ok(@moonclip.OnBoundary),
  )
  assert_eq(
    @moonclip.point_in_polygon(@moonclip.Point64::new(5L, 0L), contour),
    Ok(@moonclip.Outside),
  )

  let raw = [
    contour[0],
    contour[0],
    contour[1],
    contour[2],
    contour[3],
    contour[0],
  ]
  let saved = @moonclip.copy_path(raw)
  match @moonclip.normalize_path(raw, @moonclip.Closed) {
    Ok(cleaned) => {
      assert_eq(cleaned, contour)
      assert_eq(raw, saved)
      cleaned[0] = @moonclip.Point64::new(0L, 0L)
      assert_eq(raw, saved)
    }
    Err(error) => fail(error.message())
  }
  let invalid = @moonclip.Point64::new(1000000001L, 0L)
  match @moonclip.bounds([invalid]) {
    Err(CoordinateOutOfRange(loc, X, value)) => {
      assert_true(loc.stage is Bounds)
      assert_eq(loc.vertex_index, Some(0))
      assert_eq(value, 1000000001L)
    }
    _ => fail("Expected coordinate range error")
  }
  let limits : @moonclip.Limits = {
    max_input_paths: 1,
    max_input_vertices: 100,
  }
  assert_true(
    @moonclip.normalize_paths([contour, []], @moonclip.Closed, limits~)
    is Err(ResourceLimitExceeded(_, InputPaths, 1)),
  )
}

///|
fn run_lineclip_example() -> Unit raise {
  let clip = [
    example_rect(0L, 0L, 10L, 10L),
    [
      @moonclip.Point64::new(3L, 3L),
      @moonclip.Point64::new(3L, 7L),
      @moonclip.Point64::new(7L, 7L),
      @moonclip.Point64::new(7L, 3L),
    ],
  ]
  let paths = [
    [
      @moonclip.Point64::new(-2L, 5L),
      @moonclip.Point64::new(2L, 5L),
      @moonclip.Point64::new(5L, 5L),
      @moonclip.Point64::new(12L, 5L),
    ],
  ]
  assert_eq(@moonclip.intersect_polylines(paths, clip).unwrap(), [
    [
      @moonclip.Point64::new(0L, 5L),
      @moonclip.Point64::new(2L, 5L),
      @moonclip.Point64::new(3L, 5L),
    ],
    [@moonclip.Point64::new(7L, 5L), @moonclip.Point64::new(10L, 5L)],
  ])
  assert_eq(@moonclip.difference_polylines(paths, clip).unwrap(), [
    [@moonclip.Point64::new(-2L, 5L), @moonclip.Point64::new(0L, 5L)],
    [
      @moonclip.Point64::new(3L, 5L),
      @moonclip.Point64::new(5L, 5L),
      @moonclip.Point64::new(7L, 5L),
    ],
    [@moonclip.Point64::new(10L, 5L), @moonclip.Point64::new(12L, 5L)],
  ])
  let decimal_paths = [
    [
      @moonclip.PointD::new(-0.2, 0.5),
      @moonclip.PointD::new(0.2, 0.5),
      @moonclip.PointD::new(0.5, 0.5),
      @moonclip.PointD::new(1.2, 0.5),
    ],
  ]
  let decimal_clip = [
    example_box_d(0.0, 0.0, 1.0, 1.0),
    example_box_d(0.3, 0.3, 0.7, 0.7),
  ]
  assert_eq(
    @moonclip.intersect_polylines_d(
      decimal_paths,
      decimal_clip,
      precision=@moonclip.Precision::new(2).unwrap(),
    ).unwrap(),
    [
      [
        @moonclip.PointD::new(0.0, 0.5),
        @moonclip.PointD::new(0.2, 0.5),
        @moonclip.PointD::new(0.3, 0.5),
      ],
      [@moonclip.PointD::new(0.7, 0.5), @moonclip.PointD::new(1.0, 0.5)],
    ],
  )
  assert_eq(
    @moonclip.difference_polylines_d(
      decimal_paths,
      decimal_clip,
      precision=@moonclip.Precision::new(2).unwrap(),
    ).unwrap(),
    [
      [@moonclip.PointD::new(-0.2, 0.5), @moonclip.PointD::new(0.0, 0.5)],
      [
        @moonclip.PointD::new(0.3, 0.5),
        @moonclip.PointD::new(0.5, 0.5),
        @moonclip.PointD::new(0.7, 0.5),
      ],
      [@moonclip.PointD::new(1.0, 0.5), @moonclip.PointD::new(1.2, 0.5)],
    ],
  )
}

///|
fn run_decimal_closed_stroke_example() -> Unit raise {
  let path = example_box_d(0.0, 0.0, 1.0, 1.0)
  let result = @moonclip.stroke_closed_polyline_d(
    path,
    0.2,
    precision=@moonclip.Precision::new(2).unwrap(),
  ).unwrap()
  assert_eq(result.length(), 2)
  let outer = example_box_d(-0.1, -0.1, 1.1, 1.1)
  let hole = [
    @moonclip.PointD::new(0.1, 0.1),
    @moonclip.PointD::new(0.1, 0.9),
    @moonclip.PointD::new(0.9, 0.9),
    @moonclip.PointD::new(0.9, 0.1),
  ]
  let outer_index = if result[0].contains(outer[0]) { 0 } else { 1 }
  example_decimal_ring(result[outer_index], outer)
  example_decimal_ring(result[1 - outer_index], hole)
}

///|
fn run_closed_stroke_example() -> Unit raise {
  let path = example_rect(0L, 0L, 10L, 10L)
  let result = @moonclip.stroke_closed_polyline(path, 2.0).unwrap()
  example_result(result, [
    example_rect(-1L, -1L, 12L, 12L),
    [
      @moonclip.Point64::new(1L, 1L),
      @moonclip.Point64::new(1L, 9L),
      @moonclip.Point64::new(9L, 9L),
      @moonclip.Point64::new(9L, 1L),
    ],
  ])
}

///|
fn run_stroke_batch_example() -> Unit raise {
  let paths = [
    [@moonclip.Point64::new(0L, 0L), @moonclip.Point64::new(10L, 0L)],
    [@moonclip.Point64::new(5L, 0L), @moonclip.Point64::new(15L, 0L)],
  ]
  let region = @moonclip.stroke_polylines(paths, 2.0).unwrap()
  example_result(region, [example_rect(0L, -1L, 15L, 2L)])
}

///|
fn run_decimal_stroke_batch_example() -> Unit raise {
  let paths = [
    [@moonclip.PointD::new(-1.0, 0.0), @moonclip.PointD::new(1.0, 0.0)],
    [@moonclip.PointD::new(0.0, 0.0), @moonclip.PointD::new(2.0, 0.0)],
  ]
  let result = @moonclip.stroke_polylines_d(
    paths,
    0.5,
    precision=@moonclip.Precision::new(2).unwrap(),
  ).unwrap()
  example_decimal_rectangle(result, -1.0, -0.25, 2.0, 0.25)
}

///|
fn run_decimal_minkowski_example() -> Unit raise {
  let pattern = [
    @moonclip.PointD::new(0.0, -0.25),
    @moonclip.PointD::new(0.0, 0.25),
  ]
  let path = [@moonclip.PointD::new(-1.0, 0.0), @moonclip.PointD::new(1.0, 0.0)]
  let result = @moonclip.minkowski_sum_d(pattern, path, false).unwrap()
  example_decimal_rectangle(result, -1.0, -0.25, 1.0, 0.25)
}

///|
fn run_tree_locate_example() -> Unit raise {
  let tree = @moonclip.boolean_tree(
    [
      example_rect(0L, 0L, 20L, 20L),
      example_rect(4L, 4L, 12L, 12L),
      example_rect(8L, 8L, 4L, 4L),
    ],
    [],
    Union,
  ).unwrap()
  guard tree.locate(@moonclip.Point64::new(6L, 6L)) is Ok(InHole(hole)) else {
    fail("Expected hole query")
  }
  assert_eq(hole.depth(), 2)
  assert_true(hole.is_hole())
  guard tree.locate(@moonclip.Point64::new(10L, 10L)) is Ok(Inside(island)) else {
    fail("Expected island query")
  }
  assert_eq(island.depth(), 3)
  assert_true(!island.is_hole())
  guard tree.locate(@moonclip.Point64::new(4L, 6L)) is Ok(OnBoundary(nodes)) else {
    fail("Boundary is a separate query result")
  }
  assert_eq(nodes.length(), 1)
  assert_eq(nodes[0].depth(), 2)
  assert_true(nodes[0].is_hole())
  // Batch results preserve the input order: outside, hole, island, boundary.
  let results = tree
    .locate_many([
      @moonclip.Point64::new(-1L, 1L),
      @moonclip.Point64::new(6L, 6L),
      @moonclip.Point64::new(10L, 10L),
      @moonclip.Point64::new(4L, 6L),
    ])
    .unwrap()
  assert_eq(results.length(), 4)
  assert_true(results[0] is Outside)
  guard results[1] is InHole(node) else { fail("Batch hole order") }
  assert_eq(node.depth(), 2)
  guard results[2] is Inside(node) else { fail("Batch island order") }
  assert_eq(node.depth(), 3)
  guard results[3] is OnBoundary(nodes) else { fail("Batch boundary order") }
  assert_eq(nodes.length(), 1)
  assert_eq(nodes[0].depth(), 2)
}

///|
fn run_rectclip_example() -> Unit raise {
  let r : @moonclip.Bounds64 = { min_x: 0L, min_y: 0L, max_x: 10L, max_y: 10L, }
  let point = fn(x, y) { @moonclip.Point64::new(x, y) }
  assert_eq(
    @moonclip.rect_clip_lines(r, [
      [point(-10L, 5L), point(5L, 5L), point(20L, 5L)],
    ]),
    Ok([[point(0L, 5L), point(5L, 5L), point(10L, 5L)]]),
  )
  assert_eq(
    @moonclip.rect_clip_lines(r, [
      [point(-5L, 2L), point(15L, 2L), point(15L, 8L), point(-5L, 8L)],
    ]),
    Ok([[point(0L, 2L), point(10L, 2L)], [point(10L, 8L), point(0L, 8L)]]),
  )
  println("Rect clip lines: ordered open fragments OK")
}

///|
// Standalone public-library examples, grouped like the browser demo.
fn main raise {
  run_foundation_example()
  // Region operations and holed offsets.
  run_boolean_example()
  run_winding_example()
  run_tree_example()
  run_offset_example()
  run_offset_tree_example()
  run_join_example()
  // Open-route widening.
  run_stroke_example()
  run_stroke_tree_example()
  run_composition_example()
  // Decimal units, explicit simplification and integer pattern sweeps.
  run_decimal_example()
  run_decimal_tree_example()
  run_simplify_example()
  run_minkowski_example()
  run_minkowski_tree_example()
  println(
    "MoonClip geometry, Boolean, PolyTree, offset, stroke, composition, decimal, simplify and Minkowski OK",
  )
}

///|
// Unreleased: one cumulative open-route stroke produces its filled hierarchy.
fn run_stroke_tree_example() -> Unit raise {
  let line = [@moonclip.Point64::new(0L, 0L), @moonclip.Point64::new(20L, 0L)]
  guard @moonclip.stroke_tree(line, 4.0) is Ok(straight) else {
    fail("Expected straight stroke tree")
  }
  assert_eq(straight.roots().length(), 1)
  assert_eq(straight.roots()[0].depth(), 1)
  assert_true(!straight.roots()[0].is_hole())
  assert_eq(straight.roots()[0].children().length(), 0)
  example_result(straight.to_paths(), [example_rect(0L, -2L, 20L, 4L)])
  let route = example_rect(0L, 0L, 30L, 30L)
  route.push(route[0]) // Still an open route with two Square caps.
  guard @moonclip.stroke_tree(route, 4.0, cap=Square) is Ok(tree) else {
    fail("Expected holed stroke tree")
  }
  let expected = [
    example_rect(-2L, -2L, 34L, 34L),
    example_reverse(example_rect(2L, 2L, 26L, 26L)),
  ]
  assert_eq(tree.roots().length(), 1)
  let root = tree.roots()[0]
  assert_eq(root.depth(), 1)
  assert_true(!root.is_hole())
  assert_eq(root.children().length(), 1)
  let hole = root.children()[0]
  assert_eq(hole.depth(), 2)
  assert_true(hole.is_hole())
  assert_eq(hole.children().length(), 0)
  example_result([root.contour()], [expected[0]])
  example_result([hole.contour()], [expected[1]])
  let decimal = route.map(fn(p) {
    @moonclip.PointD::new(p.x.to_double() / 10.0, p.y.to_double() / 10.0)
  })
  guard @moonclip.stroke_tree_d(decimal, 0.4, cap=Square) is Ok(decoded) else {
    fail("Expected decimal stroke tree")
  }
  assert_eq(decoded.roots().length(), 1)
  let droot = decoded.roots()[0]
  assert_eq(droot.depth(), 1)
  assert_true(!droot.is_hole())
  assert_eq(droot.children().length(), 1)
  let dhole = droot.children()[0]
  assert_eq(dhole.depth(), 2)
  assert_true(dhole.is_hole())
  assert_eq(dhole.children().length(), 0)
  for
    (actual, grid) in [
      (droot.contour(), expected[0]),
      (dhole.contour(), expected[1]),
    ] {
    let ring = grid.map(fn(p) {
      @moonclip.PointD::new(p.x.to_double() / 10.0, p.y.to_double() / 10.0)
    })
    assert_eq(actual.length(), ring.length())
    let mut found = false
    for shift = 0; shift < ring.length(); shift = shift + 1 {
      if Array::makei(actual.length(), fn(i) {
          actual[(i + shift) % actual.length()]
        }) ==
        ring {
        found = true
      }
    }
    assert_true(found)
  }
}

///|
fn run_offset_tree_example() -> Unit raise {
  let input = [
    example_rect(0L, 0L, 40L, 40L),
    example_reverse(example_rect(10L, 10L, 20L, 20L)),
  ]
  guard @moonclip.offset_tree(input, 2.0) is Ok(tree) else {
    fail("Expected holed offset tree")
  }
  assert_eq(tree.roots().length(), 1)
  let root = tree.roots()[0]
  assert_eq(root.depth(), 1)
  assert_true(!root.is_hole())
  example_result([root.contour()], [example_rect(-2L, -2L, 44L, 44L)])
  assert_eq(root.children().length(), 1)
  let hole = root.children()[0]
  assert_eq(hole.depth(), 2)
  assert_true(hole.is_hole())
  assert_eq(hole.children().length(), 0)
  example_result([hole.contour()], [
    example_reverse(example_rect(12L, 12L, 16L, 16L)),
  ])

  let decimal = input.map(fn(path) {
    path.map(fn(p) {
      @moonclip.PointD::new(p.x.to_double() / 10.0, p.y.to_double() / 10.0)
    })
  })
  guard @moonclip.offset_tree_d(decimal, 0.2) is Ok(decoded) else {
    fail("Expected decimal holed offset tree")
  }
  assert_eq(decoded.roots().length(), 1)
  let droot = decoded.roots()[0]
  assert_eq(droot.depth(), 1)
  assert_true(!droot.is_hole())
  assert_eq(droot.children().length(), 1)
  let dhole = droot.children()[0]
  assert_eq(dhole.depth(), 2)
  assert_true(dhole.is_hole())
  assert_eq(dhole.children().length(), 0)
  for
    (actual, grid) in [
      (droot.contour(), root.contour()),
      (dhole.contour(), hole.contour()),
    ] {
    let expected = grid.map(fn(p) {
      @moonclip.PointD::new(p.x.to_double() / 10.0, p.y.to_double() / 10.0)
    })
    assert_eq(actual.length(), expected.length())
    // Ring start is unspecified; preserve every point and its winding.
    let mut found = false
    for shift = 0; shift < expected.length(); shift = shift + 1 {
      if Array::makei(actual.length(), fn(i) {
          actual[(i + shift) % actual.length()]
        }) ==
        expected {
        found = true
      }
    }
    assert_true(found)
  }
}

///|
fn example_rect(x : Int64, y : Int64, w : Int64, h : Int64) -> @moonclip.Path64 {
  [
    @moonclip.Point64::new(x, y),
    @moonclip.Point64::new(x + w, y),
    @moonclip.Point64::new(x + w, y + h),
    @moonclip.Point64::new(x, y + h),
  ]
}

///|
fn example_same_ring(a : @moonclip.Path64, b : @moonclip.Path64) -> Bool {
  if a.length() != b.length() {
    return false
  }
  for shift = 0; shift < b.length(); shift = shift + 1 {
    let mut same = true
    for i = 0; i < a.length(); i = i + 1 {
      if a[i] != b[(shift + i) % b.length()] {
        same = false
        break
      }
    }
    if same {
      return true
    }
  }
  a.is_empty()
}

///|
fn example_result(
  actual : @moonclip.Paths64,
  expected : @moonclip.Paths64,
) -> Unit raise {
  assert_eq(actual.length(), expected.length())
  let matched = Array::make(expected.length(), false)
  for path in actual {
    let mut found = false
    for i = 0; i < expected.length(); i = i + 1 {
      if !matched[i] && example_same_ring(path, expected[i]) {
        matched[i] = true
        found = true
        break
      }
    }
    assert_true(found)
  }
}

///|
fn run_boolean_example() -> Unit raise {
  let a = example_rect(0L, 0L, 10L, 10L)
  let b = example_rect(5L, 0L, 10L, 10L)
  for
    (operation, expected, twice_area) in [
      (@moonclip.Intersection, [example_rect(5L, 0L, 5L, 10L)], 100N),
      (@moonclip.Union, [example_rect(0L, 0L, 15L, 10L)], 300N),
      (@moonclip.Difference, [example_rect(0L, 0L, 5L, 10L)], 100N),
      (
        @moonclip.Xor,
        [example_rect(0L, 0L, 5L, 10L), example_rect(10L, 0L, 5L, 10L)],
        200N,
      ),
    ] {
    guard @moonclip.boolean_op([a], [b], operation) is Ok(actual) else {
      fail("Boolean operation failed")
    }
    example_result(actual, expected)
    let mut total = 0N
    for path in actual {
      guard @moonclip.area2(path) is Ok(value) else {
        fail("Expected exact area")
      }
      total += value
    }
    assert_eq(total, twice_area)
  }
  let concave = [
    @moonclip.Point64::new(0L, 0L),
    @moonclip.Point64::new(12L, 0L),
    @moonclip.Point64::new(12L, 4L),
    @moonclip.Point64::new(4L, 4L),
    @moonclip.Point64::new(4L, 12L),
    @moonclip.Point64::new(0L, 12L),
  ]
  guard @moonclip.boolean_op([concave], [], Union) is Ok(actual) else {
    fail("Concave union failed")
  }
  example_result(actual, [concave])
}

///|
fn example_reverse(path : @moonclip.Path64) -> @moonclip.Path64 {
  Array::makei(path.length(), fn(i) { path[path.length() - 1 - i] })
}

///|
fn run_winding_example() -> Unit raise {
  let a = example_rect(0L, 0L, 10L, 10L)
  let b = example_rect(5L, 0L, 10L, 10L)
  let strips = [example_rect(0L, 0L, 5L, 10L), example_rect(10L, 0L, 5L, 10L)]
  for
    (subject, nz_expected, nz_area2) in [
      ([a, b], [example_rect(0L, 0L, 15L, 10L)], 300N),
      ([a, example_reverse(b)], strips, 200N),
      (
        [example_reverse(a), example_reverse(b)],
        [example_rect(0L, 0L, 15L, 10L)],
        300N,
      ),
    ] {
    for
      (rule, expected, expected_area2) in [
        (@moonclip.EvenOdd, strips, 200N),
        (@moonclip.NonZero, nz_expected, nz_area2),
      ] {
      guard @moonclip.boolean_op(subject, [], Union, fill_rule=rule)
        is Ok(actual) else {
        fail("Expected winding result")
      }
      example_result(actual, expected)
      let mut total = 0N
      for path in actual {
        guard @moonclip.area2(path) is Ok(value) else {
          fail("Expected exact area")
        }
        total += value
      }
      assert_eq(total, expected_area2)
    }
  }
}

///|
fn run_tree_example() -> Unit raise {
  let outer = example_rect(-30L, -30L, 60L, 60L)
  let hole = example_reverse(example_rect(-20L, -20L, 40L, 40L))
  let island = example_rect(-10L, -10L, 20L, 20L)
  let subject = [outer, hole, island]
  guard @moonclip.boolean_tree(subject, [], Union, fill_rule=NonZero)
    is Ok(tree) else {
    fail("Expected PolyTree")
  }
  let roots = tree.roots()
  assert_eq(roots.length(), 1)
  let root = roots[0]
  assert_eq(root.depth(), 1)
  assert_true(!root.is_hole())
  example_result([root.contour()], [outer])
  let children = root.children()
  assert_eq(children.length(), 1)
  let h = children[0]
  assert_eq(h.depth(), 2)
  assert_true(h.is_hole())
  example_result([h.contour()], [hole])
  let islands = h.children()
  assert_eq(islands.length(), 1)
  assert_eq(islands[0].depth(), 3)
  assert_true(!islands[0].is_hole())
  assert_eq(islands[0].children().length(), 0)
  example_result([islands[0].contour()], [island])
  guard @moonclip.boolean_op(subject, [], Union, fill_rule=NonZero) is Ok(flat) else {
    fail("Expected independent flat result")
  }
  example_result(tree.to_paths(), flat)
  roots.clear()
  children.clear()
  let exposed = h.contour()
  exposed[0] = @moonclip.Point64::new(999L, 999L)
  assert_eq(tree.roots().length(), 1)
  assert_eq(tree.roots()[0].children().length(), 1)
  example_result([tree.roots()[0].children()[0].contour()], [hole])
}

///|
fn run_offset_example() -> Unit raise {
  let rectangle = [example_rect(0L, 0L, 10L, 10L)]
  for
    (delta, expected) in [
      (2.0, [example_rect(-2L, -2L, 14L, 14L)]),
      (-2.0, [example_rect(2L, 2L, 6L, 6L)]),
      (-6.0, []),
    ] {
    guard @moonclip.offset_polygons(rectangle, delta) is Ok(result) else {
      fail("Expected rectangle offset")
    }
    example_result(result, expected)
  }
  let triangle = [
    @moonclip.Point64::new(0L, 0L),
    @moonclip.Point64::new(60L, 0L),
    @moonclip.Point64::new(2L, 10L),
  ]
  guard @moonclip.offset_polygons([triangle], 3.0) is Ok(miter) else {
    fail("Expected Miter")
  }
  example_result(miter, [
    [
      @moonclip.Point64::new(-4L, -3L),
      @moonclip.Point64::new(63L, -3L),
      @moonclip.Point64::new(63L, 2L),
      @moonclip.Point64::new(0L, 13L),
    ],
  ])
  guard @moonclip.offset_polygons(
      [triangle],
      3.0,
      options=@moonclip.OffsetOptions::new(join=Bevel),
    )
    is Ok(bevel) else {
    fail("Expected Bevel")
  }
  example_result(bevel, [
    [
      @moonclip.Point64::new(-3L, 1L),
      @moonclip.Point64::new(0L, -3L),
      @moonclip.Point64::new(60L, -3L),
      @moonclip.Point64::new(61L, 3L),
      @moonclip.Point64::new(3L, 13L),
      @moonclip.Point64::new(-1L, 11L),
    ],
  ])
  let region = [
    example_rect(-30L, -30L, 60L, 60L),
    example_reverse(example_rect(-10L, -10L, 20L, 20L)),
  ]
  for
    (delta, expected) in [
      (
        2.0,
        [
          example_rect(-32L, -32L, 64L, 64L),
          example_reverse(example_rect(-8L, -8L, 16L, 16L)),
        ],
      ),
      (
        -2.0,
        [
          example_rect(-28L, -28L, 56L, 56L),
          example_reverse(example_rect(-12L, -12L, 24L, 24L)),
        ],
      ),
    ] {
    guard @moonclip.offset_polygons(region, delta) is Ok(result) else {
      fail("Expected region offset")
    }
    example_result(result, expected)
  }
  assert_true(
    @moonclip.offset_polygons(
      [],
      0.0,
      options=@moonclip.OffsetOptions::new(miter_limit=1.0),
    )
    is Err(InvalidInput(_, _)),
  )
}

///|
fn run_join_example() -> Unit raise {
  let region = [example_rect(0L, 0L, 100L, 100L)]
  guard @moonclip.offset_polygons(
      region,
      10.0,
      options=@moonclip.OffsetOptions::new(join=Square),
    )
    is Ok(square) else {
    fail("Expected Square offset")
  }
  example_result(square, [
    [
      @moonclip.Point64::new(-10L, -4L),
      @moonclip.Point64::new(-4L, -10L),
      @moonclip.Point64::new(104L, -10L),
      @moonclip.Point64::new(110L, -4L),
      @moonclip.Point64::new(110L, 104L),
      @moonclip.Point64::new(104L, 110L),
      @moonclip.Point64::new(-4L, 110L),
      @moonclip.Point64::new(-10L, 104L),
    ],
  ])
  guard @moonclip.offset_polygons(
      region,
      10.0,
      options=@moonclip.OffsetOptions::new(join=Round, arc_tolerance=0.25),
    )
    is Ok(round) else {
    fail("Expected Round offset")
  }
  example_result(round, [
    [
      @moonclip.Point64::new(104L, -9L),
      @moonclip.Point64::new(108L, -6L),
      @moonclip.Point64::new(110L, -2L),
      @moonclip.Point64::new(110L, 100L),
      @moonclip.Point64::new(109L, 104L),
      @moonclip.Point64::new(106L, 108L),
      @moonclip.Point64::new(102L, 110L),
      @moonclip.Point64::new(0L, 110L),
      @moonclip.Point64::new(-4L, 109L),
      @moonclip.Point64::new(-8L, 106L),
      @moonclip.Point64::new(-10L, 102L),
      @moonclip.Point64::new(-10L, 0L),
      @moonclip.Point64::new(-9L, -4L),
      @moonclip.Point64::new(-6L, -8L),
      @moonclip.Point64::new(-2L, -10L),
      @moonclip.Point64::new(100L, -10L),
    ],
  ])
  assert_true(square != round)
}

///|
fn run_stroke_example() -> Unit raise {
  let line = [@moonclip.Point64::new(0L, 0L), @moonclip.Point64::new(20L, 0L)]
  for
    (cap, expected) in [
      (@moonclip.CapType::Butt, [example_rect(0L, -2L, 20L, 4L)]),
      (@moonclip.CapType::Square, [example_rect(-2L, -2L, 24L, 4L)]),
    ] {
    guard @moonclip.stroke_polyline(line, 4.0, cap~) is Ok(result) else {
      fail("Expected line stroke")
    }
    example_result(result, expected)
  }
  guard @moonclip.stroke_polyline(line, 4.0, cap=Round) is Ok(round) else {
    fail("Expected round caps")
  }
  example_result(round, [
    [
      @moonclip.Point64::new(0L, 2L),
      @moonclip.Point64::new(-2L, 1L),
      @moonclip.Point64::new(-2L, -1L),
      @moonclip.Point64::new(0L, -2L),
      @moonclip.Point64::new(20L, -2L),
      @moonclip.Point64::new(22L, -1L),
      @moonclip.Point64::new(22L, 1L),
      @moonclip.Point64::new(20L, 2L),
    ],
  ])
  let route = [
    @moonclip.Point64::new(0L, 0L),
    @moonclip.Point64::new(20L, 0L),
    @moonclip.Point64::new(20L, 20L),
  ]
  guard @moonclip.stroke_polyline(
      route,
      4.0,
      cap=Round,
      options=@moonclip.OffsetOptions::new(join=Round, arc_tolerance=0.25),
    )
    is Ok(region) else {
    fail("Expected route stroke")
  }
  example_result(region, [
    [
      @moonclip.Point64::new(0L, 2L),
      @moonclip.Point64::new(-2L, 1L),
      @moonclip.Point64::new(-2L, -1L),
      @moonclip.Point64::new(0L, -2L),
      @moonclip.Point64::new(20L, -2L),
      @moonclip.Point64::new(22L, -1L),
      @moonclip.Point64::new(22L, 20L),
      @moonclip.Point64::new(21L, 22L),
      @moonclip.Point64::new(19L, 22L),
      @moonclip.Point64::new(18L, 20L),
      @moonclip.Point64::new(18L, 2L),
    ],
  ])
  assert_eq(@moonclip.stroke_polyline(line, 0.99), Ok([]))
  assert_true(@moonclip.stroke_polyline(line, -1.0) is Err(InvalidInput(_, _)))
}

///|
fn run_composition_example() -> Unit raise {
  guard @moonclip.boolean_op(
      [example_rect(0L, 0L, 10L, 10L)],
      [example_rect(5L, 0L, 10L, 10L)],
      @moonclip.Union,
      fill_rule=@moonclip.NonZero,
    )
    is Ok(united) else {
    fail("Composition Union failed")
  }
  example_result(united, [example_rect(0L, 0L, 15L, 10L)])
  guard @moonclip.offset_polygons(united, 2.0, fill_rule=@moonclip.NonZero)
    is Ok(expanded) else {
    fail("Composition expansion failed")
  }
  example_result(expanded, [example_rect(-2L, -2L, 19L, 14L)])

  let region = [
    example_rect(0L, 0L, 40L, 40L),
    example_reverse(example_rect(10L, 10L, 20L, 20L)),
  ]
  guard @moonclip.offset_polygons(region, -2.0, fill_rule=@moonclip.NonZero)
    is Ok(inset) else {
    fail("Composition inset failed")
  }
  guard @moonclip.boolean_tree(
      inset,
      [],
      @moonclip.Union,
      fill_rule=@moonclip.NonZero,
    )
    is Ok(tree) else {
    fail("Composition hierarchy failed")
  }
  assert_eq(tree.roots().length(), 1)
  let root = tree.roots()[0]
  assert_eq(root.depth(), 1)
  assert_eq(root.children().length(), 1)
  assert_true(root.children()[0].is_hole())
  example_result([root.contour()], [example_rect(2L, 2L, 36L, 36L)])
  example_result([root.children()[0].contour()], [
    example_reverse(example_rect(8L, 8L, 24L, 24L)),
  ])

  let route = [
    @moonclip.Point64::new(-10L, 10L),
    @moonclip.Point64::new(30L, 10L),
  ]
  guard @moonclip.stroke_polyline(route, 4.0, cap=@moonclip.CapType::Butt)
    is Ok(coverage) else {
    fail("Composition stroke failed")
  }
  guard @moonclip.boolean_op(
      coverage,
      [example_rect(0L, 0L, 20L, 20L)],
      @moonclip.Intersection,
      fill_rule=@moonclip.NonZero,
    )
    is Ok(clipped) else {
    fail("Composition intersection failed")
  }
  example_result(clipped, [example_rect(0L, 8L, 20L, 4L)])
}

///|
fn example_box_d(
  x1 : Double,
  y1 : Double,
  x2 : Double,
  y2 : Double,
) -> @moonclip.PathD {
  [
    @moonclip.PointD::new(x1, y1),
    @moonclip.PointD::new(x2, y1),
    @moonclip.PointD::new(x2, y2),
    @moonclip.PointD::new(x1, y2),
  ]
}

///|
fn example_decimal_rectangle(
  value : @moonclip.PathsD,
  x1 : Double,
  y1 : Double,
  x2 : Double,
  y2 : Double,
) -> Unit raise {
  assert_eq(value.length(), 1)
  let expected = example_box_d(x1, y1, x2, y2)
  let path = value[0]
  assert_eq(path.length(), 4)
  for start = 0; start < 4; start = start + 1 {
    if path[start] == expected[0] {
      for i = 0; i < 4; i = i + 1 {
        assert_eq(path[(start + i) % 4], expected[i])
      }
      return
    }
  }
  fail("Decimal contour differs from the complete expected rectangle")
}

///|
fn run_decimal_example() -> Unit raise {
  guard @moonclip.Precision::new(3) is Ok(precision) else {
    fail("Expected supported precision")
  }
  let subject = [example_box_d(-1.25, -0.25, 1.25, 1.25)]
  let clip = [example_box_d(0.25, -0.25, 2.25, 1.25)]
  let saved = @moonclip.copy_paths_d(subject)
  guard @moonclip.boolean_op_d(
      subject,
      clip,
      @moonclip.Union,
      precision~,
      fill_rule=@moonclip.NonZero,
    )
    is Ok(united) else {
    fail("Decimal Union failed")
  }
  example_decimal_rectangle(united, -1.25, -0.25, 2.25, 1.25)
  guard @moonclip.offset_polygons_d(
      united,
      0.2,
      precision~,
      fill_rule=@moonclip.NonZero,
    )
    is Ok(expanded) else {
    fail("Decimal offset failed")
  }
  example_decimal_rectangle(expanded, -1.45, -0.45, 2.45, 1.45)
  let route = [
    @moonclip.PointD::new(-1.0, 0.0),
    @moonclip.PointD::new(3.0, 0.0),
  ]
  guard @moonclip.stroke_polyline_d(
      route,
      0.4,
      precision~,
      cap=@moonclip.CapType::Butt,
    )
    is Ok(coverage) else {
    fail("Decimal stroke failed")
  }
  example_decimal_rectangle(coverage, -1.0, -0.2, 3.0, 0.2)
  guard @moonclip.boolean_op_d(
      coverage,
      [example_box_d(0.0, -1.0, 2.0, 1.0)],
      @moonclip.Intersection,
      precision~,
      fill_rule=@moonclip.NonZero,
    )
    is Ok(clipped) else {
    fail("Decimal intersection failed")
  }
  example_decimal_rectangle(clipped, 0.0, -0.2, 2.0, 0.2)
  assert_eq(subject, saved)
  assert_true(
    @moonclip.stroke_polyline_d(
      [@moonclip.PointD::new(0.0001, 0.0), @moonclip.PointD::new(0.0002, 0.0)],
      0.0,
      precision~,
    )
    is Err(
      @moonclip.QuantizationFailure(
        {
          stage: @moonclip.DecimalQuantize,
          path_index: Some(0),
          vertex_index: Some(1),
        },
        None,
        Some({ path_index: Some(0), vertex_index: Some(0), .. }),
        _
      )
    ),
  )
}

///|
fn example_decimal_ring(
  path : @moonclip.PathD,
  expected : @moonclip.PathD,
) -> Unit raise {
  assert_eq(path.length(), expected.length())
  for start = 0; start < path.length(); start = start + 1 {
    if path[start] == expected[0] {
      for i = 0; i < path.length(); i = i + 1 {
        assert_eq(path[(start + i) % path.length()], expected[i])
      }
      return
    }
  }
  fail("Decimal tree contour differs from expected ring")
}

///|
fn run_decimal_tree_example() -> Unit raise {
  let outer = example_box_d(-5.25, -5.25, 5.25, 5.25)
  let hole = example_box_d(-3.25, -3.25, 3.25, 3.25)
  let island = example_box_d(-1.25, -1.25, 1.25, 1.25)
  // EvenOdd accepts equal input winding; the returned hole is negative.
  let expected = [
    outer,
    Array::makei(hole.length(), fn(i) { hole[hole.length() - 1 - i] }),
    island,
  ]
  guard @moonclip.boolean_tree_d([outer, hole, island], [], @moonclip.Union)
    is Ok(tree) else {
    fail("Decimal tree failed")
  }
  let mut views = tree.roots()
  for i = 0; i < 3; i = i + 1 {
    assert_eq(views.length(), 1)
    let node = views[0]
    assert_eq(node.depth(), i + 1)
    assert_eq(node.is_hole(), i == 1)
    example_decimal_ring(node.contour(), expected[i])
    views = node.children()
  }
  assert_eq(views.length(), 0)
  assert_eq(tree.to_paths().length(), 3)
  println("Decimal tree: outer/hole/island OK")
}

///|
fn run_simplify_example() -> Unit raise {
  let outer = [
    @moonclip.Point64::new(0L, 0L),
    @moonclip.Point64::new(20L, 0L),
    @moonclip.Point64::new(40L, 0L),
    @moonclip.Point64::new(40L, 40L),
    @moonclip.Point64::new(0L, 40L),
  ]
  let hole = example_reverse(example_rect(10L, 10L, 20L, 20L))
  let input = [outer, hole, []]
  let saved = @moonclip.copy_paths(input)
  guard @moonclip.simplify_paths(
      input,
      options=@moonclip.SimplifyOptions::new(epsilon=0.25),
    )
    is Ok(value) else {
    fail("Simplification failed")
  }
  assert_eq(value.removed_vertices(), 1)
  assert_eq(value.removed_per_path(), [1, 0, 0])
  assert_eq(value.input_degenerate_indices(), [2])
  assert_eq(value.degenerate_indices(), [2])
  assert_eq(value.collapsed_indices(), [])
  assert_eq(input, saved)
  let paths = value.paths()
  assert_eq(paths[0], example_rect(0L, 0L, 40L, 40L))
  let selected : @moonclip.Paths64 = []
  let excluded = value.degenerate_indices()
  for i = 0; i < paths.length(); i = i + 1 {
    if !excluded.contains(i) {
      selected.push(paths[i])
    }
  }
  guard @moonclip.offset_polygons(selected, 2.0) is Ok(expanded) else {
    fail("Post-simplification offset failed")
  }
  let expected_hole = example_reverse(example_rect(12L, 12L, 16L, 16L))
  example_result(expanded, [example_rect(-2L, -2L, 44L, 44L), expected_hole])
  guard @moonclip.boolean_tree(
      expanded,
      [],
      @moonclip.Union,
      fill_rule=@moonclip.NonZero,
    )
    is Ok(tree) else {
    fail("Post-simplification tree failed")
  }
  assert_eq(tree.roots().length(), 1)
  assert_eq(tree.roots()[0].children().length(), 1)
  assert_eq(tree.roots()[0].children()[0].is_hole(), true)
  println(
    "Simplify vertices: 9 -> 8; input_degenerate=[2]; degenerate=[2]; collapsed=[]; offset/tree OK",
  )
}

///|
fn run_minkowski_example() -> Unit raise {
  guard @moonclip.minkowski_sum(
      [
        @moonclip.Point64::new(-2L, -1L),
        @moonclip.Point64::new(2L, -1L),
        @moonclip.Point64::new(2L, 1L),
        @moonclip.Point64::new(-2L, 1L),
      ],
      [
        @moonclip.Point64::new(0L, 0L),
        @moonclip.Point64::new(20L, 0L),
        @moonclip.Point64::new(20L, 20L),
      ],
      false,
    )
    is Ok(sweep0) else {
    fail("Minkowski sweep failed")
  }
  example_result(sweep0, [
    [
      @moonclip.Point64::new(18L, -1L),
      @moonclip.Point64::new(22L, -1L),
      @moonclip.Point64::new(22L, 1L),
      @moonclip.Point64::new(22L, 21L),
      @moonclip.Point64::new(18L, 21L),
      @moonclip.Point64::new(18L, 19L),
      @moonclip.Point64::new(18L, 1L),
      @moonclip.Point64::new(2L, 1L),
      @moonclip.Point64::new(-2L, 1L),
      @moonclip.Point64::new(-2L, -1L),
    ],
  ])
  guard @moonclip.minkowski_sum(
      [
        @moonclip.Point64::new(2L, 1L),
        @moonclip.Point64::new(6L, 1L),
        @moonclip.Point64::new(5L, 4L),
        @moonclip.Point64::new(2L, 3L),
      ],
      [@moonclip.Point64::new(-10L, -5L), @moonclip.Point64::new(20L, 15L)],
      false,
    )
    is Ok(sweep1) else {
    fail("Minkowski sweep failed")
  }
  example_result(sweep1, [
    [
      @moonclip.Point64::new(-4L, -4L),
      @moonclip.Point64::new(26L, 16L),
      @moonclip.Point64::new(25L, 19L),
      @moonclip.Point64::new(22L, 18L),
      @moonclip.Point64::new(-8L, -2L),
      @moonclip.Point64::new(-8L, -4L),
    ],
  ])
  guard @moonclip.minkowski_sum(
      [
        @moonclip.Point64::new(-2L, -1L),
        @moonclip.Point64::new(2L, -1L),
        @moonclip.Point64::new(2L, 1L),
        @moonclip.Point64::new(-2L, 1L),
      ],
      [
        @moonclip.Point64::new(0L, 0L),
        @moonclip.Point64::new(30L, 0L),
        @moonclip.Point64::new(30L, 20L),
        @moonclip.Point64::new(0L, 20L),
      ],
      true,
    )
    is Ok(sweep2) else {
    fail("Minkowski sweep failed")
  }
  example_result(sweep2, [
    [
      @moonclip.Point64::new(2L, -1L),
      @moonclip.Point64::new(28L, -1L),
      @moonclip.Point64::new(32L, -1L),
      @moonclip.Point64::new(32L, 1L),
      @moonclip.Point64::new(32L, 21L),
      @moonclip.Point64::new(28L, 21L),
      @moonclip.Point64::new(2L, 21L),
      @moonclip.Point64::new(-2L, 21L),
      @moonclip.Point64::new(-2L, 19L),
      @moonclip.Point64::new(-2L, 1L),
      @moonclip.Point64::new(-2L, -1L),
    ],
    [
      @moonclip.Point64::new(2L, 19L),
      @moonclip.Point64::new(28L, 19L),
      @moonclip.Point64::new(28L, 1L),
      @moonclip.Point64::new(2L, 1L),
    ],
  ])
  guard @moonclip.boolean_tree(
      sweep2,
      [],
      @moonclip.Union,
      fill_rule=@moonclip.NonZero,
    )
    is Ok(tree) else {
    fail("Minkowski tree failed")
  }
  assert_eq(tree.roots().length(), 1)
  assert_eq(tree.roots()[0].children().length(), 1)
  assert_true(tree.roots()[0].children()[0].is_hole())
  println(
    "Minkowski: rectangle/polyline, offcenter/diagonal and closed route/hole OK",
  )
}

///|
fn run_rectclip_polygons_example() -> Unit raise {
  let rect : @moonclip.Bounds64 = {
    min_x: 0L,
    min_y: 0L,
    max_x: 10L,
    max_y: 10L,
  }
  let result = @moonclip.rect_clip_polygons(rect, [
    example_rect(-2L, -2L, 14L, 14L),
    example_rect(3L, 3L, 4L, 4L),
  ]).unwrap()
  example_result(result, [
    example_rect(0L, 0L, 10L, 10L),
    example_reverse(example_rect(3L, 3L, 4L, 4L)),
  ])
}

///|
fn run_decimal_rectclip_polygons_example() -> Unit raise {
  let rect : @moonclip.BoundsD = {
    min_x: -1.25,
    min_y: -0.5,
    max_x: 2.75,
    max_y: 2.5,
  }
  let result = @moonclip.rect_clip_polygons_d(
    rect,
    [example_box_d(-2.0, -1.0, 4.0, 4.0), example_box_d(0.0, 0.0, 1.0, 1.0)],
    precision=@moonclip.Precision::new(2).unwrap(),
  ).unwrap()
  assert_eq(result.length(), 2)
  let outer = example_box_d(-1.25, -0.5, 2.75, 2.5)
  let hole = [
    @moonclip.PointD::new(0.0, 0.0),
    @moonclip.PointD::new(0.0, 1.0),
    @moonclip.PointD::new(1.0, 1.0),
    @moonclip.PointD::new(1.0, 0.0),
  ]
  let mut outer_count = 0
  for ring in result {
    if ring.contains(outer[0]) {
      example_decimal_ring(ring, outer)
      outer_count += 1
    } else {
      example_decimal_ring(ring, hole)
    }
  }
  assert_eq(outer_count, 1)
}

///|
fn run_decimal_rectclip_lines_example() -> Unit raise {
  let rect : @moonclip.BoundsD = {
    min_x: -1.25,
    min_y: -0.5,
    max_x: 2.75,
    max_y: 2.5,
  }
  let result = @moonclip.rect_clip_lines_d(
    rect,
    [
      [
        @moonclip.PointD::new(-2.0, 0.25),
        @moonclip.PointD::new(0.5, 0.25),
        @moonclip.PointD::new(3.0, 0.25),
      ],
    ],
    precision=@moonclip.Precision::new(2).unwrap(),
  ).unwrap()
  // Direct ordered comparison: the middle collinear point remains present.
  assert_eq(result, [
    [
      @moonclip.PointD::new(-1.25, 0.25),
      @moonclip.PointD::new(0.5, 0.25),
      @moonclip.PointD::new(2.75, 0.25),
    ],
  ])
}

///|
fn run_stroke_batch_tree_example() -> Unit raise {
  let paths = [
    [@moonclip.Point64::new(0L, 0L), @moonclip.Point64::new(10L, 0L)],
    [@moonclip.Point64::new(10L, 0L), @moonclip.Point64::new(10L, 10L)],
    [@moonclip.Point64::new(10L, 10L), @moonclip.Point64::new(0L, 10L)],
    [@moonclip.Point64::new(0L, 10L), @moonclip.Point64::new(0L, 0L)],
  ]
  let tree = @moonclip.stroke_polylines_tree(paths, 2.0, cap=Square).unwrap()
  let roots = tree.roots()
  assert_eq(roots.length(), 1)
  assert_eq(roots[0].depth(), 1)
  assert_eq(roots[0].is_hole(), false)
  example_result([roots[0].contour()], [example_rect(-1L, -1L, 12L, 12L)])
  let children = roots[0].children()
  assert_eq(children.length(), 1)
  assert_eq(children[0].depth(), 2)
  assert_eq(children[0].is_hole(), true)
  example_result([children[0].contour()], [
    example_reverse(example_rect(1L, 1L, 8L, 8L)),
  ])
  assert_eq(children[0].children().length(), 0)
}

///|
fn run_rectclip_tree_example() -> Unit raise {
  let rect : @moonclip.Bounds64 = {
    min_x: 0L,
    min_y: 0L,
    max_x: 5L,
    max_y: 10L,
  }
  let tree = @moonclip.rect_clip_polygons_tree(rect, [
    example_rect(-2L, -2L, 14L, 14L),
    example_rect(3L, 3L, 4L, 4L),
  ]).unwrap()
  let roots = tree.roots()
  assert_eq(roots.length(), 1)
  assert_eq(roots[0].depth(), 1)
  assert_eq(roots[0].is_hole(), false)
  assert_eq(roots[0].children().length(), 0)
  // The window cuts the hole open: it is now a notch, not a separate child.
  example_result([roots[0].contour()], [
    [
      @moonclip.Point64::new(0L, 0L),
      @moonclip.Point64::new(5L, 0L),
      @moonclip.Point64::new(5L, 3L),
      @moonclip.Point64::new(3L, 3L),
      @moonclip.Point64::new(3L, 7L),
      @moonclip.Point64::new(5L, 7L),
      @moonclip.Point64::new(5L, 10L),
      @moonclip.Point64::new(0L, 10L),
    ],
  ])
}

///|
fn run_minkowski_tree_example() -> Unit raise {
  let tree = @moonclip.minkowski_sum_tree(
    example_rect(-2L, -1L, 4L, 2L),
    example_rect(0L, 0L, 30L, 20L),
    true,
  ).unwrap()
  let expected = [
    [
      @moonclip.Point64::new(2L, -1L),
      @moonclip.Point64::new(28L, -1L),
      @moonclip.Point64::new(32L, -1L),
      @moonclip.Point64::new(32L, 1L),
      @moonclip.Point64::new(32L, 21L),
      @moonclip.Point64::new(28L, 21L),
      @moonclip.Point64::new(2L, 21L),
      @moonclip.Point64::new(-2L, 21L),
      @moonclip.Point64::new(-2L, 19L),
      @moonclip.Point64::new(-2L, 1L),
      @moonclip.Point64::new(-2L, -1L),
    ],
    [
      @moonclip.Point64::new(2L, 19L),
      @moonclip.Point64::new(28L, 19L),
      @moonclip.Point64::new(28L, 1L),
      @moonclip.Point64::new(2L, 1L),
    ],
  ]
  let roots = tree.roots()
  assert_eq(roots.length(), 1)
  assert_eq(roots[0].depth(), 1)
  assert_eq(roots[0].is_hole(), false)
  assert_eq(roots[0].contour().length(), 11)
  example_result([roots[0].contour()], [expected[0]])
  let children = roots[0].children()
  assert_eq(children.length(), 1)
  assert_eq(children[0].depth(), 2)
  assert_eq(children[0].is_hole(), true)
  assert_eq(children[0].children().length(), 0)
  example_result([children[0].contour()], [expected[1]])
}

///|
fn run_decimal_tree_locate_example() -> Unit raise {
  let tree = @moonclip.boolean_tree_d(
    [
      example_box_d(0.0, 0.0, 2.0, 2.0),
      example_box_d(0.4, 0.4, 1.6, 1.6),
      example_box_d(0.8, 0.8, 1.2, 1.2),
    ],
    [],
    Union,
    precision=@moonclip.Precision::new(2).unwrap(),
  ).unwrap()
  guard tree.locate(@moonclip.PointD::new(0.6, 0.6)) is Ok(InHole(hole)) else {
    fail("Expected decimal hole query")
  }
  assert_eq(hole.depth(), 2)
  let hole_expected = example_box_d(0.4, 0.4, 1.6, 1.6)
  example_decimal_ring(
    hole.contour(),
    Array::makei(4, fn(i) { hole_expected[3 - i] }),
  )
  let results = tree
    .locate_many([
      @moonclip.PointD::new(0.2, 0.2),
      @moonclip.PointD::new(-0.004, 1.0),
      @moonclip.PointD::new(-0.1, 1.0),
    ])
    .unwrap()
  assert_eq(results.length(), 3)
  guard results[0] is Inside(node) else { fail("Expected decimal inside") }
  assert_eq(node.depth(), 1)
  guard results[1] is OnBoundary(nodes) else {
    fail("Expected quantized boundary")
  }
  assert_eq(nodes.length(), 1)
  assert_eq(nodes[0].depth(), 1)
  assert_true(results[2] is Outside)
}

///|
fn run_closed_stroke_tree_example() -> Unit raise {
  let tree = @moonclip.stroke_closed_tree_d(
    example_box_d(0.0, 0.0, 1.0, 1.0),
    0.2,
    precision=@moonclip.Precision::new(2).unwrap(),
  ).unwrap()
  let roots = tree.roots()
  assert_eq(roots.length(), 1)
  assert_eq(roots[0].depth(), 1)
  assert_eq(roots[0].is_hole(), false)
  example_decimal_ring(roots[0].contour(), example_box_d(-0.1, -0.1, 1.1, 1.1))
  let holes = roots[0].children()
  assert_eq(holes.length(), 1)
  assert_eq(holes[0].depth(), 2)
  assert_eq(holes[0].is_hole(), true)
  assert_eq(holes[0].children().length(), 0)
  example_decimal_ring(holes[0].contour(), [
    @moonclip.PointD::new(0.1, 0.1),
    @moonclip.PointD::new(0.1, 0.9),
    @moonclip.PointD::new(0.9, 0.9),
    @moonclip.PointD::new(0.9, 0.1),
  ])
}